| Differences between
and this patch
- WebCore/WebCore.xcodeproj/project.pbxproj +12 lines
Lines 4548-4553 WebCore/WebCore.xcodeproj/project.pbxproj_sec1
4548
		BCE65BEA0EACDF16007E4533 /* Length.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCE65BE80EACDF16007E4533 /* Length.cpp */; };
4548
		BCE65BEA0EACDF16007E4533 /* Length.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCE65BE80EACDF16007E4533 /* Length.cpp */; };
4549
		BCE65BEB0EACDF16007E4533 /* Length.h in Headers */ = {isa = PBXBuildFile; fileRef = BCE65BE90EACDF16007E4533 /* Length.h */; settings = {ATTRIBUTES = (Private, ); }; };
4549
		BCE65BEB0EACDF16007E4533 /* Length.h in Headers */ = {isa = PBXBuildFile; fileRef = BCE65BE90EACDF16007E4533 /* Length.h */; settings = {ATTRIBUTES = (Private, ); }; };
4550
		BCE65D320EAD1211007E4533 /* Theme.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCE65D310EAD1211007E4533 /* Theme.cpp */; };
4550
		BCE65D320EAD1211007E4533 /* Theme.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCE65D310EAD1211007E4533 /* Theme.cpp */; };
4551
		BCE789161120D6080060ECE5 /* InlineIterator.h in Headers */ = {isa = PBXBuildFile; fileRef = BCE789151120D6080060ECE5 /* InlineIterator.h */; };
4552
		BCE789861120E7A60060ECE5 /* BidiRun.h in Headers */ = {isa = PBXBuildFile; fileRef = BCE789851120E7A60060ECE5 /* BidiRun.h */; };
4553
		BCE7898B1120E8020060ECE5 /* BidiRun.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCE7898A1120E8020060ECE5 /* BidiRun.cpp */; };
4551
		BCE7B1930D4E86960075A539 /* JSHistoryCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCE7B1920D4E86960075A539 /* JSHistoryCustom.cpp */; };
4554
		BCE7B1930D4E86960075A539 /* JSHistoryCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCE7B1920D4E86960075A539 /* JSHistoryCustom.cpp */; };
4552
		BCE99EC30DCA624100182683 /* JSXSLTProcessorConstructor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCE99EC10DCA624100182683 /* JSXSLTProcessorConstructor.cpp */; };
4555
		BCE99EC30DCA624100182683 /* JSXSLTProcessorConstructor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCE99EC10DCA624100182683 /* JSXSLTProcessorConstructor.cpp */; };
4553
		BCE99EC40DCA624100182683 /* JSXSLTProcessorConstructor.h in Headers */ = {isa = PBXBuildFile; fileRef = BCE99EC20DCA624100182683 /* JSXSLTProcessorConstructor.h */; };
4556
		BCE99EC40DCA624100182683 /* JSXSLTProcessorConstructor.h in Headers */ = {isa = PBXBuildFile; fileRef = BCE99EC20DCA624100182683 /* JSXSLTProcessorConstructor.h */; };
Lines 9810-9815 WebCore/WebCore.xcodeproj/project.pbxproj_sec2
9810
		BCE65BE80EACDF16007E4533 /* Length.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Length.cpp; sourceTree = "<group>"; };
9813
		BCE65BE80EACDF16007E4533 /* Length.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Length.cpp; sourceTree = "<group>"; };
9811
		BCE65BE90EACDF16007E4533 /* Length.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Length.h; sourceTree = "<group>"; };
9814
		BCE65BE90EACDF16007E4533 /* Length.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Length.h; sourceTree = "<group>"; };
9812
		BCE65D310EAD1211007E4533 /* Theme.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Theme.cpp; sourceTree = "<group>"; };
9815
		BCE65D310EAD1211007E4533 /* Theme.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Theme.cpp; sourceTree = "<group>"; };
9816
		BCE789151120D6080060ECE5 /* InlineIterator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InlineIterator.h; sourceTree = "<group>"; };
9817
		BCE789851120E7A60060ECE5 /* BidiRun.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BidiRun.h; sourceTree = "<group>"; };
9818
		BCE7898A1120E8020060ECE5 /* BidiRun.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BidiRun.cpp; sourceTree = "<group>"; };
9813
		BCE7B1920D4E86960075A539 /* JSHistoryCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSHistoryCustom.cpp; sourceTree = "<group>"; };
9819
		BCE7B1920D4E86960075A539 /* JSHistoryCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSHistoryCustom.cpp; sourceTree = "<group>"; };
9814
		BCE99EC10DCA624100182683 /* JSXSLTProcessorConstructor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSXSLTProcessorConstructor.cpp; sourceTree = "<group>"; };
9820
		BCE99EC10DCA624100182683 /* JSXSLTProcessorConstructor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSXSLTProcessorConstructor.cpp; sourceTree = "<group>"; };
9815
		BCE99EC20DCA624100182683 /* JSXSLTProcessorConstructor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSXSLTProcessorConstructor.h; sourceTree = "<group>"; };
9821
		BCE99EC20DCA624100182683 /* JSXSLTProcessorConstructor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSXSLTProcessorConstructor.h; sourceTree = "<group>"; };
Lines 15556-15561 WebCore/WebCore.xcodeproj/project.pbxproj_sec3
15556
				BC8C8FAA0DDCD2F200B592F4 /* style */,
15562
				BC8C8FAA0DDCD2F200B592F4 /* style */,
15557
				A8CFF04B0A154F09000A4234 /* AutoTableLayout.cpp */,
15563
				A8CFF04B0A154F09000A4234 /* AutoTableLayout.cpp */,
15558
				A8CFF0490A154F09000A4234 /* AutoTableLayout.h */,
15564
				A8CFF0490A154F09000A4234 /* AutoTableLayout.h */,
15565
				BCE7898A1120E8020060ECE5 /* BidiRun.cpp */,
15566
				BCE789851120E7A60060ECE5 /* BidiRun.h */,
15559
				BCEA4815097D93020094C9E4 /* break_lines.cpp */,
15567
				BCEA4815097D93020094C9E4 /* break_lines.cpp */,
15560
				BCEA4816097D93020094C9E4 /* break_lines.h */,
15568
				BCEA4816097D93020094C9E4 /* break_lines.h */,
15561
				9392F14F0AD1862300691BD4 /* CounterNode.cpp */,
15569
				9392F14F0AD1862300691BD4 /* CounterNode.cpp */,
Lines 15572-15577 WebCore/WebCore.xcodeproj/project.pbxproj_sec4
15572
				A8CFF5DE0A155A05000A4234 /* InlineBox.h */,
15580
				A8CFF5DE0A155A05000A4234 /* InlineBox.h */,
15573
				A8CFF5DD0A155A05000A4234 /* InlineFlowBox.cpp */,
15581
				A8CFF5DD0A155A05000A4234 /* InlineFlowBox.cpp */,
15574
				A8CFF5DC0A155A05000A4234 /* InlineFlowBox.h */,
15582
				A8CFF5DC0A155A05000A4234 /* InlineFlowBox.h */,
15583
				BCE789151120D6080060ECE5 /* InlineIterator.h */,
15575
				A8CFF5DB0A155A05000A4234 /* InlineRunBox.h */,
15584
				A8CFF5DB0A155A05000A4234 /* InlineRunBox.h */,
15576
				BCEA481A097D93020094C9E4 /* InlineTextBox.cpp */,
15585
				BCEA481A097D93020094C9E4 /* InlineTextBox.cpp */,
15577
				BCEA481B097D93020094C9E4 /* InlineTextBox.h */,
15586
				BCEA481B097D93020094C9E4 /* InlineTextBox.h */,
Lines 18505-18510 WebCore/WebCore.xcodeproj/project.pbxproj_sec5
18505
				B71FE6DF11091CB300DAEF77 /* PrintContext.h in Headers */,
18514
				B71FE6DF11091CB300DAEF77 /* PrintContext.h in Headers */,
18506
				9F72304F11184B4100AD0126 /* ScriptProfile.h in Headers */,
18515
				9F72304F11184B4100AD0126 /* ScriptProfile.h in Headers */,
18507
				9F72305111184B4100AD0126 /* ScriptProfiler.h in Headers */,
18516
				9F72305111184B4100AD0126 /* ScriptProfiler.h in Headers */,
18517
				BCE789161120D6080060ECE5 /* InlineIterator.h in Headers */,
18518
				BCE789861120E7A60060ECE5 /* BidiRun.h in Headers */,
18508
			);
18519
			);
18509
			runOnlyForDeploymentPostprocessing = 0;
18520
			runOnlyForDeploymentPostprocessing = 0;
18510
		};
18521
		};
Lines 20683-20688 WebCore/WebCore.xcodeproj/project.pbxproj_sec6
20683
				84D0C4041115F1D40018AA34 /* AffineTransform.cpp in Sources */,
20694
				84D0C4041115F1D40018AA34 /* AffineTransform.cpp in Sources */,
20684
				B776D43D1104527500BEB0EC /* PrintContext.cpp in Sources */,
20695
				B776D43D1104527500BEB0EC /* PrintContext.cpp in Sources */,
20685
				9F72305011184B4100AD0126 /* ScriptProfiler.cpp in Sources */,
20696
				9F72305011184B4100AD0126 /* ScriptProfiler.cpp in Sources */,
20697
				BCE7898B1120E8020060ECE5 /* BidiRun.cpp in Sources */,
20686
			);
20698
			);
20687
			runOnlyForDeploymentPostprocessing = 0;
20699
			runOnlyForDeploymentPostprocessing = 0;
20688
		};
20700
		};
- WebCore/accessibility/AccessibilityRenderObject.cpp -6 / +2 lines
Lines 567-578 Element* AccessibilityRenderObject::anch WebCore/accessibility/AccessibilityRenderObject.cpp_sec1
567
    RenderObject* currRenderer;
567
    RenderObject* currRenderer;
568
    
568
    
569
    // Search up the render tree for a RenderObject with a DOM node.  Defer to an earlier continuation, though.
569
    // Search up the render tree for a RenderObject with a DOM node.  Defer to an earlier continuation, though.
570
    for (currRenderer = m_renderer; currRenderer && !currRenderer->node(); currRenderer = currRenderer->parent()) {
570
    for (currRenderer = m_renderer; currRenderer && !currRenderer->node(); currRenderer = currRenderer->parent())
571
        if (currRenderer->isRenderBlock()) {
571
    {
572
            RenderInline* continuation = toRenderBlock(currRenderer)->inlineContinuation();
573
            if (continuation)
574
                return cache->getOrCreate(continuation)->anchorElement();
575
        }
576
    }
572
    }
577
    
573
    
578
    // bail if none found
574
    // bail if none found
- WebCore/rendering/BidiRun.cpp +74 lines
Line 0 WebCore/rendering/BidiRun.cpp_sec1
1
/**
2
 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3
 *           (C) 1999 Antti Koivisto (koivisto@kde.org)
4
 * Copyright (C) 2003, 2004, 2005, 2006, 2010 Apple Inc. All rights reserved.
5
 * Copyright (C) 2006 Andrew Wellington (proton@wiretapped.net)
6
 *
7
 * This library is free software; you can redistribute it and/or
8
 * modify it under the terms of the GNU Library General Public
9
 * License as published by the Free Software Foundation; either
10
 * version 2 of the License, or (at your option) any later version.
11
 *
12
 * This library is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
 * Library General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU Library General Public License
18
 * along with this library; see the file COPYING.LIB.  If not, write to
19
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20
 * Boston, MA 02110-1301, USA.
21
 *
22
 */
23
24
#include "config.h"
25
#include "BidiRun.h"
26
#include "InlineBox.h"
27
#include "RenderArena.h"
28
#include <wtf/RefCountedLeakCounter.h>
29
30
using namespace WTF;
31
32
namespace WebCore {
33
34
#ifndef NDEBUG
35
static RefCountedLeakCounter bidiRunCounter("BidiRun");
36
37
static bool inBidiRunDestroy;
38
#endif
39
40
void BidiRun::destroy()
41
{
42
#ifndef NDEBUG
43
    inBidiRunDestroy = true;
44
#endif
45
    RenderArena* renderArena = m_object->renderArena();
46
    delete this;
47
#ifndef NDEBUG
48
    inBidiRunDestroy = false;
49
#endif
50
51
    // Recover the size left there for us by operator delete and free the memory.
52
    renderArena->free(*reinterpret_cast<size_t*>(this), this);
53
}
54
55
void* BidiRun::operator new(size_t sz, RenderArena* renderArena) throw()
56
{
57
#ifndef NDEBUG
58
    bidiRunCounter.increment();
59
#endif
60
    return renderArena->allocate(sz);
61
}
62
63
void BidiRun::operator delete(void* ptr, size_t sz)
64
{
65
#ifndef NDEBUG
66
    bidiRunCounter.decrement();
67
#endif
68
    ASSERT(inBidiRunDestroy);
69
70
    // Stash size where destroy() can find it.
71
    *(size_t*)ptr = sz;
72
}
73
74
}
- WebCore/rendering/BidiRun.h +66 lines
Line 0 WebCore/rendering/BidiRun.h_sec1
1
/**
2
 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3
 *           (C) 1999 Antti Koivisto (koivisto@kde.org)
4
 * Copyright (C) 2003, 2004, 2005, 2006, 2010 Apple Inc. All rights reserved.
5
 * Copyright (C) 2006 Andrew Wellington (proton@wiretapped.net)
6
 *
7
 * This library is free software; you can redistribute it and/or
8
 * modify it under the terms of the GNU Library General Public
9
 * License as published by the Free Software Foundation; either
10
 * version 2 of the License, or (at your option) any later version.
11
 *
12
 * This library is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
 * Library General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU Library General Public License
18
 * along with this library; see the file COPYING.LIB.  If not, write to
19
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20
 * Boston, MA 02110-1301, USA.
21
 *
22
 */
23
24
#ifndef BidiRun_h
25
#define BidiRun_h
26
27
#include <wtf/StdLibExtras.h>
28
#include "BidiResolver.h"
29
#include "RenderText.h"
30
31
namespace WebCore {
32
33
class BidiContext;
34
class InlineBox;
35
36
struct BidiRun : BidiCharacterRun {
37
    BidiRun(int start, int stop, RenderObject* object, BidiContext* context, WTF::Unicode::Direction dir)
38
        : BidiCharacterRun(start, stop, context, dir)
39
        , m_object(object)
40
        , m_box(0)
41
    {
42
    }
43
44
    void destroy();
45
46
    // Overloaded new operator.
47
    void* operator new(size_t, RenderArena*) throw();
48
49
    // Overridden to prevent the normal delete from being called.
50
    void operator delete(void*, size_t);
51
52
    BidiRun* next() { return static_cast<BidiRun*>(m_next); }
53
54
private:
55
    // The normal operator new is disallowed.
56
    void* operator new(size_t) throw();
57
58
public:
59
    RenderObject* m_object;
60
    InlineBox* m_box;
61
};
62
63
}
64
65
#endif // BidiRun_h
66
- WebCore/rendering/InlineFlowBox.cpp -11 / +5 lines
Lines 32-37 WebCore/rendering/InlineFlowBox.cpp_sec1
32
#include "RenderLayer.h"
32
#include "RenderLayer.h"
33
#include "RenderListMarker.h"
33
#include "RenderListMarker.h"
34
#include "RenderTableCell.h"
34
#include "RenderTableCell.h"
35
#include "RenderView.h"
35
#include "RootInlineBox.h"
36
#include "RootInlineBox.h"
36
#include "Text.h"
37
#include "Text.h"
37
38
Lines 227-240 void InlineFlowBox::determineSpacingForF WebCore/rendering/InlineFlowBox.cpp_sec2
227
        // (3) The line may end on the inline.  If we are the last child (climbing up
228
        // (3) The line may end on the inline.  If we are the last child (climbing up
228
        // the end object's chain), then we just closed as well.
229
        // the end object's chain), then we just closed as well.
229
        if (!lineBoxList->lastLineBox()->isConstructed()) {
230
        if (!lineBoxList->lastLineBox()->isConstructed()) {
230
            RenderInline* inlineFlow = toRenderInline(renderer());
231
            if (ltr) {
231
            if (ltr) {
232
                if (!nextLineBox() &&
232
                if (!nextLineBox() &&
233
                    ((lastLine && !inlineFlow->continuation()) || nextOnLineExists() || onEndChain(endObject)))
233
                    (lastLine || nextOnLineExists() || onEndChain(endObject)))
234
                    includeRightEdge = true;
234
                    includeRightEdge = true;
235
            } else {
235
            } else {
236
                if ((!prevLineBox() || prevLineBox()->isConstructed()) &&
236
                if ((!prevLineBox() || prevLineBox()->isConstructed()) &&
237
                    ((lastLine && !inlineFlow->continuation()) || prevOnLineExists() || onEndChain(endObject)))
237
                    (lastLine || prevOnLineExists() || onEndChain(endObject)))
238
                    includeLeftEdge = true;
238
                    includeLeftEdge = true;
239
            }
239
            }
240
        }
240
        }
Lines 504-510 void InlineFlowBox::placeBoxesVertically WebCore/rendering/InlineFlowBox.cpp_sec3
504
                newY -= curr->boxModelObject()->borderTop() + curr->boxModelObject()->paddingTop();
504
                newY -= curr->boxModelObject()->borderTop() + curr->boxModelObject()->paddingTop();
505
        } else if (!curr->renderer()->isBR()) {
505
        } else if (!curr->renderer()->isBR()) {
506
            RenderBox* box = toRenderBox(curr->renderer());
506
            RenderBox* box = toRenderBox(curr->renderer());
507
            newY += box->marginTop();
507
            newY += curr->renderer()->isAnonymousInlineBlock() ? 0 : box->marginTop();
508
        }
508
        }
509
509
510
        curr->setY(newY);
510
        curr->setY(newY);
Lines 638-650 void InlineFlowBox::paint(RenderObject:: WebCore/rendering/InlineFlowBox.cpp_sec4
638
            // outlines.
638
            // outlines.
639
            if (renderer()->style()->visibility() == VISIBLE && renderer()->hasOutline() && !isRootInlineBox()) {
639
            if (renderer()->style()->visibility() == VISIBLE && renderer()->hasOutline() && !isRootInlineBox()) {
640
                RenderInline* inlineFlow = toRenderInline(renderer());
640
                RenderInline* inlineFlow = toRenderInline(renderer());
641
                if ((inlineFlow->continuation() || inlineFlow->isInlineContinuation()) && !boxModelObject()->hasSelfPaintingLayer()) {
641
                paintInfo.outlineObjects->add(inlineFlow);
642
                    // Add ourselves to the containing block of the entire continuation so that it can
643
                    // paint us atomically.
644
                    RenderBlock* block = renderer()->containingBlock()->containingBlock();
645
                    block->addContinuationWithOutline(toRenderInline(renderer()->node()->renderer()));
646
                } else if (!inlineFlow->isInlineContinuation())
647
                    paintInfo.outlineObjects->add(inlineFlow);
648
            }
642
            }
649
        } else if (paintInfo.phase == PaintPhaseMask) {
643
        } else if (paintInfo.phase == PaintPhaseMask) {
650
            paintMask(paintInfo, tx, ty);
644
            paintMask(paintInfo, tx, ty);
- WebCore/rendering/InlineIterator.h +267 lines
Line 0 WebCore/rendering/InlineIterator.h_sec1
1
/*
2
 * Copyright (C) 2000 Lars Knoll (knoll@kde.org)
3
 * Copyright (C) 2003, 2004, 2006, 2007, 2008, 2009, 2010 Apple Inc. All right reserved.
4
 * Copyright (C) 2010 Google Inc. All rights reserved.
5
 *
6
 * This library is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU Library General Public
8
 * License as published by the Free Software Foundation; either
9
 * version 2 of the License, or (at your option) any later version.
10
 *
11
 * This library is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
 * Library General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU Library General Public License
17
 * along with this library; see the file COPYING.LIB.  If not, write to
18
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19
 * Boston, MA 02110-1301, USA.
20
 *
21
 */
22
23
#ifndef InlineIterator_h
24
#define InlineIterator_h
25
26
#include "BidiRun.h"
27
#include "RenderBlock.h"
28
#include "RenderText.h"
29
#include <wtf/AlwaysInline.h>
30
#include <wtf/StdLibExtras.h>
31
32
namespace WebCore {
33
34
class InlineIterator {
35
public:
36
    InlineIterator()
37
        : block(0)
38
        , obj(0)
39
        , pos(0)
40
        , nextBreakablePosition(-1)
41
    {
42
    }
43
44
    InlineIterator(RenderBlock* b, RenderObject* o, unsigned p)
45
        : block(b)
46
        , obj(o)
47
        , pos(p)
48
        , nextBreakablePosition(-1)
49
    {
50
    }
51
52
    void increment(InlineBidiResolver* resolver = 0);
53
    bool atEnd() const;
54
55
    UChar current() const;
56
    WTF::Unicode::Direction direction() const;
57
58
    RenderBlock* block;
59
    RenderObject* obj;
60
    unsigned pos;
61
    int nextBreakablePosition;
62
};
63
64
inline bool operator==(const InlineIterator& it1, const InlineIterator& it2)
65
{
66
    return it1.pos == it2.pos && it1.obj == it2.obj;
67
}
68
69
inline bool operator!=(const InlineIterator& it1, const InlineIterator& it2)
70
{
71
    return it1.pos != it2.pos || it1.obj != it2.obj;
72
}
73
74
static inline RenderObject* bidiNext(RenderBlock* block, RenderObject* current, InlineBidiResolver* resolver = 0, bool skipInlines = true, bool* endOfInlinePtr = 0)
75
{
76
    RenderObject* next = 0;
77
    bool oldEndOfInline = endOfInlinePtr ? *endOfInlinePtr : false;
78
    bool endOfInline = false;
79
80
    while (current) {
81
        next = 0;
82
        if (!oldEndOfInline && !current->isFloating() && !current->isReplaced() && !current->isPositioned() && !current->isText()) {
83
            next = current->firstChild();
84
            if (next && resolver && next->isRenderInline()) {
85
                EUnicodeBidi ub = next->style()->unicodeBidi();
86
                if (ub != UBNormal) {
87
                    TextDirection dir = next->style()->direction();
88
                    WTF::Unicode::Direction d = (ub == Embed
89
                        ? (dir == RTL ? WTF::Unicode::RightToLeftEmbedding : WTF::Unicode::LeftToRightEmbedding)
90
                        : (dir == RTL ? WTF::Unicode::RightToLeftOverride : WTF::Unicode::LeftToRightOverride));
91
                    resolver->embed(d);
92
                }
93
            }
94
        }
95
96
        if (!next) {
97
            if (!skipInlines && !oldEndOfInline && current->isRenderInline()) {
98
                next = current;
99
                endOfInline = true;
100
                break;
101
            }
102
103
            while (current && current != block) {
104
                if (resolver && current->isRenderInline() && current->style()->unicodeBidi() != UBNormal)
105
                    resolver->embed(WTF::Unicode::PopDirectionalFormat);
106
107
                next = current->nextSibling();
108
                if (next) {
109
                    if (resolver && next->isRenderInline()) {
110
                        EUnicodeBidi ub = next->style()->unicodeBidi();
111
                        if (ub != UBNormal) {
112
                            TextDirection dir = next->style()->direction();
113
                            WTF::Unicode::Direction d = (ub == Embed
114
                                ? (dir == RTL ? WTF::Unicode::RightToLeftEmbedding: WTF::Unicode::LeftToRightEmbedding)
115
                                : (dir == RTL ? WTF::Unicode::RightToLeftOverride : WTF::Unicode::LeftToRightOverride));
116
                            resolver->embed(d);
117
                        }
118
                    }
119
                    break;
120
                }
121
                
122
                current = current->parent();
123
                if (!skipInlines && current && current != block && current->isRenderInline()) {
124
                    next = current;
125
                    endOfInline = true;
126
                    break;
127
                }
128
            }
129
        }
130
131
        if (!next)
132
            break;
133
134
        if (next->isText() || next->isFloating() || next->isReplaced() || next->isPositioned()
135
            || ((!skipInlines || !next->firstChild()) // Always return EMPTY inlines.
136
                && next->isRenderInline()))
137
            break;
138
        current = next;
139
    }
140
141
    if (endOfInlinePtr)
142
        *endOfInlinePtr = endOfInline;
143
144
    return next;
145
}
146
147
static inline RenderObject* bidiFirst(RenderBlock* block, InlineBidiResolver* resolver, bool skipInlines = true)
148
{
149
    if (!block->firstChild())
150
        return 0;
151
    
152
    RenderObject* o = block->firstChild();
153
    if (o->isRenderInline()) {
154
        if (resolver) {
155
            EUnicodeBidi ub = o->style()->unicodeBidi();
156
            if (ub != UBNormal) {
157
                TextDirection dir = o->style()->direction();
158
                WTF::Unicode::Direction d = (ub == Embed
159
                    ? (dir == RTL ? WTF::Unicode::RightToLeftEmbedding : WTF::Unicode::LeftToRightEmbedding)
160
                    : (dir == RTL ? WTF::Unicode::RightToLeftOverride : WTF::Unicode::LeftToRightOverride));
161
                resolver->embed(d);
162
            }
163
        }
164
        if (skipInlines && o->firstChild())
165
            o = bidiNext(block, o, resolver, skipInlines);
166
        else {
167
            // Never skip empty inlines.
168
            if (resolver)
169
                resolver->commitExplicitEmbedding();
170
            return o; 
171
        }
172
    }
173
174
    if (o && !o->isText() && !o->isReplaced() && !o->isFloating() && !o->isPositioned())
175
        o = bidiNext(block, o, resolver, skipInlines);
176
177
    if (resolver)
178
        resolver->commitExplicitEmbedding();
179
    return o;
180
}
181
182
inline void InlineIterator::increment(InlineBidiResolver* resolver)
183
{
184
    if (!obj)
185
        return;
186
    if (obj->isText()) {
187
        pos++;
188
        if (pos >= toRenderText(obj)->textLength()) {
189
            obj = bidiNext(block, obj, resolver);
190
            pos = 0;
191
            nextBreakablePosition = -1;
192
        }
193
    } else {
194
        obj = bidiNext(block, obj, resolver);
195
        pos = 0;
196
        nextBreakablePosition = -1;
197
    }
198
}
199
200
inline bool InlineIterator::atEnd() const
201
{
202
    return !obj;
203
}
204
205
inline UChar InlineIterator::current() const
206
{
207
    if (!obj || !obj->isText())
208
        return 0;
209
210
    RenderText* text = toRenderText(obj);
211
    if (pos >= text->textLength())
212
        return 0;
213
214
    return text->characters()[pos];
215
}
216
217
ALWAYS_INLINE WTF::Unicode::Direction InlineIterator::direction() const
218
{
219
    if (UChar c = current())
220
        return WTF::Unicode::direction(c);
221
222
    if (obj && obj->isListMarker())
223
        return obj->style()->direction() == LTR ? WTF::Unicode::LeftToRight : WTF::Unicode::RightToLeft;
224
225
    return WTF::Unicode::OtherNeutral;
226
}
227
228
template<>
229
inline void InlineBidiResolver::increment()
230
{
231
    current.increment(this);
232
}
233
234
template <>
235
inline void InlineBidiResolver::appendRun()
236
{
237
    if (!emptyRun && !eor.atEnd()) {
238
        int start = sor.pos;
239
        RenderObject *obj = sor.obj;
240
        while (obj && obj != eor.obj && obj != endOfLine.obj) {
241
            RenderBlock::appendRunsForObject(start, obj->length(), obj, *this);        
242
            start = 0;
243
            obj = bidiNext(sor.block, obj);
244
        }
245
        if (obj) {
246
            unsigned pos = obj == eor.obj ? eor.pos : UINT_MAX;
247
            if (obj == endOfLine.obj && endOfLine.pos <= pos) {
248
                reachedEndOfLine = true;
249
                pos = endOfLine.pos;
250
            }
251
            // It's OK to add runs for zero-length RenderObjects, just don't make the run larger than it should be
252
            int end = obj->length() ? pos+1 : 0;
253
            RenderBlock::appendRunsForObject(start, end, obj, *this);
254
        }
255
        
256
        eor.increment();
257
        sor = eor;
258
    }
259
260
    m_direction = WTF::Unicode::OtherNeutral;
261
    m_status.eor = WTF::Unicode::OtherNeutral;
262
}
263
264
}
265
266
#endif // InlineIterator_h
267
- WebCore/rendering/RenderBlock.cpp -214 / +77 lines
Lines 77-84 static PercentHeightDescendantsMap* gPer WebCore/rendering/RenderBlock.cpp_sec1
77
77
78
typedef WTF::HashMap<const RenderBox*, HashSet<RenderBlock*>*> PercentHeightContainerMap;
78
typedef WTF::HashMap<const RenderBox*, HashSet<RenderBlock*>*> PercentHeightContainerMap;
79
static PercentHeightContainerMap* gPercentHeightContainerMap = 0;
79
static PercentHeightContainerMap* gPercentHeightContainerMap = 0;
80
    
81
typedef WTF::HashMap<RenderBlock*, ListHashSet<RenderInline*>*> ContinuationOutlineTableMap;
82
80
83
typedef WTF::HashSet<RenderBlock*> DelayedUpdateScrollInfoSet;
81
typedef WTF::HashSet<RenderBlock*> DelayedUpdateScrollInfoSet;
84
static int gDelayUpdateScrollInfo = 0;
82
static int gDelayUpdateScrollInfo = 0;
Lines 91-97 RenderBlock::MarginInfo::MarginInfo(Rend WebCore/rendering/RenderBlock.cpp_sec2
91
    // if we had any border/padding (obviously), if we're the root or HTML elements, or if
89
    // if we had any border/padding (obviously), if we're the root or HTML elements, or if
92
    // we're positioned, floating, a table cell.
90
    // we're positioned, floating, a table cell.
93
    m_canCollapseWithChildren = !block->isRenderView() && !block->isRoot() && !block->isPositioned() &&
91
    m_canCollapseWithChildren = !block->isRenderView() && !block->isRoot() && !block->isPositioned() &&
94
        !block->isFloating() && !block->isTableCell() && !block->hasOverflowClip() && !block->isInlineBlockOrInlineTable();
92
        !block->isFloating() && !block->isTableCell() && !block->hasOverflowClip() && (!block->isInlineBlockOrInlineTable() || block->isAnonymousInlineBlock());
95
93
96
    m_canCollapseTopWithChildren = m_canCollapseWithChildren && (top == 0) && block->style()->marginTopCollapse() != MSEPARATE;
94
    m_canCollapseTopWithChildren = m_canCollapseWithChildren && (top == 0) && block->style()->marginTopCollapse() != MSEPARATE;
97
95
Lines 120-126 RenderBlock::RenderBlock(Node* node) WebCore/rendering/RenderBlock.cpp_sec3
120
      : RenderBox(node)
118
      : RenderBox(node)
121
      , m_floatingObjects(0)
119
      , m_floatingObjects(0)
122
      , m_positionedObjects(0)
120
      , m_positionedObjects(0)
123
      , m_inlineContinuation(0)
124
      , m_maxMargin(0)
121
      , m_maxMargin(0)
125
      , m_lineHeight(-1)
122
      , m_lineHeight(-1)
126
{
123
{
Lines 161-174 void RenderBlock::destroy() WebCore/rendering/RenderBlock.cpp_sec4
161
    // Make sure to destroy anonymous children first while they are still connected to the rest of the tree, so that they will
158
    // Make sure to destroy anonymous children first while they are still connected to the rest of the tree, so that they will
162
    // properly dirty line boxes that they are removed from. Effects that do :before/:after only on hover could crash otherwise.
159
    // properly dirty line boxes that they are removed from. Effects that do :before/:after only on hover could crash otherwise.
163
    children()->destroyLeftoverChildren();
160
    children()->destroyLeftoverChildren();
164
165
    // Destroy our continuation before anything other than anonymous children.
166
    // The reason we don't destroy it before anonymous children is that they may
167
    // have continuations of their own that are anonymous children of our continuation.
168
    if (m_inlineContinuation) {
169
        m_inlineContinuation->destroy();
170
        m_inlineContinuation = 0;
171
    }
172
    
161
    
173
    if (!documentBeingDestroyed()) {
162
    if (!documentBeingDestroyed()) {
174
        if (firstLineBox()) {
163
        if (firstLineBox()) {
Lines 316-322 void RenderBlock::addChild(RenderObject* WebCore/rendering/RenderBlock.cpp_sec5
316
        }
305
        }
317
    } else if (!childrenInline() && (newChild->isFloatingOrPositioned() || newChild->isInline())) {
306
    } else if (!childrenInline() && (newChild->isFloatingOrPositioned() || newChild->isInline())) {
318
        // If we're inserting an inline child but all of our children are blocks, then we have to make sure
307
        // If we're inserting an inline child but all of our children are blocks, then we have to make sure
319
        // it is put into an anomyous block box. We try to use an existing anonymous box if possible, otherwise
308
        // it is put into an anonymous block box. We try to use an existing anonymous box if possible, otherwise
320
        // a new one is created and inserted into our list of children in the appropriate position.
309
        // a new one is created and inserted into our list of children in the appropriate position.
321
        RenderObject* afterChild = beforeChild ? beforeChild->previousSibling() : lastChild();
310
        RenderObject* afterChild = beforeChild ? beforeChild->previousSibling() : lastChild();
322
311
Lines 490-498 void RenderBlock::removeLeftoverAnonymou WebCore/rendering/RenderBlock.cpp_sec6
490
    ASSERT(child->isAnonymousBlock());
479
    ASSERT(child->isAnonymousBlock());
491
    ASSERT(!child->childrenInline());
480
    ASSERT(!child->childrenInline());
492
    
481
    
493
    if (child->inlineContinuation()) 
494
        return;
495
    
496
    RenderObject* firstAnChild = child->m_children.firstChild();
482
    RenderObject* firstAnChild = child->m_children.firstChild();
497
    RenderObject* lastAnChild = child->m_children.lastChild();
483
    RenderObject* lastAnChild = child->m_children.lastChild();
498
    if (firstAnChild) {
484
    if (firstAnChild) {
Lines 535-541 void RenderBlock::removeChild(RenderObje WebCore/rendering/RenderBlock.cpp_sec7
535
    RenderObject* prev = oldChild->previousSibling();
521
    RenderObject* prev = oldChild->previousSibling();
536
    RenderObject* next = oldChild->nextSibling();
522
    RenderObject* next = oldChild->nextSibling();
537
    bool canDeleteAnonymousBlocks = !documentBeingDestroyed() && !isInline() && !oldChild->isInline() && 
523
    bool canDeleteAnonymousBlocks = !documentBeingDestroyed() && !isInline() && !oldChild->isInline() && 
538
                                    (!oldChild->isRenderBlock() || !toRenderBlock(oldChild)->inlineContinuation()) && 
524
                                    !oldChild->isRenderBlock() && 
539
                                    (!prev || (prev->isAnonymousBlock() && prev->childrenInline())) &&
525
                                    (!prev || (prev->isAnonymousBlock() && prev->childrenInline())) &&
540
                                    (!next || (next->isAnonymousBlock() && next->childrenInline()));
526
                                    (!next || (next->isAnonymousBlock() && next->childrenInline()));
541
    if (canDeleteAnonymousBlocks && prev && next) {
527
    if (canDeleteAnonymousBlocks && prev && next) {
Lines 598-606 bool RenderBlock::isSelfCollapsingBlock( WebCore/rendering/RenderBlock.cpp_sec8
598
    // on whether we have content that is all self-collapsing or not.
584
    // on whether we have content that is all self-collapsing or not.
599
    if (hasAutoHeight || ((style()->height().isFixed() || style()->height().isPercent()) && style()->height().isZero())) {
585
    if (hasAutoHeight || ((style()->height().isFixed() || style()->height().isPercent()) && style()->height().isZero())) {
600
        // If the block has inline children, see if we generated any line boxes.  If we have any
586
        // If the block has inline children, see if we generated any line boxes.  If we have any
601
        // line boxes, then we can't be self-collapsing, since we have content.
587
        // line boxes, then we can only be self-collapsing if we have nothing but anonymous inline blocks
602
        if (childrenInline())
588
        // that are also self-collapsing inside us.
603
            return !firstLineBox();
589
        if (childrenInline()) {
590
            for (RootInlineBox* child = firstRootBox(); child; child = child->nextRootBox()) {
591
                if (!child->anonymousInlineBlock() || !child->anonymousInlineBlock()->isSelfCollapsingBlock())
592
                    return false;
593
            }
594
            return true; // We have no line boxes, so we must be self-collapsing.
595
        }
604
        
596
        
605
        // Whether or not we collapse is dependent on whether all our normal flow children
597
        // Whether or not we collapse is dependent on whether all our normal flow children
606
        // are also self-collapsing.
598
        // are also self-collapsing.
Lines 855-861 void RenderBlock::addOverflowFromFloats( WebCore/rendering/RenderBlock.cpp_sec9
855
847
856
bool RenderBlock::expandsToEncloseOverhangingFloats() const
848
bool RenderBlock::expandsToEncloseOverhangingFloats() const
857
{
849
{
858
    return isInlineBlockOrInlineTable() || isFloatingOrPositioned() || hasOverflowClip() || (parent() && parent()->isFlexibleBox()) || hasColumns() || isTableCell() || isFieldset();
850
    return isFloatingOrPositioned() || hasOverflowClip() || (parent() && parent()->isFlexibleBox()) || hasColumns() || isTableCell() || isFieldset() ||
851
           (isInlineBlockOrInlineTable() && !isAnonymousInlineBlock());
859
}
852
}
860
853
861
void RenderBlock::adjustPositionedBlock(RenderBox* child, const MarginInfo& marginInfo)
854
void RenderBlock::adjustPositionedBlock(RenderBox* child, const MarginInfo& marginInfo)
Lines 1001-1019 bool RenderBlock::handleRunInChild(Rende WebCore/rendering/RenderBlock.cpp_sec10
1001
int RenderBlock::collapseMargins(RenderBox* child, MarginInfo& marginInfo)
994
int RenderBlock::collapseMargins(RenderBox* child, MarginInfo& marginInfo)
1002
{
995
{
1003
    // Get our max pos and neg top margins.
996
    // Get our max pos and neg top margins.
1004
    int posTop = child->maxTopMargin(true);
997
    int posTop = child ? child->maxTopMargin(true) : 0;
1005
    int negTop = child->maxTopMargin(false);
998
    int negTop = child ? child->maxTopMargin(false) : 0;
1006
999
1007
    // For self-collapsing blocks, collapse our bottom margins into our
1000
    // For self-collapsing blocks, collapse our bottom margins into our
1008
    // top to get new posTop and negTop values.
1001
    // top to get new posTop and negTop values.
1009
    if (child->isSelfCollapsingBlock()) {
1002
    if (child && child->isSelfCollapsingBlock()) {
1010
        posTop = max(posTop, child->maxBottomMargin(true));
1003
        posTop = max(posTop, child->maxBottomMargin(true));
1011
        negTop = max(negTop, child->maxBottomMargin(false));
1004
        negTop = max(negTop, child->maxBottomMargin(false));
1012
    }
1005
    }
1013
    
1006
    
1014
    // See if the top margin is quirky. We only care if this child has
1007
    // See if the top margin is quirky. We only care if this child has
1015
    // margins that will collapse with us.
1008
    // margins that will collapse with us.
1016
    bool topQuirk = child->isTopMarginQuirk() || style()->marginTopCollapse() == MDISCARD;
1009
    bool topQuirk = (child && child->isTopMarginQuirk()) || style()->marginTopCollapse() == MDISCARD;
1017
1010
1018
    if (marginInfo.canCollapseWithTop()) {
1011
    if (marginInfo.canCollapseWithTop()) {
1019
        // This child is collapsing with the top of the
1012
        // This child is collapsing with the top of the
Lines 1026-1032 int RenderBlock::collapseMargins(RenderB WebCore/rendering/RenderBlock.cpp_sec11
1026
        // collapse it away, even if the margin is smaller (www.webreference.com
1019
        // collapse it away, even if the margin is smaller (www.webreference.com
1027
        // has an example of this, a <dt> with 0.8em author-specified inside
1020
        // has an example of this, a <dt> with 0.8em author-specified inside
1028
        // a <dl> inside a <td>.
1021
        // a <dl> inside a <td>.
1029
        if (!marginInfo.determinedTopQuirk() && !topQuirk && (posTop-negTop)) {
1022
        if (!marginInfo.determinedTopQuirk() && !topQuirk && (posTop - negTop)) {
1030
            setTopMarginQuirk(false);
1023
            setTopMarginQuirk(false);
1031
            marginInfo.setDeterminedTopQuirk(true);
1024
            marginInfo.setDeterminedTopQuirk(true);
1032
        }
1025
        }
Lines 1044-1050 int RenderBlock::collapseMargins(RenderB WebCore/rendering/RenderBlock.cpp_sec12
1044
        marginInfo.setTopQuirk(topQuirk);
1037
        marginInfo.setTopQuirk(topQuirk);
1045
1038
1046
    int ypos = height();
1039
    int ypos = height();
1047
    if (child->isSelfCollapsingBlock()) {
1040
    if (child && child->isSelfCollapsingBlock()) {
1048
        // This child has no height.  We need to compute our
1041
        // This child has no height.  We need to compute our
1049
        // position before we collapse the child's margins together,
1042
        // position before we collapse the child's margins together,
1050
        // so that we can get an accurate position for the zero-height block.
1043
        // so that we can get an accurate position for the zero-height block.
Lines 1063-1075 int RenderBlock::collapseMargins(RenderB WebCore/rendering/RenderBlock.cpp_sec13
1063
            // that needs to be positioned correctly (e.g., a block that
1056
            // that needs to be positioned correctly (e.g., a block that
1064
            // had a specified height of 0 but that actually had subcontent).
1057
            // had a specified height of 0 but that actually had subcontent).
1065
            ypos = height() + collapsedTopPos - collapsedTopNeg;
1058
            ypos = height() + collapsedTopPos - collapsedTopNeg;
1066
    }
1059
    } else {
1067
    else {
1060
        if (child && child->style()->marginTopCollapse() == MSEPARATE) {
1068
        if (child->style()->marginTopCollapse() == MSEPARATE) {
1069
            setHeight(height() + marginInfo.margin() + child->marginTop());
1061
            setHeight(height() + marginInfo.margin() + child->marginTop());
1070
            ypos = height();
1062
            ypos = height();
1071
        }
1063
        } else if (!marginInfo.atTopOfBlock() ||
1072
        else if (!marginInfo.atTopOfBlock() ||
1073
            (!marginInfo.canCollapseTopWithChildren()
1064
            (!marginInfo.canCollapseTopWithChildren()
1074
             && (!style()->htmlHacks() || !marginInfo.quirkContainer() || !marginInfo.topQuirk()))) {
1065
             && (!style()->htmlHacks() || !marginInfo.quirkContainer() || !marginInfo.topQuirk()))) {
1075
            // We're collapsing with a previous sibling's margins and not
1066
            // We're collapsing with a previous sibling's margins and not
Lines 1078-1088 int RenderBlock::collapseMargins(RenderB WebCore/rendering/RenderBlock.cpp_sec14
1078
            ypos = height();
1069
            ypos = height();
1079
        }
1070
        }
1080
1071
1081
        marginInfo.setPosMargin(child->maxBottomMargin(true));
1072
        marginInfo.setPosMargin(child ? child->maxBottomMargin(true) : 0);
1082
        marginInfo.setNegMargin(child->maxBottomMargin(false));
1073
        marginInfo.setNegMargin(child ? child->maxBottomMargin(false) : 0);
1083
1074
1084
        if (marginInfo.margin())
1075
        if (marginInfo.margin())
1085
            marginInfo.setBottomQuirk(child->isBottomMarginQuirk() || style()->marginBottomCollapse() == MDISCARD);
1076
            marginInfo.setBottomQuirk((child && child->isBottomMarginQuirk()) || style()->marginBottomCollapse() == MDISCARD);
1086
    }
1077
    }
1087
    
1078
    
1088
    return ypos;
1079
    return ypos;
Lines 1749-1768 void RenderBlock::paintObject(PaintInfo& WebCore/rendering/RenderBlock.cpp_sec15
1749
    if ((paintPhase == PaintPhaseOutline || paintPhase == PaintPhaseSelfOutline) && hasOutline() && style()->visibility() == VISIBLE)
1740
    if ((paintPhase == PaintPhaseOutline || paintPhase == PaintPhaseSelfOutline) && hasOutline() && style()->visibility() == VISIBLE)
1750
        paintOutline(paintInfo.context, tx, ty, width(), height(), style());
1741
        paintOutline(paintInfo.context, tx, ty, width(), height(), style());
1751
1742
1752
    // 6. paint continuation outlines.
1743
    // 6. paint caret.
1753
    if ((paintPhase == PaintPhaseOutline || paintPhase == PaintPhaseChildOutlines)) {
1754
        if (inlineContinuation() && inlineContinuation()->hasOutline() && inlineContinuation()->style()->visibility() == VISIBLE) {
1755
            RenderInline* inlineRenderer = toRenderInline(inlineContinuation()->node()->renderer());
1756
            if (!inlineRenderer->hasSelfPaintingLayer())
1757
                containingBlock()->addContinuationWithOutline(inlineRenderer);
1758
            else if (!inlineRenderer->firstLineBox())
1759
                inlineRenderer->paintOutline(paintInfo.context, tx - x() + inlineRenderer->containingBlock()->x(),
1760
                                             ty - y() + inlineRenderer->containingBlock()->y());
1761
        }
1762
        paintContinuationOutlines(paintInfo, tx, ty);
1763
    }
1764
1765
    // 7. paint caret.
1766
    // If the caret's node's render object's containing block is this block, and the paint action is PaintPhaseForeground,
1744
    // If the caret's node's render object's containing block is this block, and the paint action is PaintPhaseForeground,
1767
    // then paint the caret.
1745
    // then paint the caret.
1768
    if (paintPhase == PaintPhaseForeground) {        
1746
    if (paintPhase == PaintPhaseForeground) {        
Lines 1825-1881 void RenderBlock::paintEllipsisBoxes(Pai WebCore/rendering/RenderBlock.cpp_sec16
1825
    }
1803
    }
1826
}
1804
}
1827
1805
1828
static ContinuationOutlineTableMap* continuationOutlineTable()
1829
{
1830
    DEFINE_STATIC_LOCAL(ContinuationOutlineTableMap, table, ());
1831
    return &table;
1832
}
1833
1834
void RenderBlock::addContinuationWithOutline(RenderInline* flow)
1835
{
1836
    // We can't make this work if the inline is in a layer.  We'll just rely on the broken
1837
    // way of painting.
1838
    ASSERT(!flow->layer() && !flow->isInlineContinuation());
1839
    
1840
    ContinuationOutlineTableMap* table = continuationOutlineTable();
1841
    ListHashSet<RenderInline*>* continuations = table->get(this);
1842
    if (!continuations) {
1843
        continuations = new ListHashSet<RenderInline*>;
1844
        table->set(this, continuations);
1845
    }
1846
    
1847
    continuations->add(flow);
1848
}
1849
1850
void RenderBlock::paintContinuationOutlines(PaintInfo& info, int tx, int ty)
1851
{
1852
    ContinuationOutlineTableMap* table = continuationOutlineTable();
1853
    if (table->isEmpty())
1854
        return;
1855
        
1856
    ListHashSet<RenderInline*>* continuations = table->get(this);
1857
    if (!continuations)
1858
        return;
1859
        
1860
    // Paint each continuation outline.
1861
    ListHashSet<RenderInline*>::iterator end = continuations->end();
1862
    for (ListHashSet<RenderInline*>::iterator it = continuations->begin(); it != end; ++it) {
1863
        // Need to add in the coordinates of the intervening blocks.
1864
        RenderInline* flow = *it;
1865
        RenderBlock* block = flow->containingBlock();
1866
        for ( ; block && block != this; block = block->containingBlock()) {
1867
            tx += block->x();
1868
            ty += block->y();
1869
        }
1870
        ASSERT(block);   
1871
        flow->paintOutline(info.context, tx, ty);
1872
    }
1873
    
1874
    // Delete
1875
    delete continuations;
1876
    table->remove(this);
1877
}
1878
1879
void RenderBlock::setSelectionState(SelectionState s)
1806
void RenderBlock::setSelectionState(SelectionState s)
1880
{
1807
{
1881
    if (selectionState() == s)
1808
    if (selectionState() == s)
Lines 2985-3009 void RenderBlock::clearFloats() WebCore/rendering/RenderBlock.cpp_sec17
2985
    // out of flow (like floating/positioned elements), and we also skip over any objects that may have shifted
2912
    // out of flow (like floating/positioned elements), and we also skip over any objects that may have shifted
2986
    // to avoid floats.
2913
    // to avoid floats.
2987
    bool parentHasFloats = false;
2914
    bool parentHasFloats = false;
2988
    RenderObject* prev = previousSibling();
2915
    RenderObject* prev = 0;
2989
    while (prev && (prev->isFloatingOrPositioned() || !prev->isBox() || !prev->isRenderBlock() || toRenderBlock(prev)->avoidsFloats())) {
2916
    RenderBlock* parentBlock = 0;
2990
        if (prev->isFloating())
2917
    if (isAnonymousInlineBlock()) {
2991
            parentHasFloats = true;
2918
        parentBlock = containingBlock();
2992
         prev = prev->previousSibling();
2919
        parentHasFloats = parentBlock->containsFloats();
2920
    } else {    
2921
        while (prev && (prev->isFloatingOrPositioned() || !prev->isBox() || !prev->isRenderBlock() || toRenderBlock(prev)->avoidsFloats())) {
2922
            if (prev->isFloating())
2923
                parentHasFloats = true;
2924
            prev = prev->previousSibling();
2925
        }
2926
        
2927
        parentBlock = parent()->isRenderBlock() ? toRenderBlock(parent()) : 0;
2993
    }
2928
    }
2994
2929
2995
    // First add in floats from the parent.
2930
    // First add in floats from the parent.
2996
    int offset = y();
2931
    int offset = y();
2997
    if (parentHasFloats) {
2932
    if (parentHasFloats)
2998
        RenderBlock* parentBlock = toRenderBlock(parent());
2999
        addIntrudingFloats(parentBlock, parentBlock->borderLeft() + parentBlock->paddingLeft(), offset);
2933
        addIntrudingFloats(parentBlock, parentBlock->borderLeft() + parentBlock->paddingLeft(), offset);
3000
    }
2934
3001
    
3002
    int xoffset = 0;
2935
    int xoffset = 0;
3003
    if (prev)
2936
    if (prev)
3004
        offset -= toRenderBox(prev)->y();
2937
        offset -= toRenderBox(prev)->y();
3005
    else if (parent()->isBox()) {
2938
    else if (parentBlock) {
3006
        prev = parent();
2939
        prev = parentBlock;
3007
        xoffset += toRenderBox(prev)->borderLeft() + toRenderBox(prev)->paddingLeft();
2940
        xoffset += toRenderBox(prev)->borderLeft() + toRenderBox(prev)->paddingLeft();
3008
    }
2941
    }
3009
2942
Lines 3138-3144 void RenderBlock::addIntrudingFloats(Ren WebCore/rendering/RenderBlock.cpp_sec18
3138
                // above.  |xoff| will equal -flow->marginLeft() in this case, so it's already been taken
3071
                // above.  |xoff| will equal -flow->marginLeft() in this case, so it's already been taken
3139
                // into account.  Only apply this code if |child| is false, since otherwise the left margin
3072
                // into account.  Only apply this code if |child| is false, since otherwise the left margin
3140
                // will get applied twice.
3073
                // will get applied twice.
3141
                if (prev != parent())
3074
                if (prev != containingBlock())
3142
                    floatingObj->m_left += prev->marginLeft();
3075
                    floatingObj->m_left += prev->marginLeft();
3143
                floatingObj->m_left -= marginLeft();
3076
                floatingObj->m_left -= marginLeft();
3144
                floatingObj->m_shouldPaint = false;  // We are not in the direct inheritance chain for this float. We will never paint it.
3077
                floatingObj->m_shouldPaint = false;  // We are not in the direct inheritance chain for this float. We will never paint it.
Lines 3183-3189 void RenderBlock::markAllDescendantsWith WebCore/rendering/RenderBlock.cpp_sec19
3183
        removeFloatingObject(floatToRemove);
3116
        removeFloatingObject(floatToRemove);
3184
3117
3185
    // Iterate over our children and mark them as needed.
3118
    // Iterate over our children and mark them as needed.
3186
    if (!childrenInline()) {
3119
    if (childrenInline()) {
3120
        for (RootInlineBox* box = firstRootBox(); box; box = box->nextRootBox()) {
3121
            RenderBlock* childBlock = box->anonymousInlineBlock();
3122
            if (childBlock && (floatToRemove ? childBlock->containsFloat(floatToRemove) : childBlock->containsFloats()))
3123
                childBlock->markAllDescendantsWithFloatsForLayout(floatToRemove, inLayout);
3124
        }
3125
    } else {
3187
        for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
3126
        for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
3188
            if ((!floatToRemove && child->isFloatingOrPositioned()) || !child->isRenderBlock())
3127
            if ((!floatToRemove && child->isFloatingOrPositioned()) || !child->isRenderBlock())
3189
                continue;
3128
                continue;
Lines 4142-4155 void RenderBlock::calcInlinePrefWidths() WebCore/rendering/RenderBlock.cpp_sec20
4142
                } else
4081
                } else
4143
                    clearPreviousFloat = false;
4082
                    clearPreviousFloat = false;
4144
4083
4145
                bool canBreakReplacedElement = !child->isImage() || allowImagesToBreak;
4084
                bool canBreakReplacedElement = !child->isImage() || allowImagesToBreak || child->isAnonymousInlineBlock();
4146
                if ((canBreakReplacedElement && (autoWrap || oldAutoWrap)) || clearPreviousFloat) {
4085
                if ((canBreakReplacedElement && (autoWrap || oldAutoWrap)) || clearPreviousFloat) {
4147
                    m_minPrefWidth = max(inlineMin, m_minPrefWidth);
4086
                    m_minPrefWidth = max(inlineMin, m_minPrefWidth);
4148
                    inlineMin = 0;
4087
                    inlineMin = 0;
4149
                }
4088
                }
4150
4089
4151
                // If we're supposed to clear the previous float, then terminate maxwidth as well.
4090
                // If we're supposed to clear the previous float, then terminate maxwidth as well.
4152
                if (clearPreviousFloat) {
4091
                // Also do this for anonymous inline blocks.
4092
                if (clearPreviousFloat || child->isAnonymousInlineBlock()) {
4153
                    m_maxPrefWidth = max(inlineMax, m_maxPrefWidth);
4093
                    m_maxPrefWidth = max(inlineMax, m_maxPrefWidth);
4154
                    inlineMax = 0;
4094
                    inlineMax = 0;
4155
                }
4095
                }
Lines 4158-4172 void RenderBlock::calcInlinePrefWidths() WebCore/rendering/RenderBlock.cpp_sec21
4158
                int ti = 0;
4098
                int ti = 0;
4159
                if (!addedTextIndent) {
4099
                if (!addedTextIndent) {
4160
                    addedTextIndent = true;
4100
                    addedTextIndent = true;
4161
                    ti = style()->textIndent().calcMinValue(cw);
4101
                    if (!child->isAnonymousInlineBlock()) {
4162
                    childMin+=ti;
4102
                        ti = style()->textIndent().calcMinValue(cw);
4163
                    childMax+=ti;
4103
                        childMin += ti;
4104
                        childMax += ti;
4105
                    }
4164
                }
4106
                }
4165
4107
4166
                // Add our width to the max.
4108
                // Add our width to the max.
4167
                inlineMax += childMax;
4109
                inlineMax += childMax;
4168
4110
4169
                if (!autoWrap || !canBreakReplacedElement) {
4111
                if ((!autoWrap || !canBreakReplacedElement) && !child->isAnonymousInlineBlock()) {
4170
                    if (child->isFloating())
4112
                    if (child->isFloating())
4171
                        m_minPrefWidth = max(childMin, m_minPrefWidth);
4113
                        m_minPrefWidth = max(childMin, m_minPrefWidth);
4172
                    else
4114
                    else
Lines 4177-4182 void RenderBlock::calcInlinePrefWidths() WebCore/rendering/RenderBlock.cpp_sec22
4177
4119
4178
                    // Now start a new line.
4120
                    // Now start a new line.
4179
                    inlineMin = 0;
4121
                    inlineMin = 0;
4122
                    
4123
                    if (child->isAnonymousInlineBlock()) {
4124
                        // Terminate max width as well.
4125
                        m_maxPrefWidth = max(childMax, m_maxPrefWidth);
4126
                        inlineMax = 0;
4127
                    }
4180
                }
4128
                }
4181
4129
4182
                // We are no longer stripping whitespace at the start of
4130
                // We are no longer stripping whitespace at the start of
Lines 4417-4425 int RenderBlock::lineHeight(bool firstLi WebCore/rendering/RenderBlock.cpp_sec23
4417
    // the base class.  If we're being queried as though we're the root line
4365
    // the base class.  If we're being queried as though we're the root line
4418
    // box, then the fact that we're an inline-block is irrelevant, and we behave
4366
    // box, then the fact that we're an inline-block is irrelevant, and we behave
4419
    // just like a block.
4367
    // just like a block.
4420
    if (isReplaced() && !isRootLineBox)
4368
    if (isReplaced() && !isRootLineBox) {
4369
        if (isAnonymousInlineBlock())
4370
            return height();
4421
        return height() + marginTop() + marginBottom();
4371
        return height() + marginTop() + marginBottom();
4422
    
4372
    }
4373
4423
    if (firstLine && document()->usesFirstLineRules()) {
4374
    if (firstLine && document()->usesFirstLineRules()) {
4424
        RenderStyle* s = style(firstLine);
4375
        RenderStyle* s = style(firstLine);
4425
        if (s != style())
4376
        if (s != style())
Lines 4451-4456 int RenderBlock::baselinePosition(bool b WebCore/rendering/RenderBlock.cpp_sec24
4451
        // We also give up on finding a baseline if we have a vertical scrollbar, or if we are scrolled
4402
        // We also give up on finding a baseline if we have a vertical scrollbar, or if we are scrolled
4452
        // vertically (e.g., an overflow:hidden block that has had scrollTop moved) or if the baseline is outside
4403
        // vertically (e.g., an overflow:hidden block that has had scrollTop moved) or if the baseline is outside
4453
        // of our content box.
4404
        // of our content box.
4405
        if (isAnonymousInlineBlock())
4406
            return height();
4454
        int baselinePos = (layer() && (layer()->marquee() || layer()->verticalScrollbar() || layer()->scrollYOffset() != 0)) ? -1 : lastLineBoxBaseline();
4407
        int baselinePos = (layer() && (layer()->marquee() || layer()->verticalScrollbar() || layer()->scrollYOffset() != 0)) ? -1 : lastLineBoxBaseline();
4455
        if (baselinePos != -1 && baselinePos <= borderTop() + paddingTop() + contentHeight())
4408
        if (baselinePos != -1 && baselinePos <= borderTop() + paddingTop() + contentHeight())
4456
            return marginTop() + baselinePos;
4409
            return marginTop() + baselinePos;
Lines 4875-4934 void RenderBlock::setMaxBottomMargins(in WebCore/rendering/RenderBlock.cpp_sec25
4875
    m_maxMargin->m_bottomNeg = neg;
4828
    m_maxMargin->m_bottomNeg = neg;
4876
}
4829
}
4877
4830
4878
void RenderBlock::absoluteRects(Vector<IntRect>& rects, int tx, int ty)
4879
{
4880
    // For blocks inside inlines, we go ahead and include margins so that we run right up to the
4881
    // inline boxes above and below us (thus getting merged with them to form a single irregular
4882
    // shape).
4883
    if (inlineContinuation()) {
4884
        rects.append(IntRect(tx, ty - collapsedMarginTop(),
4885
                             width(), height() + collapsedMarginTop() + collapsedMarginBottom()));
4886
        inlineContinuation()->absoluteRects(rects,
4887
                                            tx - x() + inlineContinuation()->containingBlock()->x(),
4888
                                            ty - y() + inlineContinuation()->containingBlock()->y());
4889
    } else
4890
        rects.append(IntRect(tx, ty, width(), height()));
4891
}
4892
4893
void RenderBlock::absoluteQuads(Vector<FloatQuad>& quads)
4894
{
4895
    // For blocks inside inlines, we go ahead and include margins so that we run right up to the
4896
    // inline boxes above and below us (thus getting merged with them to form a single irregular
4897
    // shape).
4898
    if (inlineContinuation()) {
4899
        FloatRect localRect(0, -collapsedMarginTop(),
4900
                            width(), height() + collapsedMarginTop() + collapsedMarginBottom());
4901
        quads.append(localToAbsoluteQuad(localRect));
4902
        inlineContinuation()->absoluteQuads(quads);
4903
    } else
4904
        quads.append(RenderBox::localToAbsoluteQuad(FloatRect(0, 0, width(), height())));
4905
}
4906
4907
IntRect RenderBlock::rectWithOutlineForRepaint(RenderBoxModelObject* repaintContainer, int outlineWidth)
4908
{
4909
    IntRect r(RenderBox::rectWithOutlineForRepaint(repaintContainer, outlineWidth));
4910
    if (inlineContinuation())
4911
        r.inflateY(collapsedMarginTop());
4912
    return r;
4913
}
4914
4915
RenderObject* RenderBlock::hoverAncestor() const
4916
{
4917
    return inlineContinuation() ? inlineContinuation() : RenderBox::hoverAncestor();
4918
}
4919
4920
void RenderBlock::updateDragState(bool dragOn)
4921
{
4922
    RenderBox::updateDragState(dragOn);
4923
    if (inlineContinuation())
4924
        inlineContinuation()->updateDragState(dragOn);
4925
}
4926
4927
RenderStyle* RenderBlock::outlineStyleForRepaint() const
4928
{
4929
    return inlineContinuation() ? inlineContinuation()->style() : style();
4930
}
4931
4932
void RenderBlock::childBecameNonInline(RenderObject*)
4831
void RenderBlock::childBecameNonInline(RenderObject*)
4933
{
4832
{
4934
    makeChildrenNonInline();
4833
    makeChildrenNonInline();
Lines 4937-4962 void RenderBlock::childBecameNonInline(R WebCore/rendering/RenderBlock.cpp_sec26
4937
    // |this| may be dead here
4836
    // |this| may be dead here
4938
}
4837
}
4939
4838
4940
void RenderBlock::updateHitTestResult(HitTestResult& result, const IntPoint& point)
4941
{
4942
    if (result.innerNode())
4943
        return;
4944
4945
    Node* n = node();
4946
    if (inlineContinuation())
4947
        // We are in the margins of block elements that are part of a continuation.  In
4948
        // this case we're actually still inside the enclosing inline element that was
4949
        // split.  Go ahead and set our inner node accordingly.
4950
        n = inlineContinuation()->node();
4951
4952
    if (n) {
4953
        result.setInnerNode(n);
4954
        if (!result.innerNonSharedNode())
4955
            result.setInnerNonSharedNode(n);
4956
        result.setLocalPoint(point);
4957
    }
4958
}
4959
4960
IntRect RenderBlock::localCaretRect(InlineBox* inlineBox, int caretOffset, int* extraWidthToEndOfLine)
4839
IntRect RenderBlock::localCaretRect(InlineBox* inlineBox, int caretOffset, int* extraWidthToEndOfLine)
4961
{
4840
{
4962
    // Do the normal calculation in most cases.
4841
    // Do the normal calculation in most cases.
Lines 5037-5056 IntRect RenderBlock::localCaretRect(Inli WebCore/rendering/RenderBlock.cpp_sec27
5037
4916
5038
void RenderBlock::addFocusRingRects(Vector<IntRect>& rects, int tx, int ty)
4917
void RenderBlock::addFocusRingRects(Vector<IntRect>& rects, int tx, int ty)
5039
{
4918
{
5040
    // For blocks inside inlines, we go ahead and include margins so that we run right up to the
4919
    if (width() || height())
5041
    // inline boxes above and below us (thus getting merged with them to form a single irregular
5042
    // shape).
5043
    if (inlineContinuation()) {
5044
        // FIXME: This check really isn't accurate. 
5045
        bool nextInlineHasLineBox = inlineContinuation()->firstLineBox();
5046
        // FIXME: This is wrong. The principal renderer may not be the continuation preceding this block.
5047
        bool prevInlineHasLineBox = toRenderInline(inlineContinuation()->node()->renderer())->firstLineBox(); 
5048
        int topMargin = prevInlineHasLineBox ? collapsedMarginTop() : 0;
5049
        int bottomMargin = nextInlineHasLineBox ? collapsedMarginBottom() : 0;
5050
        IntRect rect(tx, ty - topMargin, width(), height() + topMargin + bottomMargin);
5051
        if (!rect.isEmpty())
5052
            rects.append(rect);
5053
    } else if (width() && height())
5054
        rects.append(IntRect(tx, ty, width(), height()));
4920
        rects.append(IntRect(tx, ty, width(), height()));
5055
4921
5056
    if (!hasOverflowClip() && !hasControlClip()) {
4922
    if (!hasOverflowClip() && !hasControlClip()) {
Lines 5075-5085 void RenderBlock::addFocusRingRects(Vect WebCore/rendering/RenderBlock.cpp_sec28
5075
            }
4941
            }
5076
        }
4942
        }
5077
    }
4943
    }
5078
5079
    if (inlineContinuation())
5080
        inlineContinuation()->addFocusRingRects(rects, 
5081
                                                tx - x() + inlineContinuation()->containingBlock()->x(),
5082
                                                ty - y() + inlineContinuation()->containingBlock()->y());
5083
}
4944
}
5084
4945
5085
RenderBlock* RenderBlock::createAnonymousBlock(bool isFlexibleBox) const
4946
RenderBlock* RenderBlock::createAnonymousBlock(bool isFlexibleBox) const
Lines 5111-5116 const char* RenderBlock::renderName() co WebCore/rendering/RenderBlock.cpp_sec29
5111
        return "RenderBlock (positioned)";
4972
        return "RenderBlock (positioned)";
5112
    if (isAnonymousBlock())
4973
    if (isAnonymousBlock())
5113
        return "RenderBlock (anonymous)";
4974
        return "RenderBlock (anonymous)";
4975
    else if (isAnonymousInlineBlock())
4976
        return "RenderBlock (anonymous inline-block)";
5114
    else if (isAnonymous())
4977
    else if (isAnonymous())
5115
        return "RenderBlock (generated)";
4978
        return "RenderBlock (generated)";
5116
    if (isRelPositioned())
4979
    if (isRelPositioned())
- WebCore/rendering/RenderBlock.h -30 / +13 lines
Lines 129-143 public: WebCore/rendering/RenderBlock.h_sec1
129
129
130
    void adjustRectForColumns(IntRect&) const;
130
    void adjustRectForColumns(IntRect&) const;
131
131
132
    void addContinuationWithOutline(RenderInline*);
133
134
    RenderInline* inlineContinuation() const { return m_inlineContinuation; }
135
    void setInlineContinuation(RenderInline* c) { m_inlineContinuation = c; }
136
137
    // This function is a convenience helper for creating an anonymous block that inherits its
132
    // This function is a convenience helper for creating an anonymous block that inherits its
138
    // style from this RenderBlock.
133
    // style from this RenderBlock.
139
    RenderBlock* createAnonymousBlock(bool isFlexibleBox = false) const;
134
    RenderBlock* createAnonymousBlock(bool isFlexibleBox = false) const;
140
135
136
    virtual void paint(PaintInfo&, int tx, int ty);
137
    virtual void paintObject(PaintInfo&, int tx, int ty);
138
139
    bool inRootBlockContext() const;
140
141
    static void appendRunsForObject(int start, int end, RenderObject*, InlineBidiResolver&);    
142
    static bool requiresLineBox(const InlineIterator&, bool isLineEmpty = true, bool previousLineBrokeCleanly = true);
143
141
protected:
144
protected:
142
    void moveChildTo(RenderObject* to, RenderObjectChildList* toChildList, RenderObject* child);
145
    void moveChildTo(RenderObject* to, RenderObjectChildList* toChildList, RenderObject* child);
143
    void moveChildTo(RenderObject* to, RenderObjectChildList* toChildList, RenderObject* beforeChild, RenderObject* child);
146
    void moveChildTo(RenderObject* to, RenderObjectChildList* toChildList, RenderObject* beforeChild, RenderObject* child);
Lines 165-173 protected: WebCore/rendering/RenderBlock.h_sec2
165
168
166
    void layoutPositionedObjects(bool relayoutChildren);
169
    void layoutPositionedObjects(bool relayoutChildren);
167
170
168
    virtual void paint(PaintInfo&, int tx, int ty);
169
    virtual void paintObject(PaintInfo&, int tx, int ty);
170
171
    int rightRelOffset(int y, int fixedOffset, bool applyTextIndent = true, int* heightRemaining = 0) const;
171
    int rightRelOffset(int y, int fixedOffset, bool applyTextIndent = true, int* heightRemaining = 0) const;
172
    int leftRelOffset(int y, int fixedOffset, bool applyTextIndent = true, int* heightRemaining = 0) const;
172
    int leftRelOffset(int y, int fixedOffset, bool applyTextIndent = true, int* heightRemaining = 0) const;
173
173
Lines 180-187 protected: WebCore/rendering/RenderBlock.h_sec3
180
180
181
    virtual void updateFirstLetter();
181
    virtual void updateFirstLetter();
182
182
183
    virtual void updateHitTestResult(HitTestResult&, const IntPoint&);
184
185
    // Delay update scrollbar until finishDelayRepaint() will be
183
    // Delay update scrollbar until finishDelayRepaint() will be
186
    // called. This function is used when a flexbox is laying out its
184
    // called. This function is used when a flexbox is laying out its
187
    // descendant. If multiple calls are made to startDelayRepaint(),
185
    // descendant. If multiple calls are made to startDelayRepaint(),
Lines 245-251 private: WebCore/rendering/RenderBlock.h_sec4
245
        bool everHadLayout;
243
        bool everHadLayout;
246
    };
244
    };
247
245
248
    // The following functions' implementations are in RenderBlockLineLayout.cpp.
246
    class MarginInfo;
247
248
    // The following functions' implementations are in RenderBlockLineLayout.cpp.    
249
    void bidiReorderLine(InlineBidiResolver&, const InlineIterator& end, bool previousLineBrokeCleanly);
249
    void bidiReorderLine(InlineBidiResolver&, const InlineIterator& end, bool previousLineBrokeCleanly);
250
    RootInlineBox* determineStartPosition(bool& firstLine, bool& fullLayout, bool& previousLineBrokeCleanly,
250
    RootInlineBox* determineStartPosition(bool& firstLine, bool& fullLayout, bool& previousLineBrokeCleanly,
251
                                          InlineBidiResolver&, Vector<FloatWithRect>& floats, unsigned& numCleanFloats);
251
                                          InlineBidiResolver&, Vector<FloatWithRect>& floats, unsigned& numCleanFloats);
Lines 258-264 private: WebCore/rendering/RenderBlock.h_sec5
258
    void skipTrailingWhitespace(InlineIterator&, bool isLineEmpty, bool previousLineBrokeCleanly);
258
    void skipTrailingWhitespace(InlineIterator&, bool isLineEmpty, bool previousLineBrokeCleanly);
259
    int skipLeadingWhitespace(InlineBidiResolver&, bool firstLine, bool isLineEmpty, bool previousLineBrokeCleanly);
259
    int skipLeadingWhitespace(InlineBidiResolver&, bool firstLine, bool isLineEmpty, bool previousLineBrokeCleanly);
260
    void fitBelowFloats(int widthToFit, bool firstLine, int& availableWidth);
260
    void fitBelowFloats(int widthToFit, bool firstLine, int& availableWidth);
261
    InlineIterator findNextLineBreak(InlineBidiResolver&, bool firstLine, bool& isLineEmpty, bool& previousLineBrokeCleanly, EClear* clear = 0);
261
    InlineIterator findNextLineBreak(InlineBidiResolver&, bool firstLine, bool& isLineEmpty, bool& previousLineBrokeCleanly, MarginInfo&, EClear* clear = 0);
262
    RootInlineBox* constructLine(unsigned runCount, BidiRun* firstRun, BidiRun* lastRun, bool firstLine, bool lastLine, RenderObject* endObject);
262
    RootInlineBox* constructLine(unsigned runCount, BidiRun* firstRun, BidiRun* lastRun, bool firstLine, bool lastLine, RenderObject* endObject);
263
    InlineFlowBox* createLineBoxes(RenderObject*, bool firstLine);
263
    InlineFlowBox* createLineBoxes(RenderObject*, bool firstLine);
264
    void computeHorizontalPositionsForLine(RootInlineBox*, bool firstLine, BidiRun* firstRun, BidiRun* trailingSpaceRun, bool reachedEnd);
264
    void computeHorizontalPositionsForLine(RootInlineBox*, bool firstLine, BidiRun* firstRun, BidiRun* trailingSpaceRun, bool reachedEnd);
Lines 313-325 private: WebCore/rendering/RenderBlock.h_sec6
313
    // Obtains the nearest enclosing block (including this block) that contributes a first-line style to our inline
313
    // Obtains the nearest enclosing block (including this block) that contributes a first-line style to our inline
314
    // children.
314
    // children.
315
    virtual RenderBlock* firstLineBlock() const;
315
    virtual RenderBlock* firstLineBlock() const;
316
    bool inRootBlockContext() const;
317
318
    virtual IntRect rectWithOutlineForRepaint(RenderBoxModelObject* repaintContainer, int outlineWidth);
319
    virtual RenderStyle* outlineStyleForRepaint() const;
320
    
316
    
321
    virtual RenderObject* hoverAncestor() const;
322
    virtual void updateDragState(bool dragOn);
323
    virtual void childBecameNonInline(RenderObject* child);
317
    virtual void childBecameNonInline(RenderObject* child);
324
318
325
    virtual IntRect selectionRectForRepaint(RenderBoxModelObject* repaintContainer, bool /*clipToVisibleContent*/)
319
    virtual IntRect selectionRectForRepaint(RenderBoxModelObject* repaintContainer, bool /*clipToVisibleContent*/)
Lines 339-354 private: WebCore/rendering/RenderBlock.h_sec7
339
    int leftSelectionOffset(RenderBlock* rootBlock, int y);
333
    int leftSelectionOffset(RenderBlock* rootBlock, int y);
340
    int rightSelectionOffset(RenderBlock* rootBlock, int y);
334
    int rightSelectionOffset(RenderBlock* rootBlock, int y);
341
335
342
    virtual void absoluteRects(Vector<IntRect>&, int tx, int ty);
343
    virtual void absoluteQuads(Vector<FloatQuad>&);
344
345
    int desiredColumnWidth() const;
336
    int desiredColumnWidth() const;
346
    unsigned desiredColumnCount() const;
337
    unsigned desiredColumnCount() const;
347
    Vector<IntRect>* columnRects() const;
338
    Vector<IntRect>* columnRects() const;
348
    void setDesiredColumnCountAndWidth(int count, int width);
339
    void setDesiredColumnCountAndWidth(int count, int width);
349
    int columnGap() const;
340
    int columnGap() const;
350
    
351
    void paintContinuationOutlines(PaintInfo&, int tx, int ty);
352
341
353
    virtual IntRect localCaretRect(InlineBox*, int caretOffset, int* extraWidthToEndOfLine = 0);
342
    virtual IntRect localCaretRect(InlineBox*, int caretOffset, int* extraWidthToEndOfLine = 0);
354
343
Lines 484-495 private: WebCore/rendering/RenderBlock.h_sec8
484
    DeprecatedPtrList<FloatingObject>* m_floatingObjects;
473
    DeprecatedPtrList<FloatingObject>* m_floatingObjects;
485
    ListHashSet<RenderBox*>* m_positionedObjects;
474
    ListHashSet<RenderBox*>* m_positionedObjects;
486
475
487
    // An inline can be split with blocks occurring in between the inline content.
488
    // When this occurs we need a pointer to our next object.  We can basically be
489
    // split into a sequence of inlines and blocks.  The continuation will either be
490
    // an anonymous block (that houses other blocks) or it will be an inline flow.
491
    RenderInline* m_inlineContinuation;
492
493
    // Allocated only when some of these fields have non-default values
476
    // Allocated only when some of these fields have non-default values
494
    struct MaxMargin : Noncopyable {
477
    struct MaxMargin : Noncopyable {
495
        MaxMargin(const RenderBlock* o) 
478
        MaxMargin(const RenderBlock* o) 
Lines 517-523 private: WebCore/rendering/RenderBlock.h_sec9
517
    RenderLineBoxList m_lineBoxes;   // All of the root line boxes created for this block flow.  For example, <div>Hello<br>world.</div> will have two total lines for the <div>.
500
    RenderLineBoxList m_lineBoxes;   // All of the root line boxes created for this block flow.  For example, <div>Hello<br>world.</div> will have two total lines for the <div>.
518
501
519
    mutable int m_lineHeight;
502
    mutable int m_lineHeight;
520
    
503
521
    // RenderRubyBase objects need to be able to split and merge, moving their children around
504
    // RenderRubyBase objects need to be able to split and merge, moving their children around
522
    // (calling moveChildTo, moveAllChildrenTo, and makeChildrenNonInline).
505
    // (calling moveChildTo, moveAllChildrenTo, and makeChildrenNonInline).
523
    friend class RenderRubyBase;
506
    friend class RenderRubyBase;
- WebCore/rendering/RenderBlockLineLayout.cpp -324 / +94 lines
Lines 24-29 WebCore/rendering/RenderBlockLineLayout.cpp_sec1
24
24
25
#include "BidiResolver.h"
25
#include "BidiResolver.h"
26
#include "CharacterNames.h"
26
#include "CharacterNames.h"
27
#include "InlineIterator.h"
27
#include "InlineTextBox.h"
28
#include "InlineTextBox.h"
28
#include "Logging.h"
29
#include "Logging.h"
29
#include "RenderArena.h"
30
#include "RenderArena.h"
Lines 46-81 namespace WebCore { WebCore/rendering/RenderBlockLineLayout.cpp_sec2
46
// We don't let our line box tree for a single line get any deeper than this.
47
// We don't let our line box tree for a single line get any deeper than this.
47
const unsigned cMaxLineDepth = 200;
48
const unsigned cMaxLineDepth = 200;
48
49
49
class InlineIterator {
50
public:
51
    InlineIterator()
52
        : block(0)
53
        , obj(0)
54
        , pos(0)
55
        , nextBreakablePosition(-1)
56
    {
57
    }
58
59
    InlineIterator(RenderBlock* b, RenderObject* o, unsigned p)
60
        : block(b)
61
        , obj(o)
62
        , pos(p)
63
        , nextBreakablePosition(-1)
64
    {
65
    }
66
67
    void increment(InlineBidiResolver* resolver = 0);
68
    bool atEnd() const;
69
70
    UChar current() const;
71
    Direction direction() const;
72
73
    RenderBlock* block;
74
    RenderObject* obj;
75
    unsigned pos;
76
    int nextBreakablePosition;
77
};
78
79
static int getBorderPaddingMargin(RenderBoxModelObject* child, bool endOfInline)
50
static int getBorderPaddingMargin(RenderBoxModelObject* child, bool endOfInline)
80
{
51
{
81
    bool leftSide = (child->style()->direction() == LTR) ? !endOfInline : endOfInline;
52
    bool leftSide = (child->style()->direction() == LTR) ? !endOfInline : endOfInline;
Lines 100-346 static int inlineWidth(RenderObject* chi WebCore/rendering/RenderBlockLineLayout.cpp_sec3
100
    return extraWidth;
71
    return extraWidth;
101
}
72
}
102
73
103
struct BidiRun : BidiCharacterRun {
104
    BidiRun(int start, int stop, RenderObject* object, BidiContext* context, Direction dir)
105
        : BidiCharacterRun(start, stop, context, dir)
106
        , m_object(object)
107
        , m_box(0)
108
    {
109
    }
110
111
    void destroy();
112
113
    // Overloaded new operator.
114
    void* operator new(size_t, RenderArena*) throw();
115
116
    // Overridden to prevent the normal delete from being called.
117
    void operator delete(void*, size_t);
118
119
    BidiRun* next() { return static_cast<BidiRun*>(m_next); }
120
121
private:
122
    // The normal operator new is disallowed.
123
    void* operator new(size_t) throw();
124
125
public:
126
    RenderObject* m_object;
127
    InlineBox* m_box;
128
};
129
130
#ifndef NDEBUG
131
static RefCountedLeakCounter bidiRunCounter("BidiRun");
132
133
static bool inBidiRunDestroy;
134
#endif
135
136
void BidiRun::destroy()
137
{
138
#ifndef NDEBUG
139
    inBidiRunDestroy = true;
140
#endif
141
    RenderArena* renderArena = m_object->renderArena();
142
    delete this;
143
#ifndef NDEBUG
144
    inBidiRunDestroy = false;
145
#endif
146
147
    // Recover the size left there for us by operator delete and free the memory.
148
    renderArena->free(*reinterpret_cast<size_t*>(this), this);
149
}
150
151
void* BidiRun::operator new(size_t sz, RenderArena* renderArena) throw()
152
{
153
#ifndef NDEBUG
154
    bidiRunCounter.increment();
155
#endif
156
    return renderArena->allocate(sz);
157
}
158
159
void BidiRun::operator delete(void* ptr, size_t sz)
160
{
161
#ifndef NDEBUG
162
    bidiRunCounter.decrement();
163
#endif
164
    ASSERT(inBidiRunDestroy);
165
166
    // Stash size where destroy() can find it.
167
    *(size_t*)ptr = sz;
168
}
169
170
// ---------------------------------------------------------------------
171
172
inline bool operator==(const InlineIterator& it1, const InlineIterator& it2)
173
{
174
    return it1.pos == it2.pos && it1.obj == it2.obj;
175
}
176
177
inline bool operator!=(const InlineIterator& it1, const InlineIterator& it2)
178
{
179
    return it1.pos != it2.pos || it1.obj != it2.obj;
180
}
181
182
static inline RenderObject* bidiNext(RenderBlock* block, RenderObject* current, InlineBidiResolver* resolver = 0, bool skipInlines = true, bool* endOfInlinePtr = 0)
183
{
184
    RenderObject* next = 0;
185
    bool oldEndOfInline = endOfInlinePtr ? *endOfInlinePtr : false;
186
    bool endOfInline = false;
187
188
    while (current) {
189
        next = 0;
190
        if (!oldEndOfInline && !current->isFloating() && !current->isReplaced() && !current->isPositioned() && !current->isText()) {
191
            next = current->firstChild();
192
            if (next && resolver && next->isRenderInline()) {
193
                EUnicodeBidi ub = next->style()->unicodeBidi();
194
                if (ub != UBNormal) {
195
                    TextDirection dir = next->style()->direction();
196
                    Direction d = (ub == Embed
197
                        ? (dir == RTL ? RightToLeftEmbedding : LeftToRightEmbedding)
198
                        : (dir == RTL ? RightToLeftOverride : LeftToRightOverride));
199
                    resolver->embed(d);
200
                }
201
            }
202
        }
203
204
        if (!next) {
205
            if (!skipInlines && !oldEndOfInline && current->isRenderInline()) {
206
                next = current;
207
                endOfInline = true;
208
                break;
209
            }
210
211
            while (current && current != block) {
212
                if (resolver && current->isRenderInline() && current->style()->unicodeBidi() != UBNormal)
213
                    resolver->embed(PopDirectionalFormat);
214
215
                next = current->nextSibling();
216
                if (next) {
217
                    if (resolver && next->isRenderInline()) {
218
                        EUnicodeBidi ub = next->style()->unicodeBidi();
219
                        if (ub != UBNormal) {
220
                            TextDirection dir = next->style()->direction();
221
                            Direction d = (ub == Embed
222
                                ? (dir == RTL ? RightToLeftEmbedding: LeftToRightEmbedding)
223
                                : (dir == RTL ? RightToLeftOverride : LeftToRightOverride));
224
                            resolver->embed(d);
225
                        }
226
                    }
227
                    break;
228
                }
229
                
230
                current = current->parent();
231
                if (!skipInlines && current && current != block && current->isRenderInline()) {
232
                    next = current;
233
                    endOfInline = true;
234
                    break;
235
                }
236
            }
237
        }
238
239
        if (!next)
240
            break;
241
242
        if (next->isText() || next->isFloating() || next->isReplaced() || next->isPositioned()
243
            || ((!skipInlines || !next->firstChild()) // Always return EMPTY inlines.
244
                && next->isRenderInline()))
245
            break;
246
        current = next;
247
    }
248
249
    if (endOfInlinePtr)
250
        *endOfInlinePtr = endOfInline;
251
252
    return next;
253
}
254
255
static RenderObject* bidiFirst(RenderBlock* block, InlineBidiResolver* resolver, bool skipInlines = true)
256
{
257
    if (!block->firstChild())
258
        return 0;
259
    
260
    RenderObject* o = block->firstChild();
261
    if (o->isRenderInline()) {
262
        if (resolver) {
263
            EUnicodeBidi ub = o->style()->unicodeBidi();
264
            if (ub != UBNormal) {
265
                TextDirection dir = o->style()->direction();
266
                Direction d = (ub == Embed
267
                    ? (dir == RTL ? RightToLeftEmbedding : LeftToRightEmbedding)
268
                    : (dir == RTL ? RightToLeftOverride : LeftToRightOverride));
269
                resolver->embed(d);
270
            }
271
        }
272
        if (skipInlines && o->firstChild())
273
            o = bidiNext(block, o, resolver, skipInlines);
274
        else {
275
            // Never skip empty inlines.
276
            if (resolver)
277
                resolver->commitExplicitEmbedding();
278
            return o; 
279
        }
280
    }
281
282
    if (o && !o->isText() && !o->isReplaced() && !o->isFloating() && !o->isPositioned())
283
        o = bidiNext(block, o, resolver, skipInlines);
284
285
    if (resolver)
286
        resolver->commitExplicitEmbedding();
287
    return o;
288
}
289
290
inline void InlineIterator::increment(InlineBidiResolver* resolver)
291
{
292
    if (!obj)
293
        return;
294
    if (obj->isText()) {
295
        pos++;
296
        if (pos >= toRenderText(obj)->textLength()) {
297
            obj = bidiNext(block, obj, resolver);
298
            pos = 0;
299
            nextBreakablePosition = -1;
300
        }
301
    } else {
302
        obj = bidiNext(block, obj, resolver);
303
        pos = 0;
304
        nextBreakablePosition = -1;
305
    }
306
}
307
308
template<>
309
inline void InlineBidiResolver::increment()
310
{
311
    current.increment(this);
312
}
313
314
inline bool InlineIterator::atEnd() const
315
{
316
    return !obj;
317
}
318
319
inline UChar InlineIterator::current() const
320
{
321
    if (!obj || !obj->isText())
322
        return 0;
323
324
    RenderText* text = toRenderText(obj);
325
    if (pos >= text->textLength())
326
        return 0;
327
328
    return text->characters()[pos];
329
}
330
331
ALWAYS_INLINE Direction InlineIterator::direction() const
332
{
333
    if (UChar c = current())
334
        return Unicode::direction(c);
335
336
    if (obj && obj->isListMarker())
337
        return obj->style()->direction() == LTR ? LeftToRight : RightToLeft;
338
339
    return OtherNeutral;
340
}
341
342
// -------------------------------------------------------------------------------------------------
343
344
static void chopMidpointsAt(LineMidpointState& lineMidpointState, RenderObject* obj, unsigned pos)
74
static void chopMidpointsAt(LineMidpointState& lineMidpointState, RenderObject* obj, unsigned pos)
345
{
75
{
346
    if (!lineMidpointState.numMidpoints)
76
    if (!lineMidpointState.numMidpoints)
Lines 398-404 static void addMidpoint(LineMidpointStat WebCore/rendering/RenderBlockLineLayout.cpp_sec4
398
    midpoints[lineMidpointState.numMidpoints++] = midpoint;
128
    midpoints[lineMidpointState.numMidpoints++] = midpoint;
399
}
129
}
400
130
401
static void appendRunsForObject(int start, int end, RenderObject* obj, InlineBidiResolver& resolver)
131
void RenderBlock::appendRunsForObject(int start, int end, RenderObject* obj, InlineBidiResolver& resolver)
402
{
132
{
403
    if (start > end || obj->isFloating() ||
133
    if (start > end || obj->isFloating() ||
404
        (obj->isPositioned() && !obj->style()->hasStaticX() && !obj->style()->hasStaticY() && !obj->container()->isRenderInline()))
134
        (obj->isPositioned() && !obj->style()->hasStaticX() && !obj->style()->hasStaticY() && !obj->container()->isRenderInline()))
Lines 441-476 static void appendRunsForObject(int star WebCore/rendering/RenderBlockLineLayout.cpp_sec5
441
    }
171
    }
442
}
172
}
443
173
444
template <>
445
void InlineBidiResolver::appendRun()
446
{
447
    if (!emptyRun && !eor.atEnd()) {
448
        int start = sor.pos;
449
        RenderObject *obj = sor.obj;
450
        while (obj && obj != eor.obj && obj != endOfLine.obj) {
451
            appendRunsForObject(start, obj->length(), obj, *this);        
452
            start = 0;
453
            obj = bidiNext(sor.block, obj);
454
        }
455
        if (obj) {
456
            unsigned pos = obj == eor.obj ? eor.pos : UINT_MAX;
457
            if (obj == endOfLine.obj && endOfLine.pos <= pos) {
458
                reachedEndOfLine = true;
459
                pos = endOfLine.pos;
460
            }
461
            // It's OK to add runs for zero-length RenderObjects, just don't make the run larger than it should be
462
            int end = obj->length() ? pos+1 : 0;
463
            appendRunsForObject(start, end, obj, *this);
464
        }
465
        
466
        eor.increment();
467
        sor = eor;
468
    }
469
470
    m_direction = OtherNeutral;
471
    m_status.eor = OtherNeutral;
472
}
473
474
static inline InlineBox* createInlineBoxForRenderer(RenderObject* obj, bool isRootLineBox, bool isOnlyRun = false)
174
static inline InlineBox* createInlineBoxForRenderer(RenderObject* obj, bool isRootLineBox, bool isOnlyRun = false)
475
{
175
{
476
    if (isRootLineBox)
176
    if (isRootLineBox)
Lines 572-583 RootInlineBox* RenderBlock::constructLin WebCore/rendering/RenderBlockLineLayout.cpp_sec6
572
        if (!box)
272
        if (!box)
573
            continue;
273
            continue;
574
274
275
        // Anonymous inline blocks (used to hold blocks inside inlines) don't need to waste time wrapping
276
        // themselves in those inlines (since we want to pretend like they don't exist on this fake line).
277
        RenderObject* ancestorRenderer = r->m_object->isAnonymousInlineBlock() ? this : r->m_object->parent();
278
 
575
        // If we have no parent box yet, or if the run is not simply a sibling,
279
        // If we have no parent box yet, or if the run is not simply a sibling,
576
        // then we need to construct inline boxes as necessary to properly enclose the
280
        // then we need to construct inline boxes as necessary to properly enclose the
577
        // run's inline box.
281
        // run's inline box.
578
        if (!parentBox || parentBox->renderer() != r->m_object->parent())
282
        if (!parentBox || parentBox->renderer() != ancestorRenderer)
579
            // Create new inline boxes all the way back to the appropriate insertion point.
283
            // Create new inline boxes all the way back to the appropriate insertion point.
580
            parentBox = createLineBoxes(r->m_object->parent(), firstLine);
284
            parentBox = createLineBoxes(ancestorRenderer, firstLine);
581
285
582
        // Append the inline box to this line.
286
        // Append the inline box to this line.
583
        parentBox->addToLine(box);
287
        parentBox->addToLine(box);
Lines 619-624 void RenderBlock::computeHorizontalPosit WebCore/rendering/RenderBlockLineLayout.cpp_sec7
619
    unsigned numSpaces = 0;
323
    unsigned numSpaces = 0;
620
    ETextAlign textAlign = style()->textAlign();
324
    ETextAlign textAlign = style()->textAlign();
621
325
326
    int x = leftOffset(height(), firstLine);
327
622
    for (BidiRun* r = firstRun; r; r = r->next()) {
328
    for (BidiRun* r = firstRun; r; r = r->next()) {
623
        if (!r->m_box || r->m_object->isPositioned() || r->m_box->isLineBreak())
329
        if (!r->m_box || r->m_object->isPositioned() || r->m_box->isLineBreak())
624
            continue; // Positioned objects are only participating to figure out their
330
            continue; // Positioned objects are only participating to figure out their
Lines 656-661 void RenderBlock::computeHorizontalPosit WebCore/rendering/RenderBlockLineLayout.cpp_sec8
656
            renderBox->calcWidth();
362
            renderBox->calcWidth();
657
            r->m_box->setWidth(renderBox->width());
363
            r->m_box->setWidth(renderBox->width());
658
            totWidth += renderBox->marginLeft() + renderBox->marginRight();
364
            totWidth += renderBox->marginLeft() + renderBox->marginRight();
365
            
366
            if (r->m_object->isAnonymousInlineBlock()) {
367
                // Allow the full available width to be used, since floats will intrude into our space.
368
                availableWidth = rightOffset() - leftOffset();
369
                x = leftOffset();
370
            }
659
        }
371
        }
660
372
661
        totWidth += r->m_box->width();
373
        totWidth += r->m_box->width();
Lines 665-671 void RenderBlock::computeHorizontalPosit WebCore/rendering/RenderBlockLineLayout.cpp_sec9
665
    // we now examine our text-align property in order to determine where to position the
377
    // we now examine our text-align property in order to determine where to position the
666
    // objects horizontally.  The total width of the line can be increased if we end up
378
    // objects horizontally.  The total width of the line can be increased if we end up
667
    // justifying text.
379
    // justifying text.
668
    int x = leftOffset(height(), firstLine);
669
    switch (textAlign) {
380
    switch (textAlign) {
670
        case LEFT:
381
        case LEFT:
671
        case WEBKIT_LEFT:
382
        case WEBKIT_LEFT:
Lines 819-827 void RenderBlock::layoutInlineChildren(b WebCore/rendering/RenderBlockLineLayout.cpp_sec10
819
    bool useRepaintBounds = false;
530
    bool useRepaintBounds = false;
820
    
531
    
821
    m_overflow.clear();
532
    m_overflow.clear();
822
        
533
    
823
    setHeight(borderTop() + paddingTop());
534
    int top = borderTop() + paddingTop();
824
    int toAdd = borderBottom() + paddingBottom() + horizontalScrollbarHeight();
535
    int bottom = borderBottom() + paddingBottom() + horizontalScrollbarHeight();
536
537
    setHeight(top);
538
539
    // The margin struct caches all our current margin collapsing state. We run margin collapsing when we encounter anonymous inline blocks that are being used
540
    // for the blocks-inside-inlines case (and the inlines are empty), e.g, <span><div>One</div></span>.
541
    MarginInfo marginInfo(this, top, bottom);
825
542
826
    // Figure out if we should clear out our line boxes.
543
    // Figure out if we should clear out our line boxes.
827
    // FIXME: Handle resize eventually!
544
    // FIXME: Handle resize eventually!
Lines 850-861 void RenderBlock::layoutInlineChildren(b WebCore/rendering/RenderBlockLineLayout.cpp_sec11
850
            if (o->isReplaced() || o->isFloating() || o->isPositioned()) {
567
            if (o->isReplaced() || o->isFloating() || o->isPositioned()) {
851
                RenderBox* box = toRenderBox(o);
568
                RenderBox* box = toRenderBox(o);
852
                
569
                
853
                if (relayoutChildren || o->style()->width().isPercent() || o->style()->height().isPercent())
570
                // Make sure we layout children if they need it.
854
                    o->setChildNeedsLayout(true, false);
571
                // FIXME: Technically percentage height objects only need a relayout if their percentage isn't going to be turned into
855
                    
572
                // an auto value.  Add a method to determine this, so that we can avoid the relayout.
573
                if (relayoutChildren || ((box->style()->height().isPercent() || box->style()->minHeight().isPercent() || box->style()->maxHeight().isPercent())))
574
                    box->setChildNeedsLayout(true, false);
575
856
                // If relayoutChildren is set and we have percentage padding, we also need to invalidate the child's pref widths.
576
                // If relayoutChildren is set and we have percentage padding, we also need to invalidate the child's pref widths.
857
                if (relayoutChildren && (o->style()->paddingLeft().isPercent() || o->style()->paddingRight().isPercent()))
577
                if (relayoutChildren && (box->style()->paddingLeft().isPercent() || box->style()->paddingRight().isPercent()))
858
                    o->setPrefWidthsDirty(true, false);
578
                    box->setPrefWidthsDirty(true, false);
859
            
579
            
860
                if (o->isPositioned())
580
                if (o->isPositioned())
861
                    o->containingBlock()->insertPositionedObject(box);
581
                    o->containingBlock()->insertPositionedObject(box);
Lines 865-871 void RenderBlock::layoutInlineChildren(b WebCore/rendering/RenderBlockLineLayout.cpp_sec12
865
                    else if (fullLayout || o->needsLayout()) // Replaced elements
585
                    else if (fullLayout || o->needsLayout()) // Replaced elements
866
                        toRenderBox(o)->dirtyLineBoxes(fullLayout);
586
                        toRenderBox(o)->dirtyLineBoxes(fullLayout);
867
587
868
                    o->layoutIfNeeded();
588
                    if (!o->isReplaced() || !o->isAnonymousInlineBlock())
589
                        o->layoutIfNeeded();
869
                }
590
                }
870
            } else if (o->isText() || (o->isRenderInline() && !endOfInline)) {
591
            } else if (o->isText() || (o->isRenderInline() && !endOfInline)) {
871
                hasInlineChild = true;
592
                hasInlineChild = true;
Lines 960-966 void RenderBlock::layoutInlineChildren(b WebCore/rendering/RenderBlockLineLayout.cpp_sec13
960
            isLineEmpty = true;
681
            isLineEmpty = true;
961
            
682
            
962
            EClear clear = CNONE;
683
            EClear clear = CNONE;
963
            end = findNextLineBreak(resolver, firstLine, isLineEmpty, previousLineBrokeCleanly, &clear);
684
            end = findNextLineBreak(resolver, firstLine, isLineEmpty, previousLineBrokeCleanly, marginInfo, &clear);
964
            if (resolver.position().atEnd()) {
685
            if (resolver.position().atEnd()) {
965
                resolver.deleteRuns();
686
                resolver.deleteRuns();
966
                checkForFloatsFromLastLine = true;
687
                checkForFloatsFromLastLine = true;
Lines 1030-1035 void RenderBlock::layoutInlineChildren(b WebCore/rendering/RenderBlockLineLayout.cpp_sec14
1030
                    if (lineBox) {
751
                    if (lineBox) {
1031
                        lineBox->setEndsWithBreak(previousLineBrokeCleanly);
752
                        lineBox->setEndsWithBreak(previousLineBrokeCleanly);
1032
753
754
                        // If our previous line was an anonymous block and we are not an anonymous block, simulate a margin collapse now so that we get the proper
755
                        // increased height.  We also have to simulate a margin collapse to propagate margins through to the top of our block.
756
                        if (!lineBox->anonymousInlineBlock()) {
757
                            if (!lineBox->prevRootBox() || lineBox->prevRootBox()->anonymousInlineBlock())
758
                                collapseMargins(0, marginInfo);
759
                            marginInfo.setAtTopOfBlock(false);
760
                        }
761
1033
                        // Now we position all of our text runs horizontally.
762
                        // Now we position all of our text runs horizontally.
1034
                        computeHorizontalPositionsForLine(lineBox, firstLine, resolver.firstRun(), trailingSpaceRun, end.atEnd());
763
                        computeHorizontalPositionsForLine(lineBox, firstLine, resolver.firstRun(), trailingSpaceRun, end.atEnd());
1035
764
Lines 1161-1168 void RenderBlock::layoutInlineChildren(b WebCore/rendering/RenderBlockLineLayout.cpp_sec15
1161
        }
890
        }
1162
    }
891
    }
1163
892
1164
    // Now add in the bottom border/padding.
893
    // Now do the handling of the bottom of the block, adding in our bottom border/padding and
1165
    setHeight(height() + toAdd);
894
    // determining the correct collapsed bottom margin information.  This collapse is only necessary
895
    // if our last child was an anonymous inline block that might need to propagate margin information out to
896
    // us.
897
    if (lastRootBox() && lastRootBox()->anonymousInlineBlock())
898
        handleBottomOfBlock(top, bottom, marginInfo);
899
    else
900
        setHeight(height() + bottom);
1166
901
1167
    if (!firstLineBox() && hasLineIfEmpty())
902
    if (!firstLineBox() && hasLineIfEmpty())
1168
        setHeight(height() + lineHeight(true, true));
903
        setHeight(height() + lineHeight(true, true));
Lines 1183-1188 RootInlineBox* RenderBlock::determineSta WebCore/rendering/RenderBlockLineLayout.cpp_sec16
1183
    if (!fullLayout) {
918
    if (!fullLayout) {
1184
        size_t floatIndex = 0;
919
        size_t floatIndex = 0;
1185
        for (curr = firstRootBox(); curr && !curr->isDirty(); curr = curr->nextRootBox()) {
920
        for (curr = firstRootBox(); curr && !curr->isDirty(); curr = curr->nextRootBox()) {
921
            if (curr->anonymousInlineBlock()) {
922
                // FIXME: We have to do better than this or we will repaint too much as content inside an
923
                // anonymous inline block comes in.
924
                fullLayout = true;
925
                break;
926
            }
1186
            if (Vector<RenderBox*>* cleanLineFloats = curr->floatsPtr()) {
927
            if (Vector<RenderBox*>* cleanLineFloats = curr->floatsPtr()) {
1187
                Vector<RenderBox*>::iterator end = cleanLineFloats->end();
928
                Vector<RenderBox*>::iterator end = cleanLineFloats->end();
1188
                for (Vector<RenderBox*>::iterator o = cleanLineFloats->begin(); o != end; ++o) {
929
                for (Vector<RenderBox*>::iterator o = cleanLineFloats->begin(); o != end; ++o) {
Lines 1444-1450 static bool inlineFlowRequiresLineBox(Re WebCore/rendering/RenderBlockLineLayout.cpp_sec17
1444
    return !flow->firstChild() && flow->hasHorizontalBordersPaddingOrMargin();
1185
    return !flow->firstChild() && flow->hasHorizontalBordersPaddingOrMargin();
1445
}
1186
}
1446
1187
1447
static inline bool requiresLineBox(const InlineIterator& it, bool isLineEmpty, bool previousLineBrokeCleanly)
1188
bool RenderBlock::requiresLineBox(const InlineIterator& it, bool isLineEmpty, bool previousLineBrokeCleanly)
1448
{
1189
{
1449
    if (it.obj->isFloatingOrPositioned())
1190
    if (it.obj->isFloatingOrPositioned())
1450
        return false;
1191
        return false;
Lines 1597-1603 static inline unsigned textWidth(RenderT WebCore/rendering/RenderBlockLineLayout.cpp_sec18
1597
}
1338
}
1598
1339
1599
InlineIterator RenderBlock::findNextLineBreak(InlineBidiResolver& resolver, bool firstLine,  bool& isLineEmpty, bool& previousLineBrokeCleanly, 
1340
InlineIterator RenderBlock::findNextLineBreak(InlineBidiResolver& resolver, bool firstLine,  bool& isLineEmpty, bool& previousLineBrokeCleanly, 
1600
                                              EClear* clear)
1341
                                              MarginInfo& marginInfo, EClear* clear)
1601
{
1342
{
1602
    ASSERT(resolver.position().block == this);
1343
    ASSERT(resolver.position().block == this);
1603
1344
Lines 1638-1643 InlineIterator RenderBlock::findNextLine WebCore/rendering/RenderBlockLineLayout.cpp_sec19
1638
    bool autoWrapWasEverTrueOnLine = false;
1379
    bool autoWrapWasEverTrueOnLine = false;
1639
    bool floatsFitOnLine = true;
1380
    bool floatsFitOnLine = true;
1640
    
1381
    
1382
    bool isBlockInsideInline = false;
1383
    
1384
    int previousBlockFloatBottom = 0;
1385
    int maxBlockFloatBottom = 0;
1386
1641
    // Firefox and Opera will allow a table cell to grow to fit an image inside it under
1387
    // Firefox and Opera will allow a table cell to grow to fit an image inside it under
1642
    // very specific circumstances (in order to match common WinIE renderings). 
1388
    // very specific circumstances (in order to match common WinIE renderings). 
1643
    // Not supporting the quirk has caused us to mis-render some real sites. (See Bugzilla 10517.) 
1389
    // Not supporting the quirk has caused us to mis-render some real sites. (See Bugzilla 10517.) 
Lines 1648-1654 InlineIterator RenderBlock::findNextLine WebCore/rendering/RenderBlockLineLayout.cpp_sec20
1648
    while (o) {
1394
    while (o) {
1649
        currWS = o->isReplaced() ? o->parent()->style()->whiteSpace() : o->style()->whiteSpace();
1395
        currWS = o->isReplaced() ? o->parent()->style()->whiteSpace() : o->style()->whiteSpace();
1650
        lastWS = last->isReplaced() ? last->parent()->style()->whiteSpace() : last->style()->whiteSpace();
1396
        lastWS = last->isReplaced() ? last->parent()->style()->whiteSpace() : last->style()->whiteSpace();
1651
        
1397
        isBlockInsideInline = o->isAnonymousInlineBlock();
1398
1652
        bool autoWrap = RenderStyle::autoWrap(currWS);
1399
        bool autoWrap = RenderStyle::autoWrap(currWS);
1653
        autoWrapWasEverTrueOnLine = autoWrapWasEverTrueOnLine || autoWrap;
1400
        autoWrapWasEverTrueOnLine = autoWrapWasEverTrueOnLine || autoWrap;
1654
1401
Lines 1659-1665 InlineIterator RenderBlock::findNextLine WebCore/rendering/RenderBlockLineLayout.cpp_sec21
1659
#endif
1406
#endif
1660
1407
1661
        bool collapseWhiteSpace = RenderStyle::collapseWhiteSpace(currWS);
1408
        bool collapseWhiteSpace = RenderStyle::collapseWhiteSpace(currWS);
1662
            
1409
1663
        if (o->isBR()) {
1410
        if (o->isBR()) {
1664
            if (w + tmpW <= width) {
1411
            if (w + tmpW <= width) {
1665
                lBreak.obj = o;
1412
                lBreak.obj = o;
Lines 1766-1773 InlineIterator RenderBlock::findNextLine WebCore/rendering/RenderBlockLineLayout.cpp_sec22
1766
        } else if (o->isReplaced()) {
1513
        } else if (o->isReplaced()) {
1767
            RenderBox* replacedBox = toRenderBox(o);
1514
            RenderBox* replacedBox = toRenderBox(o);
1768
1515
1769
            // Break on replaced elements if either has normal white-space.
1516
            // Break on replaced elements if either has normal white-space.  We also always break if we
1770
            if ((autoWrap || RenderStyle::autoWrap(lastWS)) && (!o->isImage() || allowImagesToBreak)) {
1517
            // encounter a special anonymous inline block (used to hold blocks inside inlines).
1518
            if ((autoWrap || RenderStyle::autoWrap(lastWS) || isBlockInsideInline)  && (!o->isImage() || allowImagesToBreak)) {
1771
                w += tmpW;
1519
                w += tmpW;
1772
                tmpW = 0;
1520
                tmpW = 0;
1773
                lBreak.obj = o;
1521
                lBreak.obj = o;
Lines 1775-1780 InlineIterator RenderBlock::findNextLine WebCore/rendering/RenderBlockLineLayout.cpp_sec23
1775
                lBreak.nextBreakablePosition = -1;
1523
                lBreak.nextBreakablePosition = -1;
1776
            }
1524
            }
1777
1525
1526
            if (isBlockInsideInline) {
1527
                if (!isLineEmpty)
1528
                    goto end;
1529
1530
                // Reset the width to ignore floats, since we're going to allow them to intrude into our space.
1531
                width = rightOffset() - leftOffset();
1532
1533
                // FIXME: This call will update the height of our block.  It's not clear if that's going to be ok or not yet.
1534
                layoutBlockChild(replacedBox, marginInfo, previousBlockFloatBottom, maxBlockFloatBottom);
1535
1536
                lineMidpointState.betweenMidpoints = false;
1537
            }
1538
1778
            if (ignoringSpaces)
1539
            if (ignoringSpaces)
1779
                addMidpoint(lineMidpointState, InlineIterator(0, o, 0));
1540
                addMidpoint(lineMidpointState, InlineIterator(0, o, 0));
1780
1541
Lines 1798-1803 InlineIterator RenderBlock::findNextLine WebCore/rendering/RenderBlockLineLayout.cpp_sec24
1798
                    tmpW += replacedBox->width() + replacedBox->marginLeft() + replacedBox->marginRight() + inlineWidth(o);
1559
                    tmpW += replacedBox->width() + replacedBox->marginLeft() + replacedBox->marginRight() + inlineWidth(o);
1799
            } else
1560
            } else
1800
                tmpW += replacedBox->width() + replacedBox->marginLeft() + replacedBox->marginRight() + inlineWidth(o);
1561
                tmpW += replacedBox->width() + replacedBox->marginLeft() + replacedBox->marginRight() + inlineWidth(o);
1562
                
1563
            if (isBlockInsideInline) {
1564
                w += tmpW;
1565
                tmpW = 0;
1566
                lBreak.obj = o;
1567
                lBreak.pos = 0;
1568
                lBreak.nextBreakablePosition = -1;
1569
                goto end;
1570
            }
1801
        } else if (o->isText()) {
1571
        } else if (o->isText()) {
1802
            if (!pos)
1572
            if (!pos)
1803
                appliedStartWidth = false;
1573
                appliedStartWidth = false;
Lines 2191-2197 InlineIterator RenderBlock::findNextLine WebCore/rendering/RenderBlockLineLayout.cpp_sec25
2191
        }
1961
        }
2192
        //else if (lBreak.pos > 0)
1962
        //else if (lBreak.pos > 0)
2193
        //    lBreak.pos--;
1963
        //    lBreak.pos--;
2194
        else if (lBreak.obj == 0 && trailingSpaceObject->isText()) {
1964
        else if ((!lBreak.obj || lBreak.obj->isAnonymousInlineBlock()) && trailingSpaceObject->isText()) {
2195
            // Add a new end midpoint that stops right at the very end.
1965
            // Add a new end midpoint that stops right at the very end.
2196
            RenderText* text = toRenderText(trailingSpaceObject);
1966
            RenderText* text = toRenderText(trailingSpaceObject);
2197
            unsigned length = text->textLength();
1967
            unsigned length = text->textLength();
- WebCore/rendering/RenderBox.cpp -3 / +3 lines
Lines 1334-1340 void RenderBox::calcWidth() WebCore/rendering/RenderBox.cpp_sec1
1334
    }
1334
    }
1335
1335
1336
    if (containerWidth && containerWidth != (width() + m_marginLeft + m_marginRight)
1336
    if (containerWidth && containerWidth != (width() + m_marginLeft + m_marginRight)
1337
            && !isFloating() && !isInline() && !cb->isFlexibleBox()) {
1337
            && !isFloating() && (!isInline() || isAnonymousInlineBlock()) && !cb->isFlexibleBox()) {
1338
        if (cb->style()->direction() == LTR)
1338
        if (cb->style()->direction() == LTR)
1339
            m_marginRight = containerWidth - width() - m_marginLeft;
1339
            m_marginRight = containerWidth - width() - m_marginLeft;
1340
        else
1340
        else
Lines 1373-1379 bool RenderBox::sizesToIntrinsicWidth(Wi WebCore/rendering/RenderBox.cpp_sec2
1373
{
1373
{
1374
    // Marquees in WinIE are like a mixture of blocks and inline-blocks.  They size as though they're blocks,
1374
    // Marquees in WinIE are like a mixture of blocks and inline-blocks.  They size as though they're blocks,
1375
    // but they allow text to sit on the same line as the marquee.
1375
    // but they allow text to sit on the same line as the marquee.
1376
    if (isFloating() || (isInlineBlockOrInlineTable() && !isHTMLMarquee()))
1376
    if (isFloating() || (isInlineBlockOrInlineTable() && !isHTMLMarquee() && !isAnonymousInlineBlock()))
1377
        return true;
1377
        return true;
1378
1378
1379
    // This code may look a bit strange.  Basically width:intrinsic should clamp the size when testing both
1379
    // This code may look a bit strange.  Basically width:intrinsic should clamp the size when testing both
Lines 2819-2825 bool RenderBox::shrinkToAvoidFloats() co WebCore/rendering/RenderBox.cpp_sec3
2819
2819
2820
bool RenderBox::avoidsFloats() const
2820
bool RenderBox::avoidsFloats() const
2821
{
2821
{
2822
    return isReplaced() || hasOverflowClip() || isHR();
2822
    return !isAnonymousInlineBlock() && (isReplaced() || hasOverflowClip() || isHR());
2823
}
2823
}
2824
2824
2825
void RenderBox::addShadowOverflow()
2825
void RenderBox::addShadowOverflow()
- WebCore/rendering/RenderInline.cpp -358 / +57 lines
Lines 44-50 namespace WebCore { WebCore/rendering/RenderInline.cpp_sec1
44
44
45
RenderInline::RenderInline(Node* node)
45
RenderInline::RenderInline(Node* node)
46
    : RenderBoxModelObject(node)
46
    : RenderBoxModelObject(node)
47
    , m_continuation(0)
48
    , m_lineHeight(-1)
47
    , m_lineHeight(-1)
49
    , m_verticalPosition(PositionUndefined)
48
    , m_verticalPosition(PositionUndefined)
50
{
49
{
Lines 56-69 void RenderInline::destroy() WebCore/rendering/RenderInline.cpp_sec2
56
    // Make sure to destroy anonymous children first while they are still connected to the rest of the tree, so that they will
55
    // Make sure to destroy anonymous children first while they are still connected to the rest of the tree, so that they will
57
    // properly dirty line boxes that they are removed from.  Effects that do :before/:after only on hover could crash otherwise.
56
    // properly dirty line boxes that they are removed from.  Effects that do :before/:after only on hover could crash otherwise.
58
    children()->destroyLeftoverChildren();
57
    children()->destroyLeftoverChildren();
59
60
    // Destroy our continuation before anything other than anonymous children.
61
    // The reason we don't destroy it before anonymous children is that they may
62
    // have continuations of their own that are anonymous children of our continuation.
63
    if (m_continuation) {
64
        m_continuation->destroy();
65
        m_continuation = 0;
66
    }
67
    
58
    
68
    if (!documentBeingDestroyed()) {
59
    if (!documentBeingDestroyed()) {
69
        if (firstLineBox()) {
60
        if (firstLineBox()) {
Lines 92-104 void RenderInline::destroy() WebCore/rendering/RenderInline.cpp_sec3
92
    RenderBoxModelObject::destroy();
83
    RenderBoxModelObject::destroy();
93
}
84
}
94
85
95
RenderInline* RenderInline::inlineContinuation() const
96
{
97
    if (!m_continuation || m_continuation->isInline())
98
        return toRenderInline(m_continuation);
99
    return toRenderBlock(m_continuation)->inlineContinuation();
100
}
101
102
void RenderInline::updateBoxModelInfoFromStyle()
86
void RenderInline::updateBoxModelInfoFromStyle()
103
{
87
{
104
    RenderBoxModelObject::updateBoxModelInfoFromStyle();
88
    RenderBoxModelObject::updateBoxModelInfoFromStyle();
Lines 114-132 void RenderInline::styleDidChange(StyleD WebCore/rendering/RenderInline.cpp_sec4
114
{
98
{
115
    RenderBoxModelObject::styleDidChange(diff, oldStyle);
99
    RenderBoxModelObject::styleDidChange(diff, oldStyle);
116
100
117
    // Ensure that all of the split inlines pick up the new style. We
118
    // only do this if we're an inline, since we don't want to propagate
119
    // a block's style to the other inlines.
120
    // e.g., <font>foo <h4>goo</h4> moo</font>.  The <font> inlines before
121
    // and after the block share the same style, but the block doesn't
122
    // need to pass its style on to anyone else.
123
    for (RenderInline* currCont = inlineContinuation(); currCont; currCont = currCont->inlineContinuation()) {
124
        RenderBoxModelObject* nextCont = currCont->continuation();
125
        currCont->setContinuation(0);
126
        currCont->setStyle(style());
127
        currCont->setContinuation(nextCont);
128
    }
129
130
    m_lineHeight = -1;
101
    m_lineHeight = -1;
131
102
132
    // Update pseudos for :before and :after now.
103
    // Update pseudos for :before and :after now.
Lines 136-214 void RenderInline::styleDidChange(StyleD WebCore/rendering/RenderInline.cpp_sec5
136
    }
107
    }
137
}
108
}
138
109
139
void RenderInline::addChild(RenderObject* newChild, RenderObject* beforeChild)
110
void RenderInline::childBecameNonInline(RenderObject* child)
140
{
141
    if (continuation())
142
        return addChildToContinuation(newChild, beforeChild);
143
    return addChildIgnoringContinuation(newChild, beforeChild);
144
}
145
146
static RenderBoxModelObject* nextContinuation(RenderObject* renderer)
147
{
111
{
148
    if (renderer->isInline() && !renderer->isReplaced())
112
    RenderObject* next = child->nextSibling();
149
        return toRenderInline(renderer)->continuation();
113
    removeChild(child);
150
    return toRenderBlock(renderer)->inlineContinuation();
114
    addChild(child, next);
151
}
115
}
152
116
153
RenderBoxModelObject* RenderInline::continuationBefore(RenderObject* beforeChild)
117
void RenderInline::addChild(RenderObject* newChild, RenderObject* beforeChild)
154
{
155
    if (beforeChild && beforeChild->parent() == this)
156
        return this;
157
158
    RenderBoxModelObject* curr = nextContinuation(this);
159
    RenderBoxModelObject* nextToLast = this;
160
    RenderBoxModelObject* last = this;
161
    while (curr) {
162
        if (beforeChild && beforeChild->parent() == curr) {
163
            if (curr->firstChild() == beforeChild)
164
                return last;
165
            return curr;
166
        }
167
168
        nextToLast = last;
169
        last = curr;
170
        curr = nextContinuation(curr);
171
    }
172
173
    if (!beforeChild && !last->firstChild())
174
        return nextToLast;
175
    return last;
176
}
177
178
void RenderInline::addChildIgnoringContinuation(RenderObject* newChild, RenderObject* beforeChild)
179
{
118
{
180
    // Make sure we don't append things after :after-generated content if we have it.
119
    // Make sure we don't append things after :after-generated content if we have it.
181
    if (!beforeChild && isAfterContent(lastChild()))
120
    if (!beforeChild && isAfterContent(lastChild()))
182
        beforeChild = lastChild();
121
        beforeChild = lastChild();
183
122
184
    if (!newChild->isInline() && !newChild->isFloatingOrPositioned()) {
123
    // If the requested beforeChild is not one of our children, then this is most likely because
185
        // We are placing a block inside an inline. We have to perform a split of this
124
    // there is an anonymous inline-block box within this object that contains the beforeChild. So
186
        // inline into continuations.  This involves creating an anonymous block box to hold
125
    // just insert the child into the anonymous inline-block box instead of here.
187
        // |newChild|.  We then make that block box a continuation of this inline.  We take all of
126
    // A second possibility is that the beforeChild is an anonymous block inside the anonymous inline block.
188
        // the children after |beforeChild| and put them in a clone of this object.
127
    // This can happen if inlines are inserted in between two of the anonymous inline block's block-level
189
        RefPtr<RenderStyle> newStyle = RenderStyle::create();
128
    // children after it has been created.
190
        newStyle->inheritFrom(style());
129
    if (beforeChild && beforeChild->parent() != this) {
191
        newStyle->setDisplay(BLOCK);
130
        ASSERT(beforeChild->parent());
192
131
        ASSERT(beforeChild->parent()->isAnonymousInlineBlock() || beforeChild->parent()->isAnonymousBlock());
193
        RenderBlock* newBox = new (renderArena()) RenderBlock(document() /* anonymous box */);
132
        if (beforeChild->parent()->isAnonymousInlineBlock()) {
194
        newBox->setStyle(newStyle.release());
133
            if (!newChild->isInline() || (newChild->isInline() && beforeChild->parent()->firstChild() != beforeChild))
195
        RenderBoxModelObject* oldContinuation = continuation();
134
                beforeChild->parent()->addChild(newChild, beforeChild);
196
        setContinuation(newBox);
135
            else
197
136
                addChild(newChild, beforeChild->parent());
198
        // Someone may have put a <p> inside a <q>, causing a split.  When this happens, the :after content
137
        } else if (beforeChild->parent()->isAnonymousBlock()) {
199
        // has to move into the inline continuation.  Call updateBeforeAfterContent to ensure that our :after
138
            ASSERT(!beforeChild->parent()->parent() || beforeChild->parent()->parent()->isAnonymousInlineBlock());
200
        // content gets properly destroyed.
139
            ASSERT(beforeChild->isInline());
201
        bool isLastChild = (beforeChild == lastChild());
140
            if (newChild->isInline() || (!newChild->isInline() && beforeChild->parent()->firstChild() != beforeChild))
202
        if (document()->usesBeforeAfterRules())
141
                beforeChild->parent()->addChild(newChild, beforeChild);
203
            children()->updateBeforeAfterContent(this, AFTER);
142
            else
204
        if (isLastChild && beforeChild != lastChild())
143
                addChild(newChild, beforeChild->parent());
205
            beforeChild = 0; // We destroyed the last child, so now we need to update our insertion
144
        }
206
                             // point to be 0.  It's just a straight append now.
207
208
        splitFlow(beforeChild, newBox, newChild, oldContinuation);
209
        return;
145
        return;
210
    }
146
    }
211
147
148
    if (!newChild->isInline()) {
149
        // We are placing a block inside an inline. We have to place the block inside an anonymous inline-block.
150
        // This inline-block can house a sequence of contiguous block-level children, and they will all sit on the
151
        // same line together.  We try to reuse one first if possible.
152
        if (beforeChild) {
153
            if (beforeChild->previousSibling() && beforeChild->previousSibling()->isAnonymousInlineBlock()) {
154
                beforeChild->previousSibling()->addChild(newChild);
155
                return;
156
            }
157
        } else {
158
            if (lastChild() && lastChild()->isAnonymousInlineBlock()) {
159
                lastChild()->addChild(newChild);
160
                return;
161
            }
162
        }
163
 
164
        if (!newChild->isFloatingOrPositioned()) {
165
            // There was no suitable existing anonymous box.  Create a new one.
166
            RefPtr<RenderStyle> newStyle = RenderStyle::create();
167
            newStyle->inheritFrom(style());
168
            newStyle->setDisplay(INLINE_BLOCK);
169
            RenderBlock* newBox = new (renderArena()) RenderBlock(document());
170
            newBox->setStyle(newStyle);
171
            RenderBoxModelObject::addChild(newBox, beforeChild);
172
            newBox->addChild(newChild);
173
            return;
174
        }
175
    }
176
212
    RenderBoxModelObject::addChild(newChild, beforeChild);
177
    RenderBoxModelObject::addChild(newChild, beforeChild);
213
178
214
    newChild->setNeedsLayoutAndPrefWidthsRecalc();
179
    newChild->setNeedsLayoutAndPrefWidthsRecalc();
Lines 221-408 RenderInline* RenderInline::cloneInline( WebCore/rendering/RenderInline.cpp_sec6
221
    return o;
186
    return o;
222
}
187
}
223
188
224
void RenderInline::splitInlines(RenderBlock* fromBlock, RenderBlock* toBlock,
225
                                RenderBlock* middleBlock,
226
                                RenderObject* beforeChild, RenderBoxModelObject* oldCont)
227
{
228
    // Create a clone of this inline.
229
    RenderInline* clone = cloneInline(this);
230
    clone->setContinuation(oldCont);
231
232
    // Now take all of the children from beforeChild to the end and remove
233
    // them from |this| and place them in the clone.
234
    RenderObject* o = beforeChild;
235
    while (o) {
236
        RenderObject* tmp = o;
237
        o = tmp->nextSibling();
238
        clone->addChildIgnoringContinuation(children()->removeChildNode(this, tmp), 0);
239
        tmp->setNeedsLayoutAndPrefWidthsRecalc();
240
    }
241
242
    // Hook |clone| up as the continuation of the middle block.
243
    middleBlock->setInlineContinuation(clone);
244
245
    // We have been reparented and are now under the fromBlock.  We need
246
    // to walk up our inline parent chain until we hit the containing block.
247
    // Once we hit the containing block we're done.
248
    RenderBoxModelObject* curr = toRenderBoxModelObject(parent());
249
    RenderBoxModelObject* currChild = this;
250
    
251
    // FIXME: Because splitting is O(n^2) as tags nest pathologically, we cap the depth at which we're willing to clone.
252
    // There will eventually be a better approach to this problem that will let us nest to a much
253
    // greater depth (see bugzilla bug 13430) but for now we have a limit.  This *will* result in
254
    // incorrect rendering, but the alternative is to hang forever.
255
    unsigned splitDepth = 1;
256
    const unsigned cMaxSplitDepth = 200; 
257
    while (curr && curr != fromBlock) {
258
        ASSERT(curr->isRenderInline());
259
        if (splitDepth < cMaxSplitDepth) {
260
            // Create a new clone.
261
            RenderInline* cloneChild = clone;
262
            clone = cloneInline(toRenderInline(curr));
263
264
            // Insert our child clone as the first child.
265
            clone->addChildIgnoringContinuation(cloneChild, 0);
266
267
            // Hook the clone up as a continuation of |curr|.
268
            RenderInline* inlineCurr = toRenderInline(curr);
269
            oldCont = inlineCurr->continuation();
270
            inlineCurr->setContinuation(clone);
271
            clone->setContinuation(oldCont);
272
273
            // Someone may have indirectly caused a <q> to split.  When this happens, the :after content
274
            // has to move into the inline continuation.  Call updateBeforeAfterContent to ensure that the inline's :after
275
            // content gets properly destroyed.
276
            if (document()->usesBeforeAfterRules())
277
                inlineCurr->children()->updateBeforeAfterContent(this, AFTER);
278
279
            // Now we need to take all of the children starting from the first child
280
            // *after* currChild and append them all to the clone.
281
            o = currChild->nextSibling();
282
            while (o) {
283
                RenderObject* tmp = o;
284
                o = tmp->nextSibling();
285
                clone->addChildIgnoringContinuation(inlineCurr->children()->removeChildNode(curr, tmp), 0);
286
                tmp->setNeedsLayoutAndPrefWidthsRecalc();
287
            }
288
        }
289
        
290
        // Keep walking up the chain.
291
        currChild = curr;
292
        curr = toRenderBoxModelObject(curr->parent());
293
        splitDepth++;
294
    }
295
296
    // Now we are at the block level. We need to put the clone into the toBlock.
297
    toBlock->children()->appendChildNode(toBlock, clone);
298
299
    // Now take all the children after currChild and remove them from the fromBlock
300
    // and put them in the toBlock.
301
    o = currChild->nextSibling();
302
    while (o) {
303
        RenderObject* tmp = o;
304
        o = tmp->nextSibling();
305
        toBlock->children()->appendChildNode(toBlock, fromBlock->children()->removeChildNode(fromBlock, tmp));
306
    }
307
}
308
309
void RenderInline::splitFlow(RenderObject* beforeChild, RenderBlock* newBlockBox,
310
                             RenderObject* newChild, RenderBoxModelObject* oldCont)
311
{
312
    RenderBlock* pre = 0;
313
    RenderBlock* block = containingBlock();
314
    
315
    // Delete our line boxes before we do the inline split into continuations.
316
    block->deleteLineBoxTree();
317
    
318
    bool madeNewBeforeBlock = false;
319
    if (block->isAnonymousBlock() && (!block->parent() || !block->parent()->createsAnonymousWrapper())) {
320
        // We can reuse this block and make it the preBlock of the next continuation.
321
        pre = block;
322
        pre->removePositionedObjects(0);
323
        block = block->containingBlock();
324
    } else {
325
        // No anonymous block available for use.  Make one.
326
        pre = block->createAnonymousBlock();
327
        madeNewBeforeBlock = true;
328
    }
329
330
    RenderBlock* post = block->createAnonymousBlock();
331
332
    RenderObject* boxFirst = madeNewBeforeBlock ? block->firstChild() : pre->nextSibling();
333
    if (madeNewBeforeBlock)
334
        block->children()->insertChildNode(block, pre, boxFirst);
335
    block->children()->insertChildNode(block, newBlockBox, boxFirst);
336
    block->children()->insertChildNode(block, post, boxFirst);
337
    block->setChildrenInline(false);
338
    
339
    if (madeNewBeforeBlock) {
340
        RenderObject* o = boxFirst;
341
        while (o) {
342
            RenderObject* no = o;
343
            o = no->nextSibling();
344
            pre->children()->appendChildNode(pre, block->children()->removeChildNode(block, no));
345
            no->setNeedsLayoutAndPrefWidthsRecalc();
346
        }
347
    }
348
349
    splitInlines(pre, post, newBlockBox, beforeChild, oldCont);
350
351
    // We already know the newBlockBox isn't going to contain inline kids, so avoid wasting
352
    // time in makeChildrenNonInline by just setting this explicitly up front.
353
    newBlockBox->setChildrenInline(false);
354
355
    // We delayed adding the newChild until now so that the |newBlockBox| would be fully
356
    // connected, thus allowing newChild access to a renderArena should it need
357
    // to wrap itself in additional boxes (e.g., table construction).
358
    newBlockBox->addChild(newChild);
359
360
    // Always just do a full layout in order to ensure that line boxes (especially wrappers for images)
361
    // get deleted properly.  Because objects moves from the pre block into the post block, we want to
362
    // make new line boxes instead of leaving the old line boxes around.
363
    pre->setNeedsLayoutAndPrefWidthsRecalc();
364
    block->setNeedsLayoutAndPrefWidthsRecalc();
365
    post->setNeedsLayoutAndPrefWidthsRecalc();
366
}
367
368
void RenderInline::addChildToContinuation(RenderObject* newChild, RenderObject* beforeChild)
369
{
370
    RenderBoxModelObject* flow = continuationBefore(beforeChild);
371
    ASSERT(!beforeChild || beforeChild->parent()->isRenderBlock() || beforeChild->parent()->isRenderInline());
372
    RenderBoxModelObject* beforeChildParent = 0;
373
    if (beforeChild)
374
        beforeChildParent = toRenderBoxModelObject(beforeChild->parent());
375
    else {
376
        RenderBoxModelObject* cont = nextContinuation(flow);
377
        if (cont)
378
            beforeChildParent = cont;
379
        else
380
            beforeChildParent = flow;
381
    }
382
383
    if (newChild->isFloatingOrPositioned())
384
        return beforeChildParent->addChildIgnoringContinuation(newChild, beforeChild);
385
386
    // A continuation always consists of two potential candidates: an inline or an anonymous
387
    // block box holding block children.
388
    bool childInline = newChild->isInline();
389
    bool bcpInline = beforeChildParent->isInline();
390
    bool flowInline = flow->isInline();
391
392
    if (flow == beforeChildParent)
393
        return flow->addChildIgnoringContinuation(newChild, beforeChild);
394
    else {
395
        // The goal here is to match up if we can, so that we can coalesce and create the
396
        // minimal # of continuations needed for the inline.
397
        if (childInline == bcpInline)
398
            return beforeChildParent->addChildIgnoringContinuation(newChild, beforeChild);
399
        else if (flowInline == childInline)
400
            return flow->addChildIgnoringContinuation(newChild, 0); // Just treat like an append.
401
        else
402
            return beforeChildParent->addChildIgnoringContinuation(newChild, beforeChild);
403
    }
404
}
405
406
void RenderInline::paint(PaintInfo& paintInfo, int tx, int ty)
189
void RenderInline::paint(PaintInfo& paintInfo, int tx, int ty)
407
{
190
{
408
    m_lineBoxes.paint(this, paintInfo, tx, ty);
191
    m_lineBoxes.paint(this, paintInfo, tx, ty);
Lines 415-430 void RenderInline::absoluteRects(Vector< WebCore/rendering/RenderInline.cpp_sec7
415
            rects.append(IntRect(tx + curr->x(), ty + curr->y(), curr->width(), curr->height()));
198
            rects.append(IntRect(tx + curr->x(), ty + curr->y(), curr->width(), curr->height()));
416
    } else
199
    } else
417
        rects.append(IntRect(tx, ty, 0, 0));
200
        rects.append(IntRect(tx, ty, 0, 0));
418
419
    if (continuation()) {
420
        if (continuation()->isBox()) {
421
            RenderBox* box = toRenderBox(continuation());
422
            continuation()->absoluteRects(rects, 
423
                                          tx - containingBlock()->x() + box->x(),
424
                                          ty - containingBlock()->y() + box->y());
425
        } else
426
            continuation()->absoluteRects(rects, tx - containingBlock()->x(), ty - containingBlock()->y());
427
    }
428
}
201
}
429
202
430
void RenderInline::absoluteQuads(Vector<FloatQuad>& quads)
203
void RenderInline::absoluteQuads(Vector<FloatQuad>& quads)
Lines 436-444 void RenderInline::absoluteQuads(Vector< WebCore/rendering/RenderInline.cpp_sec8
436
        }
209
        }
437
    } else
210
    } else
438
        quads.append(localToAbsoluteQuad(FloatRect()));
211
        quads.append(localToAbsoluteQuad(FloatRect()));
439
440
    if (continuation())
441
        continuation()->absoluteQuads(quads);
442
}
212
}
443
213
444
int RenderInline::offsetLeft() const
214
int RenderInline::offsetLeft() const
Lines 507-524 VisiblePosition RenderInline::positionFo WebCore/rendering/RenderInline.cpp_sec9
507
        // should try to find a result by asking our containing block.
277
        // should try to find a result by asking our containing block.
508
        return cb->positionForPoint(point);
278
        return cb->positionForPoint(point);
509
    }
279
    }
510
511
    // Translate the coords from the pre-anonymous block to the post-anonymous block.
512
    int parentBlockX = cb->x() + point.x();
513
    int parentBlockY = cb->y() + point.y();
514
    RenderBoxModelObject* c = continuation();
515
    while (c) {
516
        RenderBox* contBlock = c->isInline() ? c->containingBlock() : toRenderBlock(c);
517
        if (c->isInline() || c->firstChild())
518
            return c->positionForCoordinates(parentBlockX - contBlock->x(), parentBlockY - contBlock->y());
519
        c = toRenderBlock(c)->inlineContinuation();
520
    }
521
    
522
    return RenderBoxModelObject::positionForPoint(point);
280
    return RenderBoxModelObject::positionForPoint(point);
523
}
281
}
524
282
Lines 571-577 IntRect RenderInline::clippedOverflowRec WebCore/rendering/RenderInline.cpp_sec10
571
    // Only run-ins are allowed in here during layout.
329
    // Only run-ins are allowed in here during layout.
572
    ASSERT(!view() || !view()->layoutStateEnabled() || isRunIn());
330
    ASSERT(!view() || !view()->layoutStateEnabled() || isRunIn());
573
331
574
    if (!firstLineBox() && !continuation())
332
    if (!firstLineBox())
575
        return IntRect();
333
        return IntRect();
576
334
577
    // Find our leftmost position.
335
    // Find our leftmost position.
Lines 619-629 IntRect RenderInline::clippedOverflowRec WebCore/rendering/RenderInline.cpp_sec11
619
                r.unite(childRect);
377
                r.unite(childRect);
620
            }
378
            }
621
        }
379
        }
622
623
        if (continuation() && !continuation()->isInline()) {
624
            IntRect contRect = continuation()->rectWithOutlineForRepaint(repaintContainer, ow);
625
            r.unite(contRect);
626
        }
627
    }
380
    }
628
381
629
    return r;
382
    return r;
Lines 796-844 void RenderInline::mapAbsoluteToLocalPoi WebCore/rendering/RenderInline.cpp_sec12
796
        transformState.move(-containerOffset.width(), -containerOffset.height(), preserve3D ? TransformState::AccumulateTransform : TransformState::FlattenTransform);
549
        transformState.move(-containerOffset.width(), -containerOffset.height(), preserve3D ? TransformState::AccumulateTransform : TransformState::FlattenTransform);
797
}
550
}
798
551
799
void RenderInline::updateDragState(bool dragOn)
800
{
801
    RenderBoxModelObject::updateDragState(dragOn);
802
    if (continuation())
803
        continuation()->updateDragState(dragOn);
804
}
805
806
void RenderInline::childBecameNonInline(RenderObject* child)
807
{
808
    // We have to split the parent flow.
809
    RenderBlock* newBox = containingBlock()->createAnonymousBlock();
810
    RenderBoxModelObject* oldContinuation = continuation();
811
    setContinuation(newBox);
812
    RenderObject* beforeChild = child->nextSibling();
813
    children()->removeChildNode(this, child);
814
    splitFlow(beforeChild, newBox, child, oldContinuation);
815
}
816
817
void RenderInline::updateHitTestResult(HitTestResult& result, const IntPoint& point)
818
{
819
    if (result.innerNode())
820
        return;
821
822
    Node* n = node();
823
    IntPoint localPoint(point);
824
    if (n) {
825
        if (isInlineContinuation()) {
826
            // We're in the continuation of a split inline.  Adjust our local point to be in the coordinate space
827
            // of the principal renderer's containing block.  This will end up being the innerNonSharedNode.
828
            RenderBlock* firstBlock = n->renderer()->containingBlock();
829
            
830
            // Get our containing block.
831
            RenderBox* block = containingBlock();
832
            localPoint.move(block->x() - firstBlock->x(), block->y() - firstBlock->y());
833
        }
834
835
        result.setInnerNode(n);
836
        if (!result.innerNonSharedNode())
837
            result.setInnerNonSharedNode(n);
838
        result.setLocalPoint(localPoint);
839
    }
840
}
841
842
void RenderInline::dirtyLineBoxes(bool fullLayout)
552
void RenderInline::dirtyLineBoxes(bool fullLayout)
843
{
553
{
844
    if (fullLayout)
554
    if (fullLayout)
Lines 954-970 void RenderInline::addFocusRingRects(Vec WebCore/rendering/RenderInline.cpp_sec13
954
           curr->addFocusRingRects(rects, pos.x(), pos.y());
664
           curr->addFocusRingRects(rects, pos.x(), pos.y());
955
        }
665
        }
956
    }
666
    }
957
958
    if (continuation()) {
959
        if (continuation()->isInline())
960
            continuation()->addFocusRingRects(rects, 
961
                                              tx - containingBlock()->x() + continuation()->containingBlock()->x(),
962
                                              ty - containingBlock()->y() + continuation()->containingBlock()->y());
963
        else
964
            continuation()->addFocusRingRects(rects, 
965
                                              tx - containingBlock()->x() + toRenderBox(continuation())->x(),
966
                                              ty - containingBlock()->y() + toRenderBox(continuation())->y());
967
    }
968
}
667
}
969
668
970
void RenderInline::paintOutline(GraphicsContext* graphicsContext, int tx, int ty)
669
void RenderInline::paintOutline(GraphicsContext* graphicsContext, int tx, int ty)
- WebCore/rendering/RenderInline.h -15 lines
Lines 58-67 public: WebCore/rendering/RenderInline.h_sec1
58
58
59
    InlineFlowBox* firstLineBox() const { return m_lineBoxes.firstLineBox(); }
59
    InlineFlowBox* firstLineBox() const { return m_lineBoxes.firstLineBox(); }
60
    InlineFlowBox* lastLineBox() const { return m_lineBoxes.lastLineBox(); }
60
    InlineFlowBox* lastLineBox() const { return m_lineBoxes.lastLineBox(); }
61
62
    RenderBoxModelObject* continuation() const { return m_continuation; }
63
64
    virtual void updateDragState(bool dragOn);
65
    
61
    
66
    IntSize relativePositionedInlineOffset(const RenderBox* child) const;
62
    IntSize relativePositionedInlineOffset(const RenderBox* child) const;
67
63
Lines 81-89 private: WebCore/rendering/RenderInline.h_sec2
81
77
82
    virtual bool isRenderInline() const { return true; }
78
    virtual bool isRenderInline() const { return true; }
83
79
84
    void addChildToContinuation(RenderObject* newChild, RenderObject* beforeChild);
85
    virtual void addChildIgnoringContinuation(RenderObject* newChild, RenderObject* beforeChild = 0);
86
87
    void splitInlines(RenderBlock* fromBlock, RenderBlock* toBlock, RenderBlock* middleBlock,
80
    void splitInlines(RenderBlock* fromBlock, RenderBlock* toBlock, RenderBlock* middleBlock,
88
                      RenderObject* beforeChild, RenderBoxModelObject* oldCont);
81
                      RenderObject* beforeChild, RenderBoxModelObject* oldCont);
89
    void splitFlow(RenderObject* beforeChild, RenderBlock* newBlockBox,
82
    void splitFlow(RenderObject* beforeChild, RenderBlock* newBlockBox,
Lines 126-138 private: WebCore/rendering/RenderInline.h_sec3
126
119
127
    virtual int lineHeight(bool firstLine, bool isRootLineBox = false) const;
120
    virtual int lineHeight(bool firstLine, bool isRootLineBox = false) const;
128
121
129
    RenderInline* inlineContinuation() const;
130
    void setContinuation(RenderBoxModelObject* c) { m_continuation = c; }
131
    
132
    virtual void childBecameNonInline(RenderObject* child);
122
    virtual void childBecameNonInline(RenderObject* child);
133
123
134
    virtual void updateHitTestResult(HitTestResult&, const IntPoint&);
135
136
    virtual void imageChanged(WrappedImagePtr, const IntRect* = 0);
124
    virtual void imageChanged(WrappedImagePtr, const IntRect* = 0);
137
125
138
#if ENABLE(DASHBOARD_SUPPORT)
126
#if ENABLE(DASHBOARD_SUPPORT)
Lines 145-157 private: WebCore/rendering/RenderInline.h_sec4
145
    static RenderInline* cloneInline(RenderInline* src);
133
    static RenderInline* cloneInline(RenderInline* src);
146
134
147
    void paintOutlineForLine(GraphicsContext*, int tx, int ty, const IntRect& prevLine, const IntRect& thisLine, const IntRect& nextLine);
135
    void paintOutlineForLine(GraphicsContext*, int tx, int ty, const IntRect& prevLine, const IntRect& thisLine, const IntRect& nextLine);
148
    RenderBoxModelObject* continuationBefore(RenderObject* beforeChild);
149
136
150
    RenderObjectChildList m_children;
137
    RenderObjectChildList m_children;
151
    RenderLineBoxList m_lineBoxes;   // All of the line boxes created for this inline flow.  For example, <i>Hello<br>world.</i> will have two <i> line boxes.
138
    RenderLineBoxList m_lineBoxes;   // All of the line boxes created for this inline flow.  For example, <i>Hello<br>world.</i> will have two <i> line boxes.
152
139
153
    RenderBoxModelObject* m_continuation; // Can be either a block or an inline. <b><i><p>Hello</p></i></b>. In this example the <i> will have a block as its continuation but the
154
                                          // <b> will just have an inline as its continuation.
155
    mutable int m_lineHeight;
140
    mutable int m_lineHeight;
156
    mutable int m_verticalPosition;
141
    mutable int m_verticalPosition;
157
};
142
};
- WebCore/rendering/RenderLineBoxList.cpp -6 / +6 lines
Lines 146-163 void RenderLineBoxList::dirtyLineBoxes() WebCore/rendering/RenderLineBoxList.cpp_sec1
146
146
147
void RenderLineBoxList::paint(RenderBoxModelObject* renderer, RenderObject::PaintInfo& paintInfo, int tx, int ty) const
147
void RenderLineBoxList::paint(RenderBoxModelObject* renderer, RenderObject::PaintInfo& paintInfo, int tx, int ty) const
148
{
148
{
149
    // Only paint during the foreground/selection phases.
150
    if (paintInfo.phase != PaintPhaseForeground && paintInfo.phase != PaintPhaseSelection && paintInfo.phase != PaintPhaseOutline 
151
        && paintInfo.phase != PaintPhaseSelfOutline && paintInfo.phase != PaintPhaseChildOutlines && paintInfo.phase != PaintPhaseTextClip
152
        && paintInfo.phase != PaintPhaseMask)
153
        return;
154
155
    ASSERT(renderer->isRenderBlock() || (renderer->isRenderInline() && renderer->hasLayer())); // The only way an inline could paint like this is if it has a layer.
149
    ASSERT(renderer->isRenderBlock() || (renderer->isRenderInline() && renderer->hasLayer())); // The only way an inline could paint like this is if it has a layer.
156
150
157
    // If we have no lines then we have no work to do.
151
    // If we have no lines then we have no work to do.
158
    if (!firstLineBox())
152
    if (!firstLineBox())
159
        return;
153
        return;
160
154
155
    // Only paint during the foreground/selection phases if we have a layer.  Otherwise we might have an anonymous inline block, so we can't short circuit.
156
    if (firstLineBox()->parent() && (paintInfo.phase != PaintPhaseForeground && paintInfo.phase != PaintPhaseSelection && paintInfo.phase != PaintPhaseOutline 
157
        && paintInfo.phase != PaintPhaseSelfOutline && paintInfo.phase != PaintPhaseChildOutlines && paintInfo.phase != PaintPhaseTextClip
158
        && paintInfo.phase != PaintPhaseMask))
159
        return;
160
161
    // We can check the first box and last box and avoid painting if we don't
161
    // We can check the first box and last box and avoid painting if we don't
162
    // intersect.  This is a quick short-circuit that we can take to avoid walking any lines.
162
    // intersect.  This is a quick short-circuit that we can take to avoid walking any lines.
163
    // FIXME: This check is flawed in the following extremely obscure way:
163
    // FIXME: This check is flawed in the following extremely obscure way:
- WebCore/rendering/RenderListItem.cpp -37 / +51 lines
Lines 27-32 WebCore/rendering/RenderListItem.cpp_sec1
27
#include "CachedImage.h"
27
#include "CachedImage.h"
28
#include "HTMLNames.h"
28
#include "HTMLNames.h"
29
#include "HTMLOListElement.h"
29
#include "HTMLOListElement.h"
30
#include "InlineIterator.h"
31
30
#include "RenderListMarker.h"
32
#include "RenderListMarker.h"
31
#include "RenderView.h"
33
#include "RenderView.h"
32
#include <wtf/StdLibExtras.h>
34
#include <wtf/StdLibExtras.h>
Lines 153-170 bool RenderListItem::isEmpty() const WebCore/rendering/RenderListItem.cpp_sec2
153
    return lastChild() == m_marker;
155
    return lastChild() == m_marker;
154
}
156
}
155
157
156
static RenderObject* getParentOfFirstLineBox(RenderBlock* curr, RenderObject* marker)
158
void RenderListItem::updateValue()
157
{
159
{
158
    RenderObject* firstChild = curr->firstChild();
160
    if (!m_hasExplicitValue) {
159
    if (!firstChild)
161
        m_isValueUpToDate = false;
160
        return 0;
162
        if (m_marker)
163
            m_marker->setNeedsLayoutAndPrefWidthsRecalc();
164
    }
165
}
161
166
162
    for (RenderObject* currChild = firstChild; currChild; currChild = currChild->nextSibling()) {
167
static RenderObject* firstNonMarkerChild(RenderObject* parent)
168
{
169
    RenderObject* result = parent->firstChild();
170
    while (result && result->isListMarker())
171
        result = result->nextSibling();
172
    return result;
173
}
174
175
176
static RenderBlock* listMarkerLocation(RenderBlock* block, RenderListMarker* marker)
177
{
178
    for (RenderObject* currChild = block->firstChild(); currChild; currChild = currChild->nextSibling()) {
163
        if (currChild == marker)
179
        if (currChild == marker)
164
            continue;
180
            continue;
165
181
166
        if (currChild->isInline() && (!currChild->isRenderInline() || curr->generatesLineBoxesForInlineChild(currChild)))
182
        if (currChild->isInline()) {
167
            return curr;
183
            if (!currChild->isRenderInline())
184
                return block;
185
            InlineIterator it(block, currChild, 0);
186
            while (!it.atEnd()) {
187
                if (it.obj->isAnonymousInlineBlock()) {
188
                    RenderBlock* lineBoxParent = listMarkerLocation(toRenderBlock(it.obj), marker);
189
                    if (lineBoxParent)
190
                        return lineBoxParent;
191
                } else if (RenderBlock::requiresLineBox(it))
192
                    return block;
193
                it.increment();
194
            }
195
        }
168
196
169
        if (currChild->isFloating() || currChild->isPositioned())
197
        if (currChild->isFloating() || currChild->isPositioned())
170
            continue;
198
            continue;
Lines 172-212 static RenderObject* getParentOfFirstLin WebCore/rendering/RenderListItem.cpp_sec3
172
        if (currChild->isTable() || !currChild->isRenderBlock())
200
        if (currChild->isTable() || !currChild->isRenderBlock())
173
            break;
201
            break;
174
202
175
        if (curr->isListItem() && currChild->style()->htmlHacks() && currChild->node() &&
203
        if (block->isListItem() && currChild->style()->htmlHacks() && currChild->node() &&
176
            (currChild->node()->hasTagName(ulTag)|| currChild->node()->hasTagName(olTag)))
204
            (currChild->node()->hasTagName(ulTag) || currChild->node()->hasTagName(olTag)))
177
            break;
205
            break;
178
206
179
        RenderObject* lineBox = getParentOfFirstLineBox(toRenderBlock(currChild), marker);
207
        RenderBlock* lineBoxParent = listMarkerLocation(toRenderBlock(currChild), marker);
180
        if (lineBox)
208
        if (lineBoxParent)
181
            return lineBox;
209
            return lineBoxParent;
182
    }
210
    }
183
211
184
    return 0;
212
    return 0;
185
}
213
}
186
214
187
void RenderListItem::updateValue()
188
{
189
    if (!m_hasExplicitValue) {
190
        m_isValueUpToDate = false;
191
        if (m_marker)
192
            m_marker->setNeedsLayoutAndPrefWidthsRecalc();
193
    }
194
}
195
196
static RenderObject* firstNonMarkerChild(RenderObject* parent)
197
{
198
    RenderObject* result = parent->firstChild();
199
    while (result && result->isListMarker())
200
        result = result->nextSibling();
201
    return result;
202
}
203
204
void RenderListItem::updateMarkerLocation()
215
void RenderListItem::updateMarkerLocation()
205
{
216
{
206
    // Sanity check the location of our marker.
217
    // Sanity check the location of our marker.
207
    if (m_marker) {
218
    if (m_marker) {
208
        RenderObject* markerPar = m_marker->parent();
219
        RenderObject* markerPar = m_marker->parent();
209
        RenderObject* lineBoxParent = getParentOfFirstLineBox(this, m_marker);
220
        RenderObject* lineBoxParent = listMarkerLocation(this, m_marker);
210
        if (!lineBoxParent) {
221
        if (!lineBoxParent) {
211
            // If the marker is currently contained inside an anonymous box,
222
            // If the marker is currently contained inside an anonymous box,
212
            // then we are the only item in that anonymous box (since no line box
223
            // then we are the only item in that anonymous box (since no line box
Lines 257-265 void RenderListItem::positionListMarker( WebCore/rendering/RenderListItem.cpp_sec4
257
        int markerOldX = m_marker->x();
268
        int markerOldX = m_marker->x();
258
        int yOffset = 0;
269
        int yOffset = 0;
259
        int xOffset = 0;
270
        int xOffset = 0;
260
        for (RenderBox* o = m_marker->parentBox(); o != this; o = o->parentBox()) {
271
        for (RenderObject* o = m_marker->parent(); o != this; o = o->parent()) {
261
            yOffset += o->y();
272
            if (o->isBox()) {
262
            xOffset += o->x();
273
                yOffset += toRenderBox(o)->y();
274
                xOffset += toRenderBox(o)->x();
275
            }
263
        }
276
        }
264
277
265
        bool adjustOverflow = false;
278
        bool adjustOverflow = false;
Lines 295-307 void RenderListItem::positionListMarker( WebCore/rendering/RenderListItem.cpp_sec5
295
308
296
        if (adjustOverflow) {
309
        if (adjustOverflow) {
297
            IntRect markerRect(markerXPos + xOffset, yOffset, m_marker->width(), m_marker->height());
310
            IntRect markerRect(markerXPos + xOffset, yOffset, m_marker->width(), m_marker->height());
298
            RenderBox* o = m_marker;
311
            RenderObject* o = m_marker;
299
            do {
312
            do {
300
                o = o->parentBox();
313
                o = o->parent();
301
                if (o->isRenderBlock())
314
                if (o->isRenderBlock())
302
                    toRenderBlock(o)->addLayoutOverflow(markerRect);
315
                    toRenderBlock(o)->addLayoutOverflow(markerRect);
303
                markerRect.move(-o->x(), -o->y());
316
                if (o->isBox())
304
            } while (o != this && !o->hasSelfPaintingLayer());
317
                    markerRect.move(-toRenderBox(o)->x(), -toRenderBox(o)->y());
318
            } while (o != this && (!o->isBox() || !toRenderBox(o)->hasSelfPaintingLayer())); // FIXME: Investigate <li><span style="position:relative;left:-100px"><div>text</div></span></li>
305
        }
319
        }
306
    }
320
    }
307
}
321
}
- WebCore/rendering/RenderObject.cpp -2 lines
Lines 2221-2228 void RenderObject::getTextDecorationColo WebCore/rendering/RenderObject.cpp_sec1
2221
            }
2221
            }
2222
        }
2222
        }
2223
        curr = curr->parent();
2223
        curr = curr->parent();
2224
        if (curr && curr->isRenderBlock() && toRenderBlock(curr)->inlineContinuation())
2225
            curr = toRenderBlock(curr)->inlineContinuation();
2226
    } while (curr && decorations && (!quirksMode || !curr->node() ||
2224
    } while (curr && decorations && (!quirksMode || !curr->node() ||
2227
                                     (!curr->node()->hasTagName(aTag) && !curr->node()->hasTagName(fontTag))));
2225
                                     (!curr->node()->hasTagName(aTag) && !curr->node()->hasTagName(fontTag))));
2228
2226
- WebCore/rendering/RenderObject.h +4 lines
Lines 365-370 public: WebCore/rendering/RenderObject.h_sec1
365
    {
365
    {
366
        return m_isAnonymous && style()->display() == BLOCK && style()->styleType() == NOPSEUDO && !isListMarker();
366
        return m_isAnonymous && style()->display() == BLOCK && style()->styleType() == NOPSEUDO && !isListMarker();
367
    }
367
    }
368
    bool isAnonymousInlineBlock() const
369
    {
370
        return m_isAnonymous && style()->display() == INLINE_BLOCK && style()->styleType() == NOPSEUDO && !isRubyRun() && !isRubyBase();
371
    }
368
    bool isInlineContinuation() const { return (node() ? node()->renderer() != this : false) && isRenderInline(); }
372
    bool isInlineContinuation() const { return (node() ? node()->renderer() != this : false) && isRenderInline(); }
369
    bool isFloating() const { return m_floating; }
373
    bool isFloating() const { return m_floating; }
370
    bool isPositioned() const { return m_positioned; } // absolute or fixed positioning
374
    bool isPositioned() const { return m_positioned; } // absolute or fixed positioning
- WebCore/rendering/RenderObjectChildList.cpp -10 lines
Lines 316-331 void RenderObjectChildList::updateBefore WebCore/rendering/RenderObjectChildList.cpp_sec1
316
316
317
    // Whether or not we now want generated content.  
317
    // Whether or not we now want generated content.  
318
    bool newContentWanted = pseudoElementStyle && pseudoElementStyle->display() != NONE;
318
    bool newContentWanted = pseudoElementStyle && pseudoElementStyle->display() != NONE;
319
320
    // For <q><p/></q>, if this object is the inline continuation of the <q>, we only want to generate
321
    // :after content and not :before content.
322
    if (newContentWanted && type == BEFORE && owner->isRenderInline() && toRenderInline(owner)->isInlineContinuation())
323
        newContentWanted = false;
324
325
    // Similarly, if we're the beginning of a <q>, and there's an inline continuation for our object,
326
    // then we don't generate the :after content.
327
    if (newContentWanted && type == AFTER && owner->isRenderInline() && toRenderInline(owner)->continuation())
328
        newContentWanted = false;
329
    
319
    
330
    // If we don't want generated content any longer, or if we have generated content, but it's no longer
320
    // If we don't want generated content any longer, or if we have generated content, but it's no longer
331
    // identical to the new content data we want to build render objects for, then we nuke all
321
    // identical to the new content data we want to build render objects for, then we nuke all
- WebCore/rendering/RenderRubyBase.cpp -2 lines
Lines 116-122 void RenderRubyBase::moveBlockChildren(R WebCore/rendering/RenderRubyBase.cpp_sec1
116
                if (child->isAnonymousBlock()) {
116
                if (child->isAnonymousBlock()) {
117
                    RenderBlock* anonBlock = toRenderBlock(child);
117
                    RenderBlock* anonBlock = toRenderBlock(child);
118
                    ASSERT(anonBlock->childrenInline());
118
                    ASSERT(anonBlock->childrenInline());
119
                    ASSERT(!anonBlock->inlineContinuation());
120
                    anonBlock->moveAllChildrenTo(toBase, toBase->children());
119
                    anonBlock->moveAllChildrenTo(toBase, toBase->children());
121
                    anonBlock->deleteLineBoxTree();
120
                    anonBlock->deleteLineBoxTree();
122
                    anonBlock->destroy();
121
                    anonBlock->destroy();
Lines 143-149 void RenderRubyBase::moveBlockChildren(R WebCore/rendering/RenderRubyBase.cpp_sec2
143
142
144
                    RenderBlock* anonBlock = toRenderBlock(child);
143
                    RenderBlock* anonBlock = toRenderBlock(child);
145
                    ASSERT(anonBlock->childrenInline());
144
                    ASSERT(anonBlock->childrenInline());
146
                    ASSERT(!anonBlock->inlineContinuation());
147
                    // Move inline children out of anonymous block.
145
                    // Move inline children out of anonymous block.
148
                    anonBlock->moveAllChildrenTo(this, children(), anonBlock);
146
                    anonBlock->moveAllChildrenTo(this, children(), anonBlock);
149
                    anonBlock->deleteLineBoxTree();
147
                    anonBlock->deleteLineBoxTree();
- WebCore/rendering/RootInlineBox.cpp -1 / +57 lines
Lines 31-36 WebCore/rendering/RootInlineBox.cpp_sec1
31
#include "Page.h"
31
#include "Page.h"
32
#include "RenderArena.h"
32
#include "RenderArena.h"
33
#include "RenderBlock.h"
33
#include "RenderBlock.h"
34
#include "RenderView.h"
34
35
35
using namespace std;
36
using namespace std;
36
37
Lines 163-168 void RootInlineBox::paintCustomHighlight WebCore/rendering/RootInlineBox.cpp_sec2
163
164
164
void RootInlineBox::paint(RenderObject::PaintInfo& paintInfo, int tx, int ty)
165
void RootInlineBox::paint(RenderObject::PaintInfo& paintInfo, int tx, int ty)
165
{
166
{
167
    RenderBlock* child = anonymousInlineBlock();
168
    if (child) {
169
        // Treat painting of a special inline-block line like the painting of a normal block and go through all phases.
170
        PaintPhase newPhase = (paintInfo.phase == PaintPhaseChildOutlines) ? PaintPhaseOutline : paintInfo.phase;
171
        newPhase = (newPhase == PaintPhaseChildBlockBackgrounds) ? PaintPhaseChildBlockBackground : newPhase;
172
    
173
        // We don't paint our own background, but we do let the child paint its background.
174
        RenderObject::PaintInfo info(paintInfo);
175
        info.phase = newPhase;
176
        info.paintingRoot = renderer()->paintingRootForChildren(paintInfo);
177
        bool isPrinting = renderer()->document()->printing();
178
        
179
        // Check for page-break-before: always, and if it's set, break and bail.
180
        if (isPrinting && child->style()->pageBreakBefore() == PBALWAYS &&
181
            block()->inRootBlockContext() && (ty + child->y()) > paintInfo.rect.y() && 
182
            (ty + child->y()) < paintInfo.rect.bottom()) {
183
            renderer()->view()->setBestTruncatedAt(ty + child->y(), block(), true);
184
            return;
185
        }
186
187
        if (!child->hasSelfPaintingLayer())
188
            child->paint(info, tx, ty);
189
190
        // Check for page-break-after: always, and if it's set, break and bail.
191
        if (isPrinting && child->style()->pageBreakAfter() == PBALWAYS && 
192
            block()->inRootBlockContext() && (ty + child->y() + child->height()) > paintInfo.rect.y() && 
193
            (ty + child->y() + child->height()) < paintInfo.rect.bottom()) {
194
            renderer()->view()->setBestTruncatedAt(ty + child->y() + child->height() + max(0, child->collapsedMarginBottom()), block(), true);
195
            return;
196
        }
197
        
198
        return;
199
    }
200
201
    // Only paint during the foreground/selection phases if we don't have a special anonymous inline block.
202
    if (paintInfo.phase != PaintPhaseForeground && paintInfo.phase != PaintPhaseSelection && paintInfo.phase != PaintPhaseOutline 
203
        && paintInfo.phase != PaintPhaseSelfOutline && paintInfo.phase != PaintPhaseChildOutlines && paintInfo.phase != PaintPhaseTextClip
204
        && paintInfo.phase != PaintPhaseMask)
205
        return;
206
166
    InlineFlowBox::paint(paintInfo, tx, ty);
207
    InlineFlowBox::paint(paintInfo, tx, ty);
167
    paintEllipsisBox(paintInfo, tx, ty);
208
    paintEllipsisBox(paintInfo, tx, ty);
168
#if PLATFORM(MAC)
209
#if PLATFORM(MAC)
Lines 204-209 void RootInlineBox::childRemoved(InlineB WebCore/rendering/RootInlineBox.cpp_sec3
204
245
205
int RootInlineBox::verticallyAlignBoxes(int heightOfBlock)
246
int RootInlineBox::verticallyAlignBoxes(int heightOfBlock)
206
{
247
{
248
    RenderBlock* inlineBlock = anonymousInlineBlock();
249
    if (inlineBlock) {
250
        int lineTop = inlineBlock->y();
251
        int lineBottom = inlineBlock->y() + inlineBlock->height();
252
        firstChild()->setY(lineTop);
253
        setY(lineTop);
254
        computeVerticalOverflow(lineTop, lineBottom, true);
255
        setLineTopBottomPositions(lineTop, lineBottom);
256
        return heightOfBlock;
257
    }
258
    
207
    int maxPositionTop = 0;
259
    int maxPositionTop = 0;
208
    int maxPositionBottom = 0;
260
    int maxPositionBottom = 0;
209
    int maxAscent = 0;
261
    int maxAscent = 0;
Lines 217-223 int RootInlineBox::verticallyAlignBoxes( WebCore/rendering/RootInlineBox.cpp_sec4
217
    bool strictMode = (curr && curr->document()->inStrictMode());
269
    bool strictMode = (curr && curr->document()->inStrictMode());
218
270
219
    computeLogicalBoxHeights(maxPositionTop, maxPositionBottom, maxAscent, maxDescent, strictMode);
271
    computeLogicalBoxHeights(maxPositionTop, maxPositionBottom, maxAscent, maxDescent, strictMode);
220
221
    if (maxAscent + maxDescent < max(maxPositionTop, maxPositionBottom))
272
    if (maxAscent + maxDescent < max(maxPositionTop, maxPositionBottom))
222
        adjustMaxAscentAndDescent(maxAscent, maxDescent, maxPositionTop, maxPositionBottom);
273
        adjustMaxAscentAndDescent(maxAscent, maxDescent, maxPositionTop, maxPositionBottom);
223
274
Lines 430-433 void RootInlineBox::attachLineBoxToRende WebCore/rendering/RootInlineBox.cpp_sec5
430
    block()->lineBoxes()->attachLineBox(this);
481
    block()->lineBoxes()->attachLineBox(this);
431
}
482
}
432
483
484
RenderBlock* RootInlineBox::anonymousInlineBlock() const
485
{
486
    return firstChild() && firstChild() == lastChild() && !firstChild()->isText() && firstChild()->renderer()->isAnonymousInlineBlock() ? toRenderBlock(firstChild()->renderer()) : 0;
487
}
488
433
} // namespace WebCore
489
} // namespace WebCore
- WebCore/rendering/RootInlineBox.h +2 lines
Lines 132-137 public: WebCore/rendering/RootInlineBox.h_sec1
132
    virtual void attachLineBoxToRenderObject();
132
    virtual void attachLineBoxToRenderObject();
133
    virtual void removeLineBoxFromRenderObject();
133
    virtual void removeLineBoxFromRenderObject();
134
134
135
    RenderBlock* anonymousInlineBlock() const;
136
135
protected:
137
protected:
136
    // Where this line ended.  The exact object and the position within that object are stored so that
138
    // Where this line ended.  The exact object and the position within that object are stored so that
137
    // we can create an InlineIterator beginning just after the end of this line.
139
    // we can create an InlineIterator beginning just after the end of this line.

Return to Bug 13430