[SCM] WebKit Debian packaging branch, debian/unstable, updated. debian/1.1.15-1-40151-g37bb677
hyatt
hyatt at 268f45cc-cd09-0410-ab3c-d52691b4dbfc
Sat Sep 26 08:27:20 UTC 2009
The following commit has been merged in the debian/unstable branch:
commit 0c3a9867928cb96d8b8032d6db61062901aa09a5
Author: hyatt <hyatt at 268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date: Mon Feb 23 21:26:26 2004 +0000
Fix for 3558717, make sure that form elements that are removed from a document also remove themselves
from the form.
Reviewed by darin.
* khtml/html/html_formimpl.cpp:
(HTMLGenericFormElementImpl::removedFromDocument):
* khtml/html/html_formimpl.h:
* khtml/xml/dom_nodeimpl.cpp:
* khtml/xml/dom_nodeimpl.h:
Implement smarter line layout for faster typing and repainting when individual lines change.
Reviewed by kocienda.
* khtml/khtmlview.cpp:
(KHTMLViewPrivate::KHTMLViewPrivate):
(KHTMLViewPrivate::~KHTMLViewPrivate):
(KHTMLViewPrivate::reset):
(KHTMLView::addRepaintInfo):
(KHTMLView::layout):
* khtml/khtmlview.h:
* khtml/rendering/bidi.cpp:
(khtml::Bidinext):
(khtml::appendRun):
(khtml::embed):
(khtml::RenderBlock::constructLine):
(khtml::RenderBlock::computeHorizontalPositionsForLine):
(khtml::RenderBlock::computeVerticalPositionsForLine):
(khtml::RenderBlock::bidiReorderLine):
(khtml::buildCompactRuns):
(khtml::RenderBlock::layoutInlineChildren):
(khtml::RenderBlock::determineStartPosition):
(khtml::RenderBlock::determineEndPosition):
(khtml::RenderBlock::matchedEndLine):
(khtml::RenderBlock::findNextLineBreak):
* khtml/rendering/render_block.cpp:
(khtml:::RenderFlow):
(khtml::RenderBlock::layoutBlock):
(khtml::RenderBlock::layoutBlockChildren):
(khtml::RenderBlock::positionNewFloats):
(khtml::RenderBlock::lowestPosition):
(khtml::RenderBlock::rightmostPosition):
(khtml::RenderBlock::leftmostPosition):
* khtml/rendering/render_block.h:
(khtml::RenderBlock::firstRootBox):
(khtml::RenderBlock::lastRootBox):
(khtml::RenderBlock::setLinesAppended):
(khtml::RenderBlock::linesAppended):
* khtml/rendering/render_box.cpp:
(RenderBox::dirtyLineBoxes):
(RenderBox::deleteLineBoxWrapper):
(RenderBox::setInlineBoxWrapper):
* khtml/rendering/render_box.h:
* khtml/rendering/render_br.cpp:
(RenderBR::createInlineBox):
(RenderBR::position):
* khtml/rendering/render_br.h:
* khtml/rendering/render_container.cpp:
(RenderContainer::appendChildNode):
(RenderContainer::insertChildNode):
* khtml/rendering/render_flexbox.cpp:
(khtml::RenderFlexibleBox::placeChild):
* khtml/rendering/render_flow.cpp:
(RenderFlow::extractLineBox):
(RenderFlow::attachLineBox):
(RenderFlow::removeLineBox):
(RenderFlow::dirtyLinesFromChangedChild):
(RenderFlow::dirtyLineBoxes):
(RenderFlow::createInlineBox):
* khtml/rendering/render_flow.h:
* khtml/rendering/render_line.cpp:
(InlineBox::dirtyLineBoxes):
(InlineBox::deleteLine):
(InlineBox::extractLine):
(InlineBox::attachLine):
(InlineBox::adjustVerticalPosition):
(InlineBox::root):
(InlineBox::nextOnLineExists):
(InlineBox::prevOnLineExists):
(InlineFlowBox::removeChild):
(InlineFlowBox::deleteLine):
(InlineFlowBox::extractLine):
(InlineFlowBox::attachLine):
(InlineFlowBox::adjustVerticalPosition):
(InlineFlowBox::verticallyAlignBoxes):
(InlineFlowBox::adjustMaxAscentAndDescent):
(RootInlineBox::adjustVerticalPosition):
(RootInlineBox::childRemoved):
* khtml/rendering/render_line.h:
(khtml::InlineBox::m_extracted):
(khtml::InlineBox::setExtracted):
(khtml::InlineBox::object):
(khtml::InlineBox::parent):
(khtml::InlineBox::isDirty):
(khtml::InlineBox::markDirty):
(khtml::InlineFlowBox::prevFlowBox):
(khtml::InlineFlowBox::nextFlowBox):
(khtml::RootInlineBox::RootInlineBox):
(khtml::RootInlineBox::nextRootBox):
(khtml::RootInlineBox::prevRootBox):
(khtml::RootInlineBox::setLineBreakInfo):
(khtml::RootInlineBox::setLineBreakPos):
(khtml::RootInlineBox::setBlockHeight):
(khtml::RootInlineBox::setEndsWithBreak):
(khtml::RootInlineBox::blockHeight):
(khtml::RootInlineBox::endsWithBreak):
(khtml::RootInlineBox::lineBreakObj):
(khtml::RootInlineBox::lineBreakPos):
* khtml/rendering/render_object.cpp:
(RenderObject::repaintAfterLayoutIfNeeded):
(RenderObject::repaintObjectsBeforeLayout):
(RenderObject::dirtyLinesFromChangedChild):
(RenderObject::createInlineBox):
(RenderObject::dirtyLineBoxes):
(RenderObject::setInlineBoxWrapper):
(RenderObject::deleteLineBoxWrapper):
* khtml/rendering/render_object.h:
(khtml::RenderObject::RepaintInfo::m_repaintRect):
* khtml/rendering/render_table.cpp:
(RenderTableSection::layoutRows):
* khtml/rendering/render_text.cpp:
(InlineTextBox::deleteLine):
(InlineTextBox::extractLine):
(InlineTextBox::attachLine):
(RenderText::RenderText):
(RenderText::detach):
(RenderText::extractTextBox):
(RenderText::attachTextBox):
(RenderText::removeTextBox):
(RenderText::setTextWithOffset):
(RenderText::setText):
(RenderText::dirtyLineBoxes):
(RenderText::createInlineBox):
* khtml/rendering/render_text.h:
(khtml::InlineTextBox::start):
(khtml::InlineTextBox::end):
(khtml::InlineTextBox::offsetRun):
* khtml/xml/dom_textimpl.cpp:
(CharacterDataImpl::setData):
(CharacterDataImpl::appendData):
(CharacterDataImpl::insertData):
(CharacterDataImpl::deleteData):
(CharacterDataImpl::replaceData):
(TextImpl::splitText):
* kwq/KWQRenderTreeDebug.cpp:
(write):
RenderBlock contains two other fixes. The first is a fix to rightmost/lowestPosition to properly add in
margins to floats.
Reviewed by mjs
The second fix is to repair a bug in block-level replaced elements with margins. If the floats they moved to
dodge can fit in their margins, then they don't technically have to move at all.
Reviewed by john
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@6107 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/WebCore/ChangeLog-2005-08-23 b/WebCore/ChangeLog-2005-08-23
index 7346623..55def2b 100644
--- a/WebCore/ChangeLog-2005-08-23
+++ b/WebCore/ChangeLog-2005-08-23
@@ -1,3 +1,163 @@
+2004-02-23 David Hyatt <hyatt at apple.com>
+
+ Fix for 3558717, make sure that form elements that are removed from a document also remove themselves
+ from the form.
+
+ Reviewed by darin.
+
+ * khtml/html/html_formimpl.cpp:
+ (HTMLGenericFormElementImpl::removedFromDocument):
+ * khtml/html/html_formimpl.h:
+ * khtml/xml/dom_nodeimpl.cpp:
+ * khtml/xml/dom_nodeimpl.h:
+
+ Implement smarter line layout for faster typing and repainting when individual lines change.
+
+ Reviewed by kocienda.
+
+ * khtml/khtmlview.cpp:
+ (KHTMLViewPrivate::KHTMLViewPrivate):
+ (KHTMLViewPrivate::~KHTMLViewPrivate):
+ (KHTMLViewPrivate::reset):
+ (KHTMLView::addRepaintInfo):
+ (KHTMLView::layout):
+ * khtml/khtmlview.h:
+ * khtml/rendering/bidi.cpp:
+ (khtml::Bidinext):
+ (khtml::appendRun):
+ (khtml::embed):
+ (khtml::RenderBlock::constructLine):
+ (khtml::RenderBlock::computeHorizontalPositionsForLine):
+ (khtml::RenderBlock::computeVerticalPositionsForLine):
+ (khtml::RenderBlock::bidiReorderLine):
+ (khtml::buildCompactRuns):
+ (khtml::RenderBlock::layoutInlineChildren):
+ (khtml::RenderBlock::determineStartPosition):
+ (khtml::RenderBlock::determineEndPosition):
+ (khtml::RenderBlock::matchedEndLine):
+ (khtml::RenderBlock::findNextLineBreak):
+ * khtml/rendering/render_block.cpp:
+ (khtml:::RenderFlow):
+ (khtml::RenderBlock::layoutBlock):
+ (khtml::RenderBlock::layoutBlockChildren):
+ (khtml::RenderBlock::positionNewFloats):
+ (khtml::RenderBlock::lowestPosition):
+ (khtml::RenderBlock::rightmostPosition):
+ (khtml::RenderBlock::leftmostPosition):
+ * khtml/rendering/render_block.h:
+ (khtml::RenderBlock::firstRootBox):
+ (khtml::RenderBlock::lastRootBox):
+ (khtml::RenderBlock::setLinesAppended):
+ (khtml::RenderBlock::linesAppended):
+ * khtml/rendering/render_box.cpp:
+ (RenderBox::dirtyLineBoxes):
+ (RenderBox::deleteLineBoxWrapper):
+ (RenderBox::setInlineBoxWrapper):
+ * khtml/rendering/render_box.h:
+ * khtml/rendering/render_br.cpp:
+ (RenderBR::createInlineBox):
+ (RenderBR::position):
+ * khtml/rendering/render_br.h:
+ * khtml/rendering/render_container.cpp:
+ (RenderContainer::appendChildNode):
+ (RenderContainer::insertChildNode):
+ * khtml/rendering/render_flexbox.cpp:
+ (khtml::RenderFlexibleBox::placeChild):
+ * khtml/rendering/render_flow.cpp:
+ (RenderFlow::extractLineBox):
+ (RenderFlow::attachLineBox):
+ (RenderFlow::removeLineBox):
+ (RenderFlow::dirtyLinesFromChangedChild):
+ (RenderFlow::dirtyLineBoxes):
+ (RenderFlow::createInlineBox):
+ * khtml/rendering/render_flow.h:
+ * khtml/rendering/render_line.cpp:
+ (InlineBox::dirtyLineBoxes):
+ (InlineBox::deleteLine):
+ (InlineBox::extractLine):
+ (InlineBox::attachLine):
+ (InlineBox::adjustVerticalPosition):
+ (InlineBox::root):
+ (InlineBox::nextOnLineExists):
+ (InlineBox::prevOnLineExists):
+ (InlineFlowBox::removeChild):
+ (InlineFlowBox::deleteLine):
+ (InlineFlowBox::extractLine):
+ (InlineFlowBox::attachLine):
+ (InlineFlowBox::adjustVerticalPosition):
+ (InlineFlowBox::verticallyAlignBoxes):
+ (InlineFlowBox::adjustMaxAscentAndDescent):
+ (RootInlineBox::adjustVerticalPosition):
+ (RootInlineBox::childRemoved):
+ * khtml/rendering/render_line.h:
+ (khtml::InlineBox::m_extracted):
+ (khtml::InlineBox::setExtracted):
+ (khtml::InlineBox::object):
+ (khtml::InlineBox::parent):
+ (khtml::InlineBox::isDirty):
+ (khtml::InlineBox::markDirty):
+ (khtml::InlineFlowBox::prevFlowBox):
+ (khtml::InlineFlowBox::nextFlowBox):
+ (khtml::RootInlineBox::RootInlineBox):
+ (khtml::RootInlineBox::nextRootBox):
+ (khtml::RootInlineBox::prevRootBox):
+ (khtml::RootInlineBox::setLineBreakInfo):
+ (khtml::RootInlineBox::setLineBreakPos):
+ (khtml::RootInlineBox::setBlockHeight):
+ (khtml::RootInlineBox::setEndsWithBreak):
+ (khtml::RootInlineBox::blockHeight):
+ (khtml::RootInlineBox::endsWithBreak):
+ (khtml::RootInlineBox::lineBreakObj):
+ (khtml::RootInlineBox::lineBreakPos):
+ * khtml/rendering/render_object.cpp:
+ (RenderObject::repaintAfterLayoutIfNeeded):
+ (RenderObject::repaintObjectsBeforeLayout):
+ (RenderObject::dirtyLinesFromChangedChild):
+ (RenderObject::createInlineBox):
+ (RenderObject::dirtyLineBoxes):
+ (RenderObject::setInlineBoxWrapper):
+ (RenderObject::deleteLineBoxWrapper):
+ * khtml/rendering/render_object.h:
+ (khtml::RenderObject::RepaintInfo::m_repaintRect):
+ * khtml/rendering/render_table.cpp:
+ (RenderTableSection::layoutRows):
+ * khtml/rendering/render_text.cpp:
+ (InlineTextBox::deleteLine):
+ (InlineTextBox::extractLine):
+ (InlineTextBox::attachLine):
+ (RenderText::RenderText):
+ (RenderText::detach):
+ (RenderText::extractTextBox):
+ (RenderText::attachTextBox):
+ (RenderText::removeTextBox):
+ (RenderText::setTextWithOffset):
+ (RenderText::setText):
+ (RenderText::dirtyLineBoxes):
+ (RenderText::createInlineBox):
+ * khtml/rendering/render_text.h:
+ (khtml::InlineTextBox::start):
+ (khtml::InlineTextBox::end):
+ (khtml::InlineTextBox::offsetRun):
+ * khtml/xml/dom_textimpl.cpp:
+ (CharacterDataImpl::setData):
+ (CharacterDataImpl::appendData):
+ (CharacterDataImpl::insertData):
+ (CharacterDataImpl::deleteData):
+ (CharacterDataImpl::replaceData):
+ (TextImpl::splitText):
+ * kwq/KWQRenderTreeDebug.cpp:
+ (write):
+
+ RenderBlock contains two other fixes. The first is a fix to rightmost/lowestPosition to properly add in
+ margins to floats.
+
+ Reviewed by mjs
+
+ The second fix is to repair a bug in block-level replaced elements with margins. If the floats they moved to
+ dodge can fit in their margins, then they don't technically have to move at all.
+
+ Reviewed by john
+
2004-02-20 Maciej Stachowiak <mjs at apple.com>
Reviewed by Darin.
diff --git a/WebCore/khtml/html/html_formimpl.cpp b/WebCore/khtml/html/html_formimpl.cpp
index d1af261..135a7cd 100644
--- a/WebCore/khtml/html/html_formimpl.cpp
+++ b/WebCore/khtml/html/html_formimpl.cpp
@@ -780,6 +780,15 @@ void HTMLGenericFormElementImpl::attach()
}
}
+void HTMLGenericFormElementImpl::removedFromDocument()
+{
+ if (m_form)
+ m_form->removeFormElement(this);
+ m_form = 0;
+
+ HTMLElementImpl::removedFromDocument();
+}
+
HTMLFormElementImpl *HTMLGenericFormElementImpl::getForm() const
{
NodeImpl *p = parentNode();
diff --git a/WebCore/khtml/html/html_formimpl.h b/WebCore/khtml/html/html_formimpl.h
index 147d263..e894b41 100644
--- a/WebCore/khtml/html/html_formimpl.h
+++ b/WebCore/khtml/html/html_formimpl.h
@@ -144,6 +144,8 @@ public:
virtual void parseHTMLAttribute(HTMLAttributeImpl *attr);
virtual void attach();
+ virtual void removedFromDocument();
+
virtual void reset() {}
void onSelect();
diff --git a/WebCore/khtml/khtmlview.cpp b/WebCore/khtml/khtmlview.cpp
index 041b5ab..f470029 100644
--- a/WebCore/khtml/khtmlview.cpp
+++ b/WebCore/khtml/khtmlview.cpp
@@ -96,6 +96,7 @@ class KHTMLViewPrivate {
public:
KHTMLViewPrivate()
{
+ repaintRects = 0;
underMouse = 0;
reset();
tp=0;
@@ -123,6 +124,7 @@ public:
if (underMouse)
underMouse->deref();
delete tooltip;
+ delete repaintRects;
}
void reset()
{
@@ -162,6 +164,8 @@ public:
#if APPLE_CHANGES
firstLayout = true;
#endif
+ if (repaintRects)
+ repaintRects->clear();
}
QPainter *tp;
@@ -204,6 +208,10 @@ public:
#endif
bool mousePressed;
KHTMLToolTip *tooltip;
+
+ // Used by objects during layout to communicate repaints that need to take place only
+ // after all layout has been completed.
+ QPtrList<RenderObject::RepaintInfo>* repaintRects;
};
#ifndef QT_NO_TOOLTIP
@@ -503,6 +511,16 @@ bool KHTMLView::needsFullRepaint() const
return d->doFullRepaint;
}
+void KHTMLView::addRepaintInfo(RenderObject* o, const QRect& r)
+{
+ if (!d->repaintRects) {
+ d->repaintRects = new QPtrList<RenderObject::RepaintInfo>;
+ d->repaintRects->setAutoDelete(true);
+ }
+
+ d->repaintRects->append(new RenderObject::RepaintInfo(o, r));
+}
+
void KHTMLView::layout()
{
if (d->layoutSuppressed)
@@ -549,6 +567,8 @@ void KHTMLView::layout()
}
d->doFullRepaint = d->firstLayout || root->printingMode();
+ if (d->repaintRects)
+ d->repaintRects->clear();
#if APPLE_CHANGES
// Now set our scrollbar state for the layout.
@@ -617,6 +637,16 @@ void KHTMLView::layout()
root->updateWidgetPositions();
#endif
+ if (d->repaintRects && !d->repaintRects->isEmpty()) {
+ // FIXME: Could optimize this and have objects removed from this list
+ // if they ever do full repaints.
+ RenderObject::RepaintInfo* r;
+ QPtrListIterator<RenderObject::RepaintInfo> it(*d->repaintRects);
+ for ( ; (r = it.current()); ++it)
+ r->m_object->repaintRectangle(r->m_repaintRect);
+ d->repaintRects->clear();
+ }
+
if (root->needsLayout()) {
//qDebug("needs layout, delaying repaint");
scheduleRelayout();
diff --git a/WebCore/khtml/khtmlview.h b/WebCore/khtml/khtmlview.h
index 03b7094..687c07e 100644
--- a/WebCore/khtml/khtmlview.h
+++ b/WebCore/khtml/khtmlview.h
@@ -158,6 +158,8 @@ public:
bool needsFullRepaint() const;
+ void addRepaintInfo(khtml::RenderObject* o, const QRect& r);
+
#if APPLE_CHANGES
void resetScrollBars();
#endif
diff --git a/WebCore/khtml/rendering/bidi.cpp b/WebCore/khtml/rendering/bidi.cpp
index c97726c..3ceb121 100644
--- a/WebCore/khtml/rendering/bidi.cpp
+++ b/WebCore/khtml/rendering/bidi.cpp
@@ -93,9 +93,9 @@ static uint sCurrMidpoint;
static bool betweenMidpoints;
static bool isLineEmpty = true;
-static bool previousLineBrokeAtBR = true;
+static bool previousLineBrokeCleanly = true;
static QChar::Direction dir;
-static bool adjustEmbeddding;
+static bool adjustEmbedding;
static bool emptyRun = true;
static int numSpaces;
@@ -250,7 +250,7 @@ static inline RenderObject *Bidinext(RenderObject *par, RenderObject *current, B
//kdDebug( 6040 ) << "current = " << current << endl;
if (!oldEndOfInline && !current->isFloating() && !current->isReplaced() && !current->isPositioned()) {
next = current->firstChild();
- if ( next && adjustEmbeddding ) {
+ if ( next && adjustEmbedding ) {
EUnicodeBidi ub = next->style()->unicodeBidi();
if ( ub != UBNormal && !emptyRun ) {
EDirection dir = next->style()->direction();
@@ -272,7 +272,7 @@ QChar::Direction d = ( ub == Embed ? ( dir == RTL ? QChar::DirRLE : QChar::DirLR
while (current && current != par) {
next = current->nextSibling();
if (next) break;
- if ( adjustEmbeddding && current->style()->unicodeBidi() != UBNormal && !emptyRun ) {
+ if ( adjustEmbedding && current->style()->unicodeBidi() != UBNormal && !emptyRun ) {
embed( QChar::DirPDF, bidi );
}
current = current->parent();
@@ -516,8 +516,8 @@ static void appendRun( BidiState &bidi )
kdDebug(6041) << "appendRun: dir="<<(int)dir<<endl;
#endif
- bool b = adjustEmbeddding;
- adjustEmbeddding = false;
+ bool b = adjustEmbedding;
+ adjustEmbedding = false;
int start = bidi.sor.pos;
RenderObject *obj = bidi.sor.obj;
@@ -533,7 +533,7 @@ static void appendRun( BidiState &bidi )
bidi.sor = bidi.eor;
dir = QChar::DirON;
bidi.status.eor = QChar::DirON;
- adjustEmbeddding = b;
+ adjustEmbedding = b;
}
static void embed( QChar::Direction d, BidiState &bidi )
@@ -541,8 +541,8 @@ static void embed( QChar::Direction d, BidiState &bidi )
#if BIDI_DEBUG > 1
qDebug("*** embed dir=%d emptyrun=%d", d, emptyRun );
#endif
- bool b = adjustEmbeddding ;
- adjustEmbeddding = false;
+ bool b = adjustEmbedding ;
+ adjustEmbedding = false;
if ( d == QChar::DirPDF ) {
BidiContext *c = bidi.context->parent;
if (c) {
@@ -602,7 +602,7 @@ static void embed( QChar::Direction d, BidiState &bidi )
bidi.status.lastStrong = runDir;
}
}
- adjustEmbeddding = b;
+ adjustEmbedding = b;
}
InlineFlowBox* RenderBlock::createLineBoxes(RenderObject* obj)
@@ -641,7 +641,7 @@ InlineFlowBox* RenderBlock::createLineBoxes(RenderObject* obj)
return box;
}
-InlineFlowBox* RenderBlock::constructLine(const BidiIterator &start, const BidiIterator &end)
+RootInlineBox* RenderBlock::constructLine(const BidiIterator &start, const BidiIterator &end)
{
if (!sFirstBidiRun)
return 0; // We had no runs. Don't make a root inline box at all. The line is empty.
@@ -649,17 +649,18 @@ InlineFlowBox* RenderBlock::constructLine(const BidiIterator &start, const BidiI
InlineFlowBox* parentBox = 0;
for (BidiRun* r = sFirstBidiRun; r; r = r->nextRun) {
// Create a box for our object.
- r->box = r->obj->createInlineBox(r->obj->isPositioned(), false);
-
- // If we have no parent box yet, or if the run is not simply a sibling,
- // then we need to construct inline boxes as necessary to properly enclose the
- // run's inline box.
- if (!parentBox || (parentBox->object() != r->obj->parent()))
- // Create new inline boxes all the way back to the appropriate insertion point.
- parentBox = createLineBoxes(r->obj->parent());
-
- // Append the inline box to this line.
- parentBox->addToLine(r->box);
+ r->box = r->obj->createInlineBox(r->obj->isPositioned(), false, sBidiRunCount == 1);
+ if (r->box) {
+ // If we have no parent box yet, or if the run is not simply a sibling,
+ // then we need to construct inline boxes as necessary to properly enclose the
+ // run's inline box.
+ if (!parentBox || (parentBox->object() != r->obj->parent()))
+ // Create new inline boxes all the way back to the appropriate insertion point.
+ parentBox = createLineBoxes(r->obj->parent());
+
+ // Append the inline box to this line.
+ parentBox->addToLine(r->box);
+ }
}
// We should have a root inline box. It should be unconstructed and
@@ -680,16 +681,16 @@ InlineFlowBox* RenderBlock::constructLine(const BidiIterator &start, const BidiI
lastLineBox()->setConstructed();
// Return the last line.
- return lastLineBox();
+ return lastRootBox();
}
-void RenderBlock::computeHorizontalPositionsForLine(InlineFlowBox* lineBox, BidiState &bidi)
+void RenderBlock::computeHorizontalPositionsForLine(RootInlineBox* lineBox, BidiState &bidi)
{
// First determine our total width.
int totWidth = lineBox->getFlowSpacingWidth();
BidiRun* r = 0;
for (r = sFirstBidiRun; r; r = r->nextRun) {
- if (r->obj->isPositioned())
+ if (!r->box || r->obj->isPositioned())
continue; // Positioned objects are only participating to figure out their
// correct static x position. They have no effect on the width.
if (r->obj->isText())
@@ -718,7 +719,7 @@ void RenderBlock::computeHorizontalPositionsForLine(InlineFlowBox* lineBox, Bidi
numSpaces = 0;
break;
case JUSTIFY:
- if (numSpaces != 0 && !bidi.current.atEnd() && !bidi.current.obj->isBR() )
+ if (numSpaces != 0 && !bidi.current.atEnd() && !lineBox->endsWithBreak())
break;
// fall through
case TAAUTO:
@@ -741,6 +742,8 @@ void RenderBlock::computeHorizontalPositionsForLine(InlineFlowBox* lineBox, Bidi
if (numSpaces > 0) {
for (r = sFirstBidiRun; r; r = r->nextRun) {
+ if (!r->box) continue;
+
int spaceAdd = 0;
if (numSpaces > 0 && r->obj->isText() && !r->compact) {
// get the number of spaces in the run
@@ -771,9 +774,10 @@ void RenderBlock::computeHorizontalPositionsForLine(InlineFlowBox* lineBox, Bidi
m_overflowWidth = rightPos; // FIXME: Work for rtl overflow also.
}
-void RenderBlock::computeVerticalPositionsForLine(InlineFlowBox* lineBox)
+void RenderBlock::computeVerticalPositionsForLine(RootInlineBox* lineBox)
{
lineBox->verticallyAlignBoxes(m_height);
+ lineBox->setBlockHeight(m_height);
// See if the line spilled out. If so set overflow height accordingly.
int bottomOfLine = lineBox->bottomOverflow();
@@ -782,6 +786,8 @@ void RenderBlock::computeVerticalPositionsForLine(InlineFlowBox* lineBox)
// Now make sure we place replaced render objects correctly.
for (BidiRun* r = sFirstBidiRun; r; r = r->nextRun) {
+ if (!r->box) continue; // Skip runs with no line boxes.
+
// Align positioned boxes with the top of the line box. This is
// a reasonable approximation of an appropriate y position.
if (r->obj->isPositioned())
@@ -1154,9 +1160,9 @@ void RenderBlock::bidiReorderLine(const BidiIterator &start, const BidiIterator
// this causes the operator ++ to open and close embedding levels as needed
// for the CSS unicode-bidi property
- adjustEmbeddding = true;
+ adjustEmbedding = true;
bidi.current.increment( bidi );
- adjustEmbeddding = false;
+ adjustEmbedding = false;
if ( bidi.current == end ) {
if ( emptyRun )
@@ -1249,14 +1255,14 @@ static void buildCompactRuns(RenderObject* compactObj, BidiState &bidi)
// Format the compact like it is its own single line. We build up all the runs for
// the little compact and then reorder them for bidi.
RenderBlock* compactBlock = static_cast<RenderBlock*>(compactObj);
- adjustEmbeddding = true;
+ adjustEmbedding = true;
BidiIterator start(compactBlock, first(compactBlock, bidi), 0);
- adjustEmbeddding = false;
+ adjustEmbedding = false;
BidiIterator end = start;
betweenMidpoints = false;
isLineEmpty = true;
- previousLineBrokeAtBR = true;
+ previousLineBrokeCleanly = true;
end = compactBlock->findNextLineBreak(start, bidi);
if (!isLineEmpty)
@@ -1274,10 +1280,13 @@ static void buildCompactRuns(RenderObject* compactObj, BidiState &bidi)
sBuildingCompactRuns = false;
}
-void RenderBlock::layoutInlineChildren(bool relayoutChildren)
+QRect RenderBlock::layoutInlineChildren(bool relayoutChildren)
{
BidiState bidi;
+ bool useRepaintRect = false;
+ QRect repaintRect(0,0,0,0);
+
m_overflowHeight = 0;
invalidateVerticalPositions();
@@ -1295,37 +1304,47 @@ void RenderBlock::layoutInlineChildren(bool relayoutChildren)
if (style()->hidesOverflow() && m_layer)
toAdd += m_layer->horizontalScrollbarHeight();
- // Clear out our line boxes.
- deleteLineBoxes();
+ // Figure out if we should clear out our line boxes.
+ // FIXME: Handle resize eventually!
+ // FIXME: Do something better when floats are present.
+ bool fullLayout = !firstLineBox() || !firstChild() || selfNeedsLayout() || relayoutChildren || containsFloats();
+ if (fullLayout)
+ deleteLineBoxes();
if (firstChild()) {
// layout replaced elements
bool endOfInline = false;
- RenderObject *o = first( this, bidi, false );
- while ( o ) {
- if(o->isReplaced() || o->isFloating() || o->isPositioned()) {
- //kdDebug(6041) << "layouting replaced or floating child" << endl;
+ RenderObject *o = first(this, bidi, false);
+ bool hasFloat = false;
+ while (o) {
+ if (o->isReplaced() || o->isFloating() || o->isPositioned()) {
if (relayoutChildren || o->style()->width().isPercent() || o->style()->height().isPercent())
o->setChildNeedsLayout(true, false);
if (o->isPositioned())
o->containingBlock()->insertPositionedObject(o);
- else
+ else {
+ if (o->isFloating())
+ hasFloat = true;
+ else if (fullLayout || o->needsLayout()) // Replaced elements
+ o->dirtyLineBoxes(fullLayout);
o->layoutIfNeeded();
-
- if (o->isReplaced())
- o->deleteLineBoxWrapper();
- }
- else if(o->isText()) {
- static_cast<RenderText *>(o)->deleteTextBoxes();
- o->setNeedsLayout(false);
+ }
}
- else if (o->isInlineFlow() && !endOfInline) {
- static_cast<RenderFlow*>(o)->deleteLineBoxes();
+ else if (o->isText() || (o->isInlineFlow() && !endOfInline)) {
+ if (fullLayout || o->selfNeedsLayout())
+ o->dirtyLineBoxes(fullLayout);
o->setNeedsLayout(false);
}
o = Bidinext( this, o, bidi, false, &endOfInline);
}
+ if (hasFloat)
+ fullLayout = true; // FIXME: Will need to find a way to optimize floats some day.
+
+ if (fullLayout && !selfNeedsLayout())
+ setNeedsLayout(true, false); // Mark ourselves as needing a full layout. This way we'll repaint like
+ // we're supposed to.
+
BidiContext *startEmbed;
if( style()->direction() == LTR ) {
startEmbed = new BidiContext( 0, QChar::DirL );
@@ -1338,27 +1357,48 @@ void RenderBlock::layoutInlineChildren(bool relayoutChildren)
bidi.status.lastStrong = QChar::DirON;
bidi.status.last = QChar::DirON;
-
bidi.context = startEmbed;
- adjustEmbeddding = true;
- BidiIterator start(this, first(this, bidi), 0);
- adjustEmbeddding = false;
- BidiIterator end = start;
-
- m_firstLine = true;
if (!smidpoints)
smidpoints = new QMemArray<BidiIterator>;
-
+
sNumMidpoints = 0;
sCurrMidpoint = 0;
sCompactFirstBidiRun = sCompactLastBidiRun = 0;
sCompactBidiRunCount = 0;
-
- previousLineBrokeAtBR = true;
- while( !end.atEnd() ) {
+ // We want to skip ahead to the first dirty line
+ BidiIterator start;
+ RootInlineBox* startLine = determineStartPosition(fullLayout, start, bidi);
+
+ // We also find the first clean line and extract these lines. We will add them back
+ // if we determine that we're able to synchronize after handling all our dirty lines.
+ BidiIterator cleanLineStart;
+ int endLineYPos;
+ RootInlineBox* endLine = (fullLayout || !startLine) ?
+ 0 : determineEndPosition(startLine, cleanLineStart, endLineYPos);
+
+ if (startLine) {
+ useRepaintRect = true;
+ repaintRect.setY(m_height);
+ RenderArena* arena = renderArena();
+ RootInlineBox* box = startLine;
+ while (box) {
+ RootInlineBox* next = box->nextRootBox();
+ box->deleteLine(arena);
+ box = next;
+ }
+ startLine = 0;
+ }
+
+ BidiIterator end = start;
+
+ bool endLineMatched = false;
+ while (!end.atEnd()) {
start = end;
+ if (endLine && (endLineMatched = matchedEndLine(start, cleanLineStart, endLine, endLineYPos)))
+ break;
+
betweenMidpoints = false;
isLineEmpty = true;
if (m_firstLine && firstChild() && firstChild()->isCompact()) {
@@ -1382,9 +1422,12 @@ void RenderBlock::layoutInlineChildren(bool relayoutChildren)
sBidiRunCount += sCompactBidiRunCount;
}
+ RootInlineBox* lineBox = 0;
if (sBidiRunCount) {
- InlineFlowBox* lineBox = constructLine(start, end);
+ lineBox = constructLine(start, end);
if (lineBox) {
+ lineBox->setEndsWithBreak(previousLineBrokeCleanly);
+
// Now we position all of our text runs horizontally.
computeHorizontalPositionsForLine(lineBox, bidi);
@@ -1395,16 +1438,15 @@ void RenderBlock::layoutInlineChildren(bool relayoutChildren)
}
}
- if( end == start || (end.obj && end.obj->isBR() && !start.obj->isBR() ) ) {
- adjustEmbeddding = true;
+ if (end == start || (end.obj && end.obj->style()->whiteSpace() == PRE && end.current() == QChar('\n'))) {
+ adjustEmbedding = true;
end.increment(bidi);
- adjustEmbeddding = false;
- } else if (end.obj && end.obj->style()->whiteSpace() == PRE && end.current() == QChar('\n')) {
- adjustEmbeddding = true;
- end.increment(bidi);
- adjustEmbeddding = false;
+ adjustEmbedding = false;
}
+ if (lineBox)
+ lineBox->setLineBreakInfo(end.obj, end.pos);
+
m_firstLine = false;
newLine();
}
@@ -1416,6 +1458,45 @@ void RenderBlock::layoutInlineChildren(bool relayoutChildren)
}
startEmbed->deref();
//embed->deref();
+
+ if (endLine) {
+ if (endLineMatched) {
+ // Attach all the remaining lines, and then adjust their y-positions as needed.
+ for (RootInlineBox* line = endLine; line; line = line->nextRootBox())
+ line->attachLine();
+
+ // Now apply the offset to each line if needed.
+ int delta = m_height - endLineYPos;
+ if (delta)
+ for (RootInlineBox* line = endLine; line; line = line->nextRootBox())
+ line->adjustVerticalPosition(delta);
+
+ // Now set our height and check for overflow.
+ int currYPos = m_height;
+ m_height = lastRootBox()->blockHeight();
+ m_overflowHeight = kMax(m_height, m_overflowHeight);
+ int bottomOfLine = lastRootBox()->bottomOverflow();
+ if (bottomOfLine > m_height && bottomOfLine > m_overflowHeight)
+ m_overflowHeight = bottomOfLine;
+ if (delta)
+ repaintRect.setHeight(kMax(m_overflowHeight-delta, m_overflowHeight) - repaintRect.y());
+ else
+ repaintRect.setHeight(currYPos - repaintRect.y());
+ }
+ else {
+ // Delete all the remaining lines.
+ m_overflowHeight = kMax(m_height, m_overflowHeight);
+ InlineRunBox* line = endLine;
+ RenderArena* arena = renderArena();
+ while (line) {
+ InlineRunBox* next = line->nextLineBox();
+ if (!next)
+ repaintRect.setHeight(kMax(m_overflowHeight, line->bottomOverflow()) - repaintRect.y());
+ line->deleteLine(arena);
+ line = next;
+ }
+ }
+ }
}
sNumMidpoints = 0;
@@ -1430,9 +1511,18 @@ void RenderBlock::layoutInlineChildren(bool relayoutChildren)
m_height += toAdd;
// Always make sure this is at least our height.
- if (m_overflowHeight < m_height)
- m_overflowHeight = m_height;
+ m_overflowHeight = kMax(m_height, m_overflowHeight);
+
+ if (useRepaintRect) {
+ repaintRect.setWidth(kMax((int)m_width, m_overflowWidth));
+ if (repaintRect.height() == 0)
+ repaintRect.setHeight(m_overflowHeight - repaintRect.y());
+ }
+
+ setLinesAppended(false);
+ return repaintRect;
+
#if BIDI_DEBUG > 1
kdDebug(6041) << " ------- bidi end " << this << " -------" << endl;
#endif
@@ -1440,6 +1530,128 @@ void RenderBlock::layoutInlineChildren(bool relayoutChildren)
//kdDebug(6040) << "height = " << m_height <<endl;
}
+RootInlineBox* RenderBlock::determineStartPosition(bool fullLayout, BidiIterator& start, BidiState& bidi)
+{
+ RootInlineBox* curr = 0;
+ RootInlineBox* last = 0;
+ RenderObject* startObj = 0;
+ int pos = 0;
+
+ if (fullLayout) {
+ // Nuke all our lines.
+ if (firstRootBox()) {
+ RenderArena* arena = renderArena();
+ curr = firstRootBox();
+ while (curr) {
+ RootInlineBox* next = curr->nextRootBox();
+ curr->deleteLine(arena);
+ curr = next;
+ }
+ KHTMLAssert(!m_firstLineBox && !m_lastLineBox);
+ }
+ }
+ else {
+ for (curr = firstRootBox(); curr && !curr->isDirty(); curr = curr->nextRootBox());
+ if (curr) {
+ // We have a dirty line.
+ if (curr->prevRootBox()) {
+ // We have a previous line.
+ if (!curr->prevRootBox()->endsWithBreak())
+ curr = curr->prevRootBox(); // The previous line didn't break cleanly, so treat it as dirty also.
+ }
+ }
+ else {
+ // No dirty lines were found.
+ // If the last line didn't break cleanly, treat it as dirty.
+ if (lastRootBox() && !lastRootBox()->endsWithBreak())
+ curr = lastRootBox();
+ }
+
+ // If we have no dirty lines, then last is just the last root box.
+ last = curr ? curr->prevRootBox() : lastRootBox();
+ }
+
+ m_firstLine = !last;
+ previousLineBrokeCleanly = !last || last->endsWithBreak();
+ if (last) {
+ m_height = last->blockHeight();
+ int bottomOfLine = last->bottomOverflow();
+ if (bottomOfLine > m_height && bottomOfLine > m_overflowHeight)
+ m_overflowHeight = bottomOfLine;
+ startObj = last->lineBreakObj();
+ pos = last->lineBreakPos();
+ }
+ else
+ startObj = first(this, bidi, 0);
+
+ adjustEmbedding = true;
+ start = BidiIterator(this, startObj, pos);
+ adjustEmbedding = false;
+
+ return curr;
+}
+
+RootInlineBox* RenderBlock::determineEndPosition(RootInlineBox* startLine, BidiIterator& cleanLineStart,
+ int& yPos)
+{
+ RootInlineBox* last = 0;
+ if (m_linesAppended)
+ last = 0;
+ else {
+ for (RootInlineBox* curr = startLine; curr; curr = curr->nextRootBox())
+ if (curr->isDirty() && curr->nextRootBox() && !curr->nextRootBox()->isDirty())
+ last = curr->nextRootBox();
+ }
+
+ if (!last)
+ return 0;
+
+ cleanLineStart = BidiIterator(this, last->prevRootBox()->lineBreakObj(), last->prevRootBox()->lineBreakPos());
+ yPos = last->prevRootBox()->blockHeight();
+
+ for (RootInlineBox* line = last; line; line = line->nextRootBox())
+ line->extractLine(); // Disconnect all line boxes from their render objects while preserving
+ // their connections to one another.
+
+ return last;
+}
+
+bool RenderBlock::matchedEndLine(const BidiIterator& start, const BidiIterator& endLineStart,
+ RootInlineBox*& endLine, int& endYPos)
+{
+ if (start == endLineStart)
+ return true; // The common case. All the data we already have is correct.
+ else {
+ // The first clean line doesn't match, but we can check a handful of following lines to try
+ // to match back up.
+ static int numLines = 8; // The # of lines we're willing to match against.
+ RootInlineBox* line = endLine;
+ for (int i = 0; i < numLines && line; i++, line = line->nextRootBox()) {
+ if (line->lineBreakObj() == start.obj && line->lineBreakPos() == start.pos) {
+ // We have a match.
+ RootInlineBox* result = line->nextRootBox();
+
+ // Set our yPos to be the block height of endLine.
+ if (result)
+ endYPos = line->blockHeight();
+
+ // Now delete the lines that we failed to sync.
+ RootInlineBox* boxToDelete = endLine;
+ RenderArena* arena = renderArena();
+ while (boxToDelete && boxToDelete != result) {
+ RootInlineBox* next = boxToDelete->nextRootBox();
+ boxToDelete->deleteLine(arena);
+ boxToDelete = next;
+ }
+
+ endLine = result;
+ return result;
+ }
+ }
+ }
+ return false;
+}
+
BidiIterator RenderBlock::findNextLineBreak(BidiIterator &start, BidiState &bidi)
{
int width = lineWidth(m_height);
@@ -1473,9 +1685,9 @@ BidiIterator RenderBlock::findNextLineBreak(BidiIterator &start, BidiState &bidi
}
}
- adjustEmbeddding = true;
+ adjustEmbedding = true;
start.increment(bidi);
- adjustEmbeddding = false;
+ adjustEmbedding = false;
}
if ( start.atEnd() ){
@@ -1502,18 +1714,19 @@ BidiIterator RenderBlock::findNextLineBreak(BidiIterator &start, BidiState &bidi
RenderObject *last = o;
int pos = start.pos;
- bool prevLineBrokeCleanly = previousLineBrokeAtBR;
- previousLineBrokeAtBR = false;
+ bool prevLineBrokeCleanly = previousLineBrokeCleanly;
+ previousLineBrokeCleanly = false;
while( o ) {
#ifdef DEBUG_LINEBREAKS
kdDebug(6041) << "new object "<< o <<" width = " << w <<" tmpw = " << tmpW << endl;
#endif
if(o->isBR()) {
- if( w + tmpW <= width ) {
+ if (w + tmpW <= width) {
lBreak.obj = o;
lBreak.pos = 0;
-
+ lBreak.increment(bidi);
+
// A <br> always breaks a line, so don't let the line be collapsed
// away. Also, the space at the end of a line with a <br> does not
// get collapsed away. It only does this if the previous line broke
@@ -1522,7 +1735,7 @@ BidiIterator RenderBlock::findNextLineBreak(BidiIterator &start, BidiState &bidi
if (prevLineBrokeCleanly)
isLineEmpty = false;
trailingSpaceObject = 0;
- previousLineBrokeAtBR = true;
+ previousLineBrokeCleanly = true;
if (!isLineEmpty) {
// only check the clear status for non-empty lines.
@@ -1720,6 +1933,7 @@ BidiIterator RenderBlock::findNextLineBreak(BidiIterator &start, BidiState &bidi
if( *(str+pos) == '\n' && isPre) {
lBreak.obj = o;
lBreak.pos = pos;
+ previousLineBrokeCleanly = true;
#ifdef DEBUG_LINEBREAKS
kdDebug(6041) << "forced break sol: " << start.obj << " " << start.pos << " end: " << lBreak.obj << " " << lBreak.pos << " width=" << w << endl;
diff --git a/WebCore/khtml/rendering/render_block.cpp b/WebCore/khtml/rendering/render_block.cpp
index c910114..38e51fd 100644
--- a/WebCore/khtml/rendering/render_block.cpp
+++ b/WebCore/khtml/rendering/render_block.cpp
@@ -53,6 +53,7 @@ RenderBlock::RenderBlock(DOM::NodeImpl* node)
m_positionedObjects = 0;
m_pre = false;
m_firstLine = false;
+ m_linesAppended = false;
m_clearStatus = CNONE;
m_maxTopPosMargin = m_maxTopNegMargin = m_maxBottomPosMargin = m_maxBottomNegMargin = 0;
m_topMarginQuirk = m_bottomMarginQuirk = false;
@@ -434,8 +435,9 @@ void RenderBlock::layoutBlock(bool relayoutChildren)
}
// kdDebug( 6040 ) << "childrenInline()=" << childrenInline() << endl;
+ QRect repaintRect(0,0,0,0);
if (childrenInline())
- layoutInlineChildren( relayoutChildren );
+ repaintRect = layoutInlineChildren( relayoutChildren );
else
layoutBlockChildren( relayoutChildren );
@@ -495,9 +497,14 @@ void RenderBlock::layoutBlock(bool relayoutChildren)
m_layer->updateScrollInfoAfterLayout();
// Repaint with our new bounds if they are different from our old bounds.
+ bool didFullRepaint = false;
if (checkForRepaint)
- repaintAfterLayoutIfNeeded(oldBounds, oldFullBounds);
-
+ didFullRepaint = repaintAfterLayoutIfNeeded(oldBounds, oldFullBounds);
+ if (!didFullRepaint && !repaintRect.isEmpty()) {
+ RenderCanvas* c = canvas();
+ if (c && c->view())
+ c->view()->addRepaintInfo(this, repaintRect); // We need to do a partial repaint of our content.
+ }
setNeedsLayout(false);
}
@@ -967,7 +974,9 @@ void RenderBlock::layoutBlockChildren( bool relayoutChildren )
// to shift over as necessary to dodge any floats that might get in the way.
if (child->avoidsFloats()) {
int leftOff = leftOffset(m_height);
- if (leftOff != xPos) {
+ if (style()->textAlign() != KHTML_CENTER && child->style()->marginLeft().type != Variable)
+ chPos = kMax(chPos, leftOff); // Let the float sit in the child's margin if it can fit.
+ else if (leftOff != xPos) {
// The object is shifting right. The object might be centered, so we need to
// recalculate our horizontal margins. Note that the containing block content
// width computation will take into account the delta between |leftOff| and |xPos|
@@ -982,8 +991,23 @@ void RenderBlock::layoutBlockChildren( bool relayoutChildren )
}
} else {
chPos -= child->width() + child->marginRight();
- if (child->avoidsFloats())
- chPos -= (xPos - rightOffset(m_height));
+ if (child->avoidsFloats()) {
+ int rightOff = rightOffset(m_height);
+ if (style()->textAlign() != KHTML_CENTER && child->style()->marginRight().type != Variable)
+ chPos = kMin(chPos, rightOff - child->width()); // Let the float sit in the child's margin if it can fit.
+ else if (rightOff != xPos) {
+ // The object is shifting left. The object might be centered, so we need to
+ // recalculate our horizontal margins. Note that the containing block content
+ // width computation will take into account the delta between |rightOff| and |xPos|
+ // so that we can just pass the content width in directly to the |calcHorizontalMargins|
+ // function.
+ // -dwh
+ int cw = lineWidth( child->yPos() );
+ static_cast<RenderBox*>(child)->calcHorizontalMargins
+ ( child->style()->marginLeft(), child->style()->marginRight(), cw);
+ chPos = rightOff - child->marginRight() - child->width();
+ }
+ }
}
child->setPos(chPos, child->yPos());
@@ -1034,7 +1058,7 @@ void RenderBlock::layoutBlockChildren( bool relayoutChildren )
// If the child moved, we have to repaint it as well as any floating/positioned
// descendants. An exception is if we need a layout. In this case, we know we're going to
// repaint ourselves (and the child) anyway.
- if (!selfNeedsLayout() && checkForRepaintDuringLayout())
+ if (!selfNeedsLayout() && child->checkForRepaintDuringLayout())
child->repaintDuringLayoutIfMoved(oldChildX, oldChildY);
child = child->nextSibling();
@@ -1475,7 +1499,7 @@ void RenderBlock::positionNewFloats()
f->endY = f->startY + _height;
// If the child moved, we have to repaint it.
- if (checkForRepaintDuringLayout())
+ if (o->checkForRepaintDuringLayout())
o->repaintDuringLayoutIfMoved(oldChildX, oldChildY);
//kdDebug( 6040 ) << "floatingObject x/y= (" << f->left << "/" << f->startY << "-" << f->width << "/" << f->endY - f->startY << ")" << endl;
@@ -1638,7 +1662,7 @@ RenderBlock::lowestPosition(bool includeOverflowInterior, bool includeSelf) cons
QPtrListIterator<FloatingObject> it(*m_floatingObjects);
for ( ; (r = it.current()); ++it ) {
if (!r->noPaint) {
- int lp = r->startY + r->node->lowestPosition(false);
+ int lp = r->startY + r->node->marginTop() + r->node->lowestPosition(false);
bottom = kMax(bottom, lp);
}
}
@@ -1676,7 +1700,7 @@ int RenderBlock::rightmostPosition(bool includeOverflowInterior, bool includeSel
QPtrListIterator<FloatingObject> it(*m_floatingObjects);
for ( ; (r = it.current()); ++it ) {
if (!r->noPaint) {
- int rp = r->left + r->node->rightmostPosition(false);
+ int rp = r->left + r->node->marginLeft() + r->node->rightmostPosition(false);
right = kMax(right, rp);
}
}
@@ -1714,7 +1738,7 @@ int RenderBlock::leftmostPosition(bool includeOverflowInterior, bool includeSelf
QPtrListIterator<FloatingObject> it(*m_floatingObjects);
for ( ; (r = it.current()); ++it ) {
if (!r->noPaint) {
- int lp = r->left + r->node->leftmostPosition(false);
+ int lp = r->left + r->node->marginLeft() + r->node->leftmostPosition(false);
left = kMin(left, lp);
}
}
diff --git a/WebCore/khtml/rendering/render_block.h b/WebCore/khtml/rendering/render_block.h
index 1c7d4c3..49d73e2 100644
--- a/WebCore/khtml/rendering/render_block.h
+++ b/WebCore/khtml/rendering/render_block.h
@@ -102,7 +102,7 @@ public:
virtual void layout();
virtual void layoutBlock( bool relayoutChildren );
void layoutBlockChildren( bool relayoutChildren );
- void layoutInlineChildren( bool relayoutChildren );
+ QRect layoutInlineChildren( bool relayoutChildren );
void layoutPositionedObjects( bool relayoutChildren );
void insertPositionedObject(RenderObject *o);
@@ -113,11 +113,15 @@ public:
// the implementation of the following functions is in bidi.cpp
void bidiReorderLine(const BidiIterator &start, const BidiIterator &end, BidiState &bidi );
+ RootInlineBox* determineStartPosition(bool fullLayout, BidiIterator &start, BidiState &bidi);
+ RootInlineBox* determineEndPosition(RootInlineBox* startBox, BidiIterator& cleanLineStart, int& yPos);
+ bool matchedEndLine(const BidiIterator& start, const BidiIterator& endLineStart,
+ RootInlineBox*& endLine, int& endYPos);
BidiIterator findNextLineBreak(BidiIterator &start, BidiState &info );
- InlineFlowBox* constructLine(const BidiIterator& start, const BidiIterator& end);
+ RootInlineBox* constructLine(const BidiIterator& start, const BidiIterator& end);
InlineFlowBox* createLineBoxes(RenderObject* obj);
- void computeHorizontalPositionsForLine(InlineFlowBox* lineBox, BidiState &bidi);
- void computeVerticalPositionsForLine(InlineFlowBox* lineBox);
+ void computeHorizontalPositionsForLine(RootInlineBox* lineBox, BidiState &bidi);
+ void computeVerticalPositionsForLine(RootInlineBox* lineBox);
// end bidi.cpp functions
virtual void paint(PaintInfo& i, int tx, int ty);
@@ -171,6 +175,9 @@ public:
virtual int getBaselineOfFirstLineBox();
virtual InlineFlowBox* getFirstLineBox();
+ RootInlineBox* firstRootBox() { return static_cast<RootInlineBox*>(m_firstLineBox); }
+ RootInlineBox* lastRootBox() { return static_cast<RootInlineBox*>(m_lastLineBox); }
+
// overrides RenderObject
virtual bool requiresLayer();
@@ -181,6 +188,9 @@ public:
bool inRootBlockContext() const;
+ void setLinesAppended(bool b=true) { m_linesAppended = b; }
+ bool linesAppended() const { return m_linesAppended; }
+
#ifndef NDEBUG
virtual void printTree(int indent=0) const;
virtual void dump(QTextStream *stream, QString ind = "") const;
@@ -225,6 +235,7 @@ protected:
EClear m_clearStatus : 2; // used during layuting of paragraphs
bool m_topMarginQuirk : 1;
bool m_bottomMarginQuirk : 1;
+ bool m_linesAppended : 1; // Whether or not a block with inline children has had lines appended.
short m_maxTopPosMargin;
short m_maxTopNegMargin;
diff --git a/WebCore/khtml/rendering/render_box.cpp b/WebCore/khtml/rendering/render_box.cpp
index a5393c5..a3f9cb4 100644
--- a/WebCore/khtml/rendering/render_box.cpp
+++ b/WebCore/khtml/rendering/render_box.cpp
@@ -542,6 +542,19 @@ bool RenderBox::absolutePosition(int &xPos, int &yPos, bool f)
}
}
+void RenderBox::dirtyLineBoxes(bool fullLayout, bool)
+{
+ if (m_inlineBoxWrapper) {
+ if (fullLayout) {
+ m_inlineBoxWrapper->remove();
+ m_inlineBoxWrapper->detach(renderArena());
+ m_inlineBoxWrapper = 0;
+ }
+ else
+ m_inlineBoxWrapper->dirtyLineBoxes();
+ }
+}
+
void RenderBox::position(InlineBox* box, int from, int len, bool reverse)
{
if (isPositioned()) {
@@ -586,6 +599,11 @@ void RenderBox::deleteLineBoxWrapper()
m_inlineBoxWrapper->detach(renderArena());
}
+void RenderBox::setInlineBoxWrapper(InlineBox* b)
+{
+ m_inlineBoxWrapper = b;
+}
+
QRect RenderBox::getAbsoluteRepaintRect()
{
int ow = style() ? style()->outlineSize() : 0;
diff --git a/WebCore/khtml/rendering/render_box.h b/WebCore/khtml/rendering/render_box.h
index 8401afe..9dbd94e 100644
--- a/WebCore/khtml/rendering/render_box.h
+++ b/WebCore/khtml/rendering/render_box.h
@@ -83,10 +83,13 @@ public:
virtual void position(InlineBox* box, int from, int len, bool reverse);
+ virtual void dirtyLineBoxes(bool fullLayout, bool isRootLineBox=false);
+
// For inline replaced elements, this function returns the inline box that owns us. Enables
// the replaced RenderObject to quickly determine what line it is contained on and to easily
// iterate over structures on the line.
virtual InlineBox* inlineBoxWrapper() const;
+ virtual void setInlineBoxWrapper(InlineBox* b);
void deleteLineBoxWrapper();
virtual int lowestPosition(bool includeOverflowInterior=true, bool includeSelf=true) const;
diff --git a/WebCore/khtml/rendering/render_br.cpp b/WebCore/khtml/rendering/render_br.cpp
index c1ed931..e6fb2a0 100644
--- a/WebCore/khtml/rendering/render_br.cpp
+++ b/WebCore/khtml/rendering/render_br.cpp
@@ -34,6 +34,15 @@ RenderBR::~RenderBR()
{
}
+InlineBox* RenderBR::createInlineBox(bool makePlaceholder, bool isRootLineBox, bool isOnlyRun)
+{
+ // We only make a box for a <br> if we are on a line by ourself or in strict mode
+ // (Note the use of strict mode. In "almost strict" mode, we don't make a box for <br>.)
+ if (isOnlyRun || document()->inStrictMode())
+ return RenderText::createInlineBox(makePlaceholder, isRootLineBox, isOnlyRun);
+ return 0;
+}
+
void RenderBR::position(InlineBox* box, int from, int len, bool reverse)
{
InlineTextBox *s = static_cast<InlineTextBox*>(box);
@@ -42,10 +51,6 @@ void RenderBR::position(InlineBox* box, int from, int len, bool reverse)
m_x = s->xPos();
m_y = s->yPos();
m_height = s->height();
-
- s->remove();
- s->detach(renderArena());
- m_firstTextBox = m_lastTextBox = 0;
}
short RenderBR::lineHeight(bool firstLine, bool isRootLineBox) const
diff --git a/WebCore/khtml/rendering/render_br.h b/WebCore/khtml/rendering/render_br.h
index 180827c..decaf29 100644
--- a/WebCore/khtml/rendering/render_br.h
+++ b/WebCore/khtml/rendering/render_br.h
@@ -48,6 +48,7 @@ public:
virtual void setStyle(RenderStyle* _style);
// overrides
+ virtual InlineBox* createInlineBox(bool, bool, bool isOnlyRun = false);
virtual void calcMinMaxWidth() {}
virtual short minWidth() const { return 0; }
virtual short maxWidth() const { return 0; }
diff --git a/WebCore/khtml/rendering/render_container.cpp b/WebCore/khtml/rendering/render_container.cpp
index acb7990..3c45cd7 100644
--- a/WebCore/khtml/rendering/render_container.cpp
+++ b/WebCore/khtml/rendering/render_container.cpp
@@ -346,6 +346,9 @@ void RenderContainer::appendChildNode(RenderObject* newChild)
newChild->setNeedsLayoutAndMinMaxRecalc(); // Goes up the containing block hierarchy.
if (!normalChildNeedsLayout())
setChildNeedsLayout(true); // We may supply the static position for an absolute positioned child.
+
+ if (!newChild->isFloatingOrPositioned() && childrenInline())
+ dirtyLinesFromChangedChild(newChild);
}
void RenderContainer::insertChildNode(RenderObject* child, RenderObject* beforeChild)
@@ -378,6 +381,9 @@ void RenderContainer::insertChildNode(RenderObject* child, RenderObject* beforeC
child->setNeedsLayoutAndMinMaxRecalc();
if (!normalChildNeedsLayout())
setChildNeedsLayout(true); // We may supply the static position for an absolute positioned child.
+
+ if (!child->isFloatingOrPositioned() && childrenInline())
+ dirtyLinesFromChangedChild(child);
}
diff --git a/WebCore/khtml/rendering/render_flexbox.cpp b/WebCore/khtml/rendering/render_flexbox.cpp
index 0d38078..a67c750 100644
--- a/WebCore/khtml/rendering/render_flexbox.cpp
+++ b/WebCore/khtml/rendering/render_flexbox.cpp
@@ -921,7 +921,7 @@ void RenderFlexibleBox::placeChild(RenderObject* child, int x, int y)
// If the child moved, we have to repaint it as well as any floating/positioned
// descendants. An exception is if we need a layout. In this case, we know we're going to
// repaint ourselves (and the child) anyway.
- if (!selfNeedsLayout() && checkForRepaintDuringLayout())
+ if (!selfNeedsLayout() && child->checkForRepaintDuringLayout())
child->repaintDuringLayoutIfMoved(oldChildX, oldChildY);
}
diff --git a/WebCore/khtml/rendering/render_flow.cpp b/WebCore/khtml/rendering/render_flow.cpp
index c038de0..4a7713c 100644
--- a/WebCore/khtml/rendering/render_flow.cpp
+++ b/WebCore/khtml/rendering/render_flow.cpp
@@ -125,6 +125,46 @@ void RenderFlow::addChild(RenderObject *newChild, RenderObject *beforeChild)
return addChildToFlow(newChild, beforeChild);
}
+void RenderFlow::extractLineBox(InlineFlowBox* box)
+{
+ m_lastLineBox = box->prevFlowBox();
+ if (box == m_firstLineBox)
+ m_firstLineBox = 0;
+ if (box->prevLineBox())
+ box->prevLineBox()->setNextLineBox(0);
+ box->setPreviousLineBox(0);
+ for (InlineRunBox* curr = box; curr; curr = curr->nextLineBox())
+ curr->setExtracted();
+}
+
+void RenderFlow::attachLineBox(InlineFlowBox* box)
+{
+ if (m_lastLineBox) {
+ m_lastLineBox->setNextLineBox(box);
+ box->setPreviousLineBox(m_lastLineBox);
+ }
+ else
+ m_firstLineBox = box;
+ InlineFlowBox* last = box;
+ for (InlineFlowBox* curr = box; curr; curr = curr->nextFlowBox()) {
+ curr->setExtracted(false);
+ last = curr;
+ }
+ m_lastLineBox = last;
+}
+
+void RenderFlow::removeLineBox(InlineFlowBox* box)
+{
+ if (box == m_firstLineBox)
+ m_firstLineBox = box->nextFlowBox();
+ if (box == m_lastLineBox)
+ m_lastLineBox = box->prevFlowBox();
+ if (box->nextLineBox())
+ box->nextLineBox()->setPreviousLineBox(box->prevLineBox());
+ if (box->prevLineBox())
+ box->prevLineBox()->setNextLineBox(box->nextLineBox());
+}
+
void RenderFlow::deleteLineBoxes()
{
if (m_firstLineBox) {
@@ -151,6 +191,63 @@ void RenderFlow::detach()
RenderBox::detach();
}
+void RenderFlow::dirtyLinesFromChangedChild(RenderObject* child)
+{
+ if (!parent() || selfNeedsLayout() || isTable())
+ return;
+
+ if (!isInline() && (!child->nextSibling() || !firstLineBox())) {
+ // An append onto the end of a block or we don't have any lines anyway.
+ // In this case we don't have to dirty any specific lines.
+ static_cast<RenderBlock*>(this)->setLinesAppended();
+ return;
+ }
+
+ // For an empty inline, go ahead and propagate the check up to our parent.
+ if (isInline() && !firstLineBox())
+ return parent()->dirtyLinesFromChangedChild(this);
+
+ // Try to figure out which line box we belong in. First try to find a previous
+ // line box by examining our siblings. If we didn't find a line box, then use our
+ // parent's first line box.
+ RootInlineBox* box = 0;
+ for (RenderObject* curr = child->previousSibling(); curr; curr = curr->previousSibling()) {
+ if (curr->isFloatingOrPositioned())
+ continue;
+
+ if (curr->isReplaced()) {
+ InlineBox* wrapper = curr->inlineBoxWrapper();
+ if (wrapper)
+ box = wrapper->root();
+ }
+ else if (curr->isText()) {
+ InlineTextBox* textBox = static_cast<RenderText*>(curr)->lastTextBox();
+ if (textBox)
+ box = textBox->root();
+ }
+ else if (curr->isInlineFlow()) {
+ InlineRunBox* runBox = static_cast<RenderFlow*>(curr)->lastLineBox();
+ if (runBox)
+ box = runBox->root();
+ }
+
+ if (box)
+ break;
+ }
+ if (!box)
+ box = lastLineBox()->root();
+
+ // If we found a line box, then dirty it.
+ if (box) {
+ box->markDirty();
+ if (child->isBR()) {
+ RootInlineBox* next = box->nextRootBox();
+ if (next)
+ next->markDirty();
+ }
+ }
+}
+
short RenderFlow::lineHeight(bool firstLine, bool isRootLineBox) const
{
if (firstLine) {
@@ -174,7 +271,20 @@ short RenderFlow::lineHeight(bool firstLine, bool isRootLineBox) const
return m_lineHeight;
}
-InlineBox* RenderFlow::createInlineBox(bool makePlaceHolderBox, bool isRootLineBox)
+void RenderFlow::dirtyLineBoxes(bool fullLayout, bool isRootLineBox)
+{
+ if (!isRootLineBox && isReplaced())
+ return RenderBox::dirtyLineBoxes(isRootLineBox);
+
+ if (fullLayout)
+ deleteLineBoxes();
+ else {
+ for (InlineRunBox* curr = firstLineBox(); curr; curr = curr->nextLineBox())
+ curr->dirtyLineBoxes();
+ }
+}
+
+InlineBox* RenderFlow::createInlineBox(bool makePlaceHolderBox, bool isRootLineBox, bool isOnlyRun)
{
if (!isRootLineBox &&
(isReplaced() || makePlaceHolderBox)) // Inline tables and inline blocks
diff --git a/WebCore/khtml/rendering/render_flow.h b/WebCore/khtml/rendering/render_flow.h
index a2d0daa..3076f7f 100644
--- a/WebCore/khtml/rendering/render_flow.h
+++ b/WebCore/khtml/rendering/render_flow.h
@@ -56,16 +56,22 @@ public:
static RenderFlow* createAnonymousFlow(DOM::DocumentImpl* doc, RenderStyle* style);
+ void extractLineBox(InlineFlowBox* lineBox);
+ void attachLineBox(InlineFlowBox* lineBox);
+ void removeLineBox(InlineFlowBox* lineBox);
void deleteLineBoxes();
virtual void detach();
+ virtual void dirtyLinesFromChangedChild(RenderObject* child);
+
virtual short lineHeight(bool firstLine, bool isRootLineBox=false) const;
InlineFlowBox* firstLineBox() const { return m_firstLineBox; }
InlineFlowBox* lastLineBox() const { return m_lastLineBox; }
- virtual InlineBox* createInlineBox(bool makePlaceHolderBox, bool isRootLineBox);
-
+ virtual InlineBox* createInlineBox(bool makePlaceHolderBox, bool isRootLineBox, bool isOnlyRun=false);
+ virtual void dirtyLineBoxes(bool fullLayout, bool isRootLineBox = false);
+
void paintLineBoxBackgroundBorder(PaintInfo& i, int _tx, int _ty);
void paintLineBoxDecorations(PaintInfo& i, int _tx, int _ty);
diff --git a/WebCore/khtml/rendering/render_line.cpp b/WebCore/khtml/rendering/render_line.cpp
index fc3ce0f..fdce20b 100644
--- a/WebCore/khtml/rendering/render_line.cpp
+++ b/WebCore/khtml/rendering/render_line.cpp
@@ -90,6 +90,66 @@ long InlineBox::caretMaxOffset() const
return 1;
}
+void InlineBox::dirtyLineBoxes()
+{
+ markDirty();
+ for (InlineFlowBox* curr = parent(); curr && !curr->isDirty(); curr = curr->parent())
+ curr->markDirty();
+}
+
+void InlineBox::deleteLine(RenderArena* arena)
+{
+ detach(arena);
+}
+
+void InlineBox::extractLine()
+{
+ m_extracted = true;
+ m_object->setInlineBoxWrapper(0);
+}
+
+void InlineBox::attachLine()
+{
+ m_extracted = false;
+ m_object->setInlineBoxWrapper(this);
+}
+
+void InlineBox::adjustVerticalPosition(int delta)
+{
+ m_y += delta;
+ if (m_object->isReplaced() || m_object->isBR())
+ m_object->setPos(m_object->xPos(), m_object->yPos() + delta);
+}
+
+RootInlineBox* InlineBox::root()
+{
+ if (m_parent)
+ return m_parent->root();
+ return static_cast<RootInlineBox*>(this);
+}
+
+bool InlineBox::nextOnLineExists() const
+{
+ if (!parent())
+ return false;
+
+ if (nextOnLine())
+ return true;
+
+ return parent()->nextOnLineExists();
+}
+
+bool InlineBox::prevOnLineExists() const
+{
+ if (!parent())
+ return false;
+
+ if (prevOnLine())
+ return true;
+
+ return parent()->prevOnLineExists();
+}
+
int InlineFlowBox::marginLeft()
{
if (!includeLeftEdge())
@@ -136,6 +196,12 @@ int InlineFlowBox::getFlowSpacingWidth()
void InlineFlowBox::removeChild(InlineBox* child)
{
+ if (!m_dirty)
+ dirtyLineBoxes();
+
+ if (!child->nextOnLineExists())
+ child->root()->childRemoved(child);
+
if (child == m_firstChild)
m_firstChild = child->nextOnLine();
if (child == m_lastChild)
@@ -146,26 +212,41 @@ void InlineFlowBox::removeChild(InlineBox* child)
child->prevOnLine()->setNextOnLine(child->nextOnLine());
}
-bool InlineFlowBox::nextOnLineExists()
+void InlineFlowBox::deleteLine(RenderArena* arena)
{
- if (!parent())
- return false;
-
- if (nextOnLine())
- return true;
-
- return parent()->nextOnLineExists();
+ InlineBox* child = m_firstChild;
+ InlineBox* next = 0;
+ while (child) {
+ next = child->nextOnLine();
+ child->deleteLine(arena);
+ child = next;
+ }
+
+ static_cast<RenderFlow*>(m_object)->removeLineBox(this);
+ detach(arena);
}
-bool InlineFlowBox::prevOnLineExists()
+void InlineFlowBox::extractLine()
{
- if (!parent())
- return false;
+ if (!m_extracted)
+ static_cast<RenderFlow*>(m_object)->extractLineBox(this);
+ for (InlineBox* child = m_firstChild; child; child = child->nextOnLine())
+ child->extractLine();
+}
- if (prevOnLine())
- return true;
+void InlineFlowBox::attachLine()
+{
+ if (m_extracted)
+ static_cast<RenderFlow*>(m_object)->attachLineBox(this);
+ for (InlineBox* child = m_firstChild; child; child = child->nextOnLine())
+ child->attachLine();
+}
- return parent()->prevOnLineExists();
+void InlineFlowBox::adjustVerticalPosition(int delta)
+{
+ InlineRunBox::adjustVerticalPosition(delta);
+ for (InlineBox* child = m_firstChild; child; child = child->nextOnLine())
+ child->adjustVerticalPosition(delta);
}
bool InlineFlowBox::onEndChain(RenderObject* endObject)
@@ -316,7 +397,7 @@ void InlineFlowBox::verticallyAlignBoxes(int& heightOfBlock)
computeLogicalBoxHeights(maxPositionTop, maxPositionBottom, maxAscent, maxDescent, strictMode);
- if (maxAscent + maxDescent < QMAX(maxPositionTop, maxPositionBottom))
+ if (maxAscent + maxDescent < kMax(maxPositionTop, maxPositionBottom))
adjustMaxAscentAndDescent(maxAscent, maxDescent, maxPositionTop, maxPositionBottom);
int maxHeight = maxAscent + maxDescent;
@@ -351,7 +432,7 @@ void InlineFlowBox::adjustMaxAscentAndDescent(int& maxAscent, int& maxDescent,
maxAscent = curr->height() - maxDescent;
}
- if ( maxAscent + maxDescent >= QMAX( maxPositionTop, maxPositionBottom ) )
+ if (maxAscent + maxDescent >= kMax(maxPositionTop, maxPositionBottom))
break;
}
@@ -631,3 +712,24 @@ void InlineFlowBox::paintDecorations(RenderObject::PaintInfo& i, int _tx, int _t
#endif
}
}
+
+void RootInlineBox::adjustVerticalPosition(int delta)
+{
+ InlineFlowBox::adjustVerticalPosition(delta);
+ m_topOverflow += delta;
+ m_bottomOverflow += delta;
+ m_blockHeight += delta;
+}
+
+void RootInlineBox::childRemoved(InlineBox* box)
+{
+ if (box->object() == m_lineBreakObj)
+ setLineBreakInfo(0,0);
+
+ RootInlineBox* prev = prevRootBox();
+ if (prev && prev->lineBreakObj() == box->object()) {
+ prev->setLineBreakInfo(0,0);
+ prev->markDirty();
+ }
+}
+
diff --git a/WebCore/khtml/rendering/render_line.h b/WebCore/khtml/rendering/render_line.h
index abadd9b..5cc07a5 100644
--- a/WebCore/khtml/rendering/render_line.h
+++ b/WebCore/khtml/rendering/render_line.h
@@ -27,7 +27,8 @@
namespace khtml {
class InlineFlowBox;
-
+class RootInlineBox;
+
// InlineBox represents a rectangle that occurs on a line. It corresponds to
// some RenderObject (i.e., it represents a portion of that RenderObject).
class InlineBox
@@ -35,7 +36,7 @@ class InlineBox
public:
InlineBox(RenderObject* obj)
:m_object(obj), m_x(0), m_y(0), m_width(0), m_height(0), m_baseline(0),
- m_firstLine(false), m_constructed(false)
+ m_firstLine(false), m_constructed(false), m_dirty(false), m_extracted(false)
{
m_next = 0;
m_prev = 0;
@@ -46,6 +47,12 @@ public:
void detach(RenderArena* renderArena);
+ virtual void deleteLine(RenderArena* arena);
+ virtual void extractLine();
+ virtual void attachLine();
+
+ virtual void adjustVerticalPosition(int delta);
+
// Overloaded new operator.
void* operator new(size_t sz, RenderArena* renderArena) throw();
@@ -69,7 +76,8 @@ public:
if (m_next)
m_next->setConstructed();
}
-
+ void setExtracted(bool b = true) { m_extracted = b; }
+
void setFirstLineStyleBit(bool f) { m_firstLine = f; }
bool isFirstLineStyle() const { return m_firstLine; }
@@ -79,12 +87,16 @@ public:
InlineBox* prevOnLine() const { return m_prev; }
void setNextOnLine(InlineBox* next) { m_next = next; }
void setPrevOnLine(InlineBox* prev) { m_prev = prev; }
+ bool nextOnLineExists() const;
+ bool prevOnLineExists() const;
- RenderObject* object() { return m_object; }
+ RenderObject* object() const { return m_object; }
- InlineFlowBox* parent() { return m_parent; }
+ InlineFlowBox* parent() const { return m_parent; }
void setParent(InlineFlowBox* par) { m_parent = par; }
+ RootInlineBox* root();
+
void setWidth(short w) { m_width = w; }
short width() { return m_width; }
@@ -108,6 +120,11 @@ public:
virtual long caretMinOffset() const;
virtual long caretMaxOffset() const;
+ bool isDirty() const { return m_dirty; }
+ void markDirty(bool dirty=true) { m_dirty = dirty; }
+
+ void dirtyLineBoxes();
+
public: // FIXME: Would like to make this protected, but methods are accessing these
// members over in the part.
RenderObject* m_object;
@@ -120,6 +137,8 @@ public: // FIXME: Would like to make this protected, but methods are accessing t
bool m_firstLine : 1;
bool m_constructed : 1;
+ bool m_dirty : 1;
+ bool m_extracted : 1;
InlineBox* m_next; // The next element on the same line as us.
InlineBox* m_prev; // The previous element on the same line as us.
@@ -164,6 +183,9 @@ public:
virtual bool isInlineFlowBox() { return true; }
+ InlineFlowBox* prevFlowBox() const { return static_cast<InlineFlowBox*>(m_prevLine); }
+ InlineFlowBox* nextFlowBox() const { return static_cast<InlineFlowBox*>(m_nextLine); }
+
InlineBox* firstChild() { return m_firstChild; }
InlineBox* lastChild() { return m_lastChild; }
@@ -186,6 +208,11 @@ public:
m_hasTextChildren = true;
}
+ virtual void deleteLine(RenderArena* arena);
+ virtual void extractLine();
+ virtual void attachLine();
+ virtual void adjustVerticalPosition(int delta);
+
virtual void paintBackgroundAndBorder(RenderObject::PaintInfo& i, int _tx, int _ty, int xOffsetOnLine);
virtual void paintDecorations(RenderObject::PaintInfo& i, int _tx, int _ty);
@@ -209,8 +236,6 @@ public:
// Helper functions used during line construction and placement.
void determineSpacingForFlowBoxes(bool lastLine, RenderObject* endObject);
int getFlowSpacingWidth();
- bool nextOnLineExists();
- bool prevOnLineExists();
bool onEndChain(RenderObject* endObject);
int placeBoxesHorizontally(int x);
void verticallyAlignBoxes(int& heightOfBlock);
@@ -238,19 +263,51 @@ class RootInlineBox : public InlineFlowBox
{
public:
RootInlineBox(RenderObject* obj)
- :InlineFlowBox(obj)
- {
- m_topOverflow = m_bottomOverflow = 0;
- }
+ : InlineFlowBox(obj), m_topOverflow(0), m_bottomOverflow(0), m_lineBreakObj(0), m_lineBreakPos(0),
+ m_blockHeight(0), m_endsWithBreak(false)
+ {}
+
+ RootInlineBox* nextRootBox() { return static_cast<RootInlineBox*>(m_nextLine); }
+ RootInlineBox* prevRootBox() { return static_cast<RootInlineBox*>(m_prevLine); }
+
+ virtual void adjustVerticalPosition(int delta);
virtual bool isRootInlineBox() { return true; }
virtual int topOverflow() { return m_topOverflow; }
virtual int bottomOverflow() { return m_bottomOverflow; }
virtual void setOverflowPositions(int top, int bottom) { m_topOverflow = top; m_bottomOverflow = bottom; }
+ void setLineBreakInfo(RenderObject* obj, uint breakPos)
+ { m_lineBreakObj = obj; m_lineBreakPos = breakPos; }
+ void setLineBreakPos(int p) { m_lineBreakPos = p; }
+
+ void setBlockHeight(int h) { m_blockHeight = h; }
+ void setEndsWithBreak(bool b) { m_endsWithBreak = b; }
+
+ int blockHeight() const { return m_blockHeight; }
+ bool endsWithBreak() const { return m_endsWithBreak; }
+ RenderObject* lineBreakObj() const { return m_lineBreakObj; }
+ uint lineBreakPos() const { return m_lineBreakPos; }
+
+ void childRemoved(InlineBox* box);
+
protected:
+ // Normally we are only as tall as the style on our block dictates, but we might have content
+ // that spills out above the height of our font (e.g, a tall image), or something that extends further
+ // below our line (e.g., a child whose font has a huge descent).
int m_topOverflow;
int m_bottomOverflow;
+
+ // Where this line ended. The exact object and the position within that object are stored so that
+ // we can create a BidiIterator beginning just after the end of this line.
+ RenderObject* m_lineBreakObj;
+ uint m_lineBreakPos;
+
+ // The height of the block at the end of this line. This is where the next line starts.
+ int m_blockHeight;
+
+ // Whether the line ends with a <br>.
+ bool m_endsWithBreak;
};
}; //namespace
diff --git a/WebCore/khtml/rendering/render_object.cpp b/WebCore/khtml/rendering/render_object.cpp
index 2af72e5..c6c1b31 100644
--- a/WebCore/khtml/rendering/render_object.cpp
+++ b/WebCore/khtml/rendering/render_object.cpp
@@ -1154,21 +1154,23 @@ void RenderObject::repaintRectangle(const QRect& r, bool immediate)
c->repaintViewRectangle(absRect, immediate);
}
-void RenderObject::repaintAfterLayoutIfNeeded(const QRect& oldBounds, const QRect& oldFullBounds)
+bool RenderObject::repaintAfterLayoutIfNeeded(const QRect& oldBounds, const QRect& oldFullBounds)
{
QRect newBounds, newFullBounds;
getAbsoluteRepaintRectIncludingFloats(newBounds, newFullBounds);
if (newBounds != oldBounds || selfNeedsLayout()) {
RenderObject* c = canvas();
if (!c || !c->isCanvas())
- return;
+ return false;
RenderCanvas* canvasObj = static_cast<RenderCanvas*>(c);
if (canvasObj->printingMode())
- return; // Don't repaint if we're printing.
+ return false; // Don't repaint if we're printing.
canvasObj->repaintViewRectangle(oldFullBounds);
if (newBounds != oldBounds)
canvasObj->repaintViewRectangle(newFullBounds);
+ return true;
}
+ return false;
}
void RenderObject::repaintDuringLayoutIfMoved(int x, int y)
@@ -1189,10 +1191,8 @@ void RenderObject::repaintObjectsBeforeLayout()
if (!needsLayout() || isText())
return;
- // FIXME: For now we just always repaint blocks with inline children, regardless of whether
- // they're really dirty or not.
bool blockWithInlineChildren = (isRenderBlock() && !isTable() && normalChildNeedsLayout() && childrenInline());
- if (selfNeedsLayout() || blockWithInlineChildren) {
+ if (selfNeedsLayout()) {
repaint();
if (blockWithInlineChildren)
return;
@@ -1242,6 +1242,10 @@ void RenderObject::computeAbsoluteRepaintRect(QRect& r, bool f)
return parent()->computeAbsoluteRepaintRect(r, f);
}
+void RenderObject::dirtyLinesFromChangedChild(RenderObject* child)
+{
+}
+
#ifndef NDEBUG
QString RenderObject::information() const
@@ -1995,19 +1999,28 @@ void RenderObject::removeLeftoverAnonymousBoxes()
{
}
-InlineBox* RenderObject::createInlineBox(bool,bool isRootLineBox)
+InlineBox* RenderObject::createInlineBox(bool, bool isRootLineBox, bool)
{
KHTMLAssert(!isRootLineBox);
return new (renderArena()) InlineBox(this);
}
+void RenderObject::dirtyLineBoxes(bool, bool)
+{
+}
+
InlineBox* RenderObject::inlineBoxWrapper() const
{
return 0;
}
+void RenderObject::setInlineBoxWrapper(InlineBox* b)
+{
+}
+
void RenderObject::deleteLineBoxWrapper()
-{}
+{
+}
RenderStyle* RenderObject::style(bool firstLine) const {
RenderStyle *s = m_style;
diff --git a/WebCore/khtml/rendering/render_object.h b/WebCore/khtml/rendering/render_object.h
index 0881baf..83f291f 100644
--- a/WebCore/khtml/rendering/render_object.h
+++ b/WebCore/khtml/rendering/render_object.h
@@ -322,12 +322,14 @@ public:
void scheduleRelayout();
- virtual InlineBox* createInlineBox(bool makePlaceHolderBox, bool isRootLineBox);
+ virtual InlineBox* createInlineBox(bool makePlaceHolderBox, bool isRootLineBox, bool isOnlyRun=false);
+ virtual void dirtyLineBoxes(bool fullLayout, bool isRootLineBox=false);
// For inline replaced elements, this function returns the inline box that owns us. Enables
// the replaced RenderObject to quickly determine what line it is contained on and to easily
// iterate over structures on the line.
virtual InlineBox* inlineBoxWrapper() const;
+ virtual void setInlineBoxWrapper(InlineBox* b);
void deleteLineBoxWrapper();
// for discussion of lineHeight see CSS2 spec
@@ -454,11 +456,22 @@ public:
bool m_active;
};
+ // Used to signal a specific subrect within an object that must be repainted after
+ // layout is complete.
+ struct RepaintInfo {
+ RenderObject* m_object;
+ QRect m_repaintRect;
+
+ RepaintInfo(RenderObject* o, const QRect& r) :m_object(o), m_repaintRect(r) {}
+ };
+
FindSelectionResult checkSelectionPoint(int x, int y, int tx, int ty, DOM::NodeImpl*&, int& offset);
virtual FindSelectionResult checkSelectionPointIgnoringContinuations(int x, int y, int tx, int ty, DOM::NodeImpl*&, int& offset);
virtual bool nodeAtPoint(NodeInfo& info, int x, int y, int tx, int ty,
HitTestAction hitTestAction = HitTestAll, bool inside=false);
+ virtual void dirtyLinesFromChangedChild(RenderObject* child);
+
// set the style of the object.
virtual void setStyle(RenderStyle *style);
@@ -611,7 +624,7 @@ public:
void repaintRectangle(const QRect& r, bool immediate = false);
// Repaint only if our old bounds and new bounds are different.
- virtual void repaintAfterLayoutIfNeeded(const QRect& oldBounds, const QRect& oldFullBounds);
+ bool repaintAfterLayoutIfNeeded(const QRect& oldBounds, const QRect& oldFullBounds);
// Repaint only if the object moved.
virtual void repaintDuringLayoutIfMoved(int oldX, int oldY);
diff --git a/WebCore/khtml/rendering/render_table.cpp b/WebCore/khtml/rendering/render_table.cpp
index 5bb51b7..432c3bd 100644
--- a/WebCore/khtml/rendering/render_table.cpp
+++ b/WebCore/khtml/rendering/render_table.cpp
@@ -1367,7 +1367,7 @@ int RenderTableSection::layoutRows( int toAdd )
// If the cell moved, we have to repaint it as well as any floating/positioned
// descendants. An exception is if we need a layout. In this case, we know we're going to
// repaint ourselves (and the cell) anyway.
- if (!table()->selfNeedsLayout() && checkForRepaintDuringLayout())
+ if (!table()->selfNeedsLayout() && cell->checkForRepaintDuringLayout())
cell->repaintDuringLayoutIfMoved(oldCellX, oldCellY);
}
}
diff --git a/WebCore/khtml/rendering/render_text.cpp b/WebCore/khtml/rendering/render_text.cpp
index ca32c83..6bde190 100644
--- a/WebCore/khtml/rendering/render_text.cpp
+++ b/WebCore/khtml/rendering/render_text.cpp
@@ -71,6 +71,28 @@ void InlineTextBox::operator delete(void* ptr, size_t sz)
*(size_t *)ptr = sz;
}
+void InlineTextBox::deleteLine(RenderArena* arena)
+{
+ static_cast<RenderText*>(m_object)->removeTextBox(this);
+ detach(arena);
+}
+
+void InlineTextBox::extractLine()
+{
+ if (m_extracted)
+ return;
+
+ static_cast<RenderText*>(m_object)->extractTextBox(this);
+}
+
+void InlineTextBox::attachLine()
+{
+ if (!m_extracted)
+ return;
+
+ static_cast<RenderText*>(m_object)->attachTextBox(this);
+}
+
void InlineTextBox::paintSelection(const Font *f, RenderText *text, QPainter *p, RenderStyle* style, int tx, int ty, int startPos, int endPos)
{
if(startPos > m_len) return;
@@ -237,7 +259,7 @@ FindSelectionResult InlineTextBox::checkSelectionPoint(int _x, int _y, int _tx,
// -------------------------------------------------------------------------------------
RenderText::RenderText(DOM::NodeImpl* node, DOMStringImpl *_str)
- : RenderObject(node)
+ : RenderObject(node), m_linesDirty(false)
{
// init RenderObject attributes
setRenderText(); // our object inherits from RenderText
@@ -297,13 +319,56 @@ RenderText::~RenderText()
void RenderText::detach()
{
if (!documentBeingDestroyed()) {
- for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox())
- box->remove();
+ if (firstTextBox())
+ for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox())
+ box->remove();
+ else if (parent() && isBR())
+ parent()->dirtyLinesFromChangedChild(this);
}
deleteTextBoxes();
RenderObject::detach();
}
+void RenderText::extractTextBox(InlineTextBox* box)
+{
+ m_lastTextBox = box->prevTextBox();
+ if (box == m_firstTextBox)
+ m_firstTextBox = 0;
+ if (box->prevTextBox())
+ box->prevTextBox()->setNextLineBox(0);
+ box->setPreviousLineBox(0);
+ for (InlineRunBox* curr = box; curr; curr = curr->nextLineBox())
+ curr->setExtracted();
+}
+
+void RenderText::attachTextBox(InlineTextBox* box)
+{
+ if (m_lastTextBox) {
+ m_lastTextBox->setNextLineBox(box);
+ box->setPreviousLineBox(m_lastTextBox);
+ }
+ else
+ m_firstTextBox = box;
+ InlineTextBox* last = box;
+ for (InlineTextBox* curr = box; curr; curr = curr->nextTextBox()) {
+ curr->setExtracted(false);
+ last = curr;
+ }
+ m_lastTextBox = last;
+}
+
+void RenderText::removeTextBox(InlineTextBox* box)
+{
+ if (box == m_firstTextBox)
+ m_firstTextBox = box->nextTextBox();
+ if (box == m_lastTextBox)
+ m_lastTextBox = box->prevTextBox();
+ if (box->nextTextBox())
+ box->nextTextBox()->setPreviousLineBox(box->prevTextBox());
+ if (box->prevTextBox())
+ box->prevTextBox()->setNextLineBox(box->nextTextBox());
+}
+
void RenderText::deleteTextBoxes()
{
if (firstTextBox()) {
@@ -1116,14 +1181,64 @@ const QFont &RenderText::font()
return style()->font();
}
+void RenderText::setTextWithOffset(DOMStringImpl *text, uint offset, uint len, bool force)
+{
+ uint oldLen = str ? str->l : 0;
+ uint newLen = text ? text->l : 0;
+ uint delta = newLen - oldLen;
+ uint end = len ? offset+len-1 : offset;
+
+ RootInlineBox* firstRootBox = 0;
+ RootInlineBox* lastRootBox = 0;
+
+ // Dirty all text boxes that include characters in between offset and offset+len.
+ for (InlineTextBox* curr = firstTextBox(); curr; curr = curr->nextTextBox()) {
+ // Text run is entirely before the affected range.
+ if (curr->end() < offset)
+ continue;
+
+ // Text run is entirely after the affected range.
+ if (curr->start() > end) {
+ curr->offsetRun(delta);
+ RootInlineBox* root = curr->root();
+ if (!firstRootBox)
+ firstRootBox = root;
+ lastRootBox = root;
+ }
+ else if (curr->end() >= offset && curr->end() <= end)
+ curr->dirtyLineBoxes(); // Text run overlaps with the left end of the affected range.
+ else if (curr->start() <= offset && curr->end() >= end)
+ curr->dirtyLineBoxes(); // Text run subsumes the affected range.
+ else if (curr->start() <= end && curr->end() >= end)
+ curr->dirtyLineBoxes(); // Text run overlaps with right end of the affected range.
+ }
+
+ // Now we have to walk all of the clean lines and adjust their cached line break information
+ // to reflect our updated offsets.
+ if (lastRootBox)
+ lastRootBox = lastRootBox->nextRootBox();
+ if (firstRootBox) {
+ RootInlineBox* prev = firstRootBox->prevRootBox();
+ if (prev)
+ firstRootBox = prev;
+ }
+ for (RootInlineBox* curr = firstRootBox; curr && curr != lastRootBox; curr = curr->nextRootBox()) {
+ if (curr->lineBreakObj() == this && curr->lineBreakPos() >= end)
+ curr->setLineBreakPos(curr->lineBreakPos()+delta);
+ }
+
+ m_linesDirty = true;
+ setText(text, force);
+}
+
void RenderText::setText(DOMStringImpl *text, bool force)
{
-#if APPLE_CHANGES
if (!text)
return;
-#endif
- if( !force && str == text ) return;
- if(str) str->deref();
+ if (!force && str == text)
+ return;
+ if (str)
+ str->deref();
str = text;
if (str) {
@@ -1143,6 +1258,7 @@ void RenderText::setText(DOMStringImpl *text, bool force)
#if APPLE_CHANGES
cacheWidths();
#endif
+
// ### what should happen if we change the text of a
// RenderBR object ?
KHTMLAssert(!isBR() || (str->l == 1 && (*str->s) == '\n'));
@@ -1178,7 +1294,18 @@ short RenderText::baselinePosition( bool firstLine, bool ) const
( lineHeight( firstLine ) - fm.height() ) / 2;
}
-InlineBox* RenderText::createInlineBox(bool, bool isRootLineBox)
+void RenderText::dirtyLineBoxes(bool fullLayout, bool)
+{
+ if (fullLayout)
+ deleteTextBoxes();
+ else if (!m_linesDirty) {
+ for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox())
+ box->dirtyLineBoxes();
+ }
+ m_linesDirty = false;
+}
+
+InlineBox* RenderText::createInlineBox(bool, bool isRootLineBox, bool)
{
KHTMLAssert(!isRootLineBox);
InlineTextBox* textBox = new (renderArena()) InlineTextBox(this);
diff --git a/WebCore/khtml/rendering/render_text.h b/WebCore/khtml/rendering/render_text.h
index 3fd9b90..02fc1a6 100644
--- a/WebCore/khtml/rendering/render_text.h
+++ b/WebCore/khtml/rendering/render_text.h
@@ -56,8 +56,17 @@ public:
InlineTextBox* nextTextBox() const { return static_cast<InlineTextBox*>(nextLineBox()); }
InlineTextBox* prevTextBox() const { return static_cast<InlineTextBox*>(prevLineBox()); }
+ uint start() const { return m_start; }
+ uint end() const { return m_len ? m_start+m_len-1 : m_start; }
+
+ void offsetRun(int d) { m_start += d; }
+
void detach(RenderArena* arena);
+ virtual void deleteLine(RenderArena* arena);
+ virtual void extractLine();
+ virtual void attachLine();
+
// Overloaded new operator. Derived classes must override operator new
// in order to allocate out of the RenderArena.
void* operator new(size_t sz, RenderArena* renderArena) throw();
@@ -118,13 +127,17 @@ public:
virtual void paint(PaintInfo& i, int tx, int ty);
+ void extractTextBox(InlineTextBox* textBox);
+ void attachTextBox(InlineTextBox* textBox);
+ void removeTextBox(InlineTextBox* textBox);
void deleteTextBoxes();
virtual void detach();
DOM::DOMString data() const { return str; }
DOM::DOMStringImpl *string() const { return str; }
- virtual InlineBox* createInlineBox(bool,bool);
+ virtual InlineBox* createInlineBox(bool,bool, bool isOnlyRun = false);
+ virtual void dirtyLineBoxes(bool fullLayout, bool isRootInlineBox = false);
virtual void layout() {assert(false);}
@@ -176,6 +189,7 @@ public:
bool isFixedWidthFont() const;
void setText(DOM::DOMStringImpl *text, bool force=false);
+ void setTextWithOffset(DOM::DOMStringImpl *text, uint offset, uint len, bool force=false);
virtual SelectionState selectionState() const {return m_selectionState;}
virtual void setSelectionState(SelectionState s) {m_selectionState = s; }
@@ -230,7 +244,12 @@ protected: // members
bool m_hasBeginWS : 1; // Whether or not we begin with WS (only true if we aren't pre)
bool m_hasEndWS : 1; // Whether or not we end with WS (only true if we aren't pre)
- // 19 bits left
+ bool m_linesDirty : 1; // This bit indicates that the text run has already dirtied specific
+ // line boxes, and this hint will enable layoutInlineChildren to avoid
+ // just dirtying everything when character data is modified (e.g., appended/inserted
+ // or removed).
+
+ // 22 bits left
#if APPLE_CHANGES
mutable bool m_allAsciiChecked:1;
mutable bool m_allAscii:1;
diff --git a/WebCore/khtml/xml/dom_nodeimpl.cpp b/WebCore/khtml/xml/dom_nodeimpl.cpp
index 8d1a67c..56d8dcb 100644
--- a/WebCore/khtml/xml/dom_nodeimpl.cpp
+++ b/WebCore/khtml/xml/dom_nodeimpl.cpp
@@ -1586,6 +1586,8 @@ void NodeBaseImpl::removeChildren()
next = n->nextSibling();
if (n->attached())
n->detach();
+ if (n->inDocument())
+ n->removedFromDocument();
n->setPreviousSibling(0);
n->setNextSibling(0);
n->setParent(0);
@@ -1771,6 +1773,20 @@ void NodeBaseImpl::detach()
NodeImpl::detach();
}
+void NodeBaseImpl::insertedIntoDocument()
+{
+ NodeImpl::insertedIntoDocument();
+ for (NodeImpl *child = _first; child; child = child->nextSibling())
+ child->insertedIntoDocument();
+}
+
+void NodeBaseImpl::removedFromDocument()
+{
+ NodeImpl::removedFromDocument();
+ for (NodeImpl *child = _first; child; child = child->nextSibling())
+ child->removedFromDocument();
+}
+
void NodeBaseImpl::cloneChildNodes(NodeImpl *clone)
{
int exceptioncode = 0;
diff --git a/WebCore/khtml/xml/dom_nodeimpl.h b/WebCore/khtml/xml/dom_nodeimpl.h
index f97bc04..ed8b8f7 100644
--- a/WebCore/khtml/xml/dom_nodeimpl.h
+++ b/WebCore/khtml/xml/dom_nodeimpl.h
@@ -481,6 +481,9 @@ public:
virtual unsigned long childNodeCount();
virtual NodeImpl *childNode(unsigned long index);
+ virtual void insertedIntoDocument();
+ virtual void removedFromDocument();
+
// check for being (grand-..)father:
bool checkNoOwner( NodeImpl *other, int &exceptioncode );
diff --git a/WebCore/khtml/xml/dom_textimpl.cpp b/WebCore/khtml/xml/dom_textimpl.cpp
index 4f7a9ab..19bd751 100644
--- a/WebCore/khtml/xml/dom_textimpl.cpp
+++ b/WebCore/khtml/xml/dom_textimpl.cpp
@@ -73,8 +73,7 @@ void CharacterDataImpl::setData( const DOMString &_data, int &exceptioncode )
if(str) str->ref();
if (m_render)
(static_cast<RenderText*>(m_render))->setText(str);
- setChanged(true);
-
+
dispatchModifiedEvent(oldStr);
if(oldStr) oldStr->deref();
}
@@ -109,9 +108,8 @@ void CharacterDataImpl::appendData( const DOMString &arg, int &exceptioncode )
str->ref();
str->append(arg.impl);
if (m_render)
- (static_cast<RenderText*>(m_render))->setText(str);
- setChanged(true);
-
+ (static_cast<RenderText*>(m_render))->setTextWithOffset(str, oldStr->l, 0);
+
dispatchModifiedEvent(oldStr);
oldStr->deref();
}
@@ -128,9 +126,8 @@ void CharacterDataImpl::insertData( const unsigned long offset, const DOMString
str->ref();
str->insert(arg.impl, offset);
if (m_render)
- (static_cast<RenderText*>(m_render))->setText(str);
- setChanged(true);
-
+ (static_cast<RenderText*>(m_render))->setTextWithOffset(str, offset, 0);
+
dispatchModifiedEvent(oldStr);
oldStr->deref();
}
@@ -147,9 +144,8 @@ void CharacterDataImpl::deleteData( const unsigned long offset, const unsigned l
str->ref();
str->remove(offset,count);
if (m_render)
- (static_cast<RenderText*>(m_render))->setText(str);
- setChanged(true);
-
+ (static_cast<RenderText*>(m_render))->setTextWithOffset(str, offset, count);
+
dispatchModifiedEvent(oldStr);
oldStr->deref();
}
@@ -173,9 +169,8 @@ void CharacterDataImpl::replaceData( const unsigned long offset, const unsigned
str->remove(offset,realCount);
str->insert(arg.impl, offset);
if (m_render)
- (static_cast<RenderText*>(m_render))->setText(str);
- setChanged(true);
-
+ (static_cast<RenderText*>(m_render))->setTextWithOffset(str, offset, count);
+
dispatchModifiedEvent(oldStr);
oldStr->deref();
}
@@ -356,7 +351,6 @@ TextImpl *TextImpl::splitText( const unsigned long offset, int &exceptioncode )
if (m_render)
(static_cast<RenderText*>(m_render))->setText(str);
- setChanged(true);
return newText;
}
diff --git a/WebCore/kwq/KWQRenderTreeDebug.cpp b/WebCore/kwq/KWQRenderTreeDebug.cpp
index 2efd96f..9444208 100644
--- a/WebCore/kwq/KWQRenderTreeDebug.cpp
+++ b/WebCore/kwq/KWQRenderTreeDebug.cpp
@@ -234,7 +234,7 @@ static void write(QTextStream &ts, const RenderObject &o, int indent = 0)
ts << o << "\n";
- if (o.isText()) {
+ if (o.isText() && !o.isBR()) {
const RenderText &text = static_cast<const RenderText &>(o);
for (InlineTextBox* box = text.firstTextBox(); box; box = box->nextTextBox()) {
writeIndent(ts, indent+1);
--
WebKit Debian packaging
More information about the Pkg-webkit-commits
mailing list