[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 07:23:09 UTC 2009
The following commit has been merged in the debian/unstable branch:
commit bb0cea624c1e4e150ba5dd354c50dc20a48248a6
Author: hyatt <hyatt at 268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date: Fri Jan 31 21:44:07 2003 +0000
Split RenderFlow into subclasses: RenderInline and RenderBlock.
This change should make inlines a lot smaller (since nearly all
of the member variables in RenderFlow moved into RenderBlock).
It also simplifies methods like containingBlock(), which can
now return a RenderBlock.
Reviewed by darin
* WebCore.pbproj/project.pbxproj:
* khtml/css/cssstyleselector.cpp:
* khtml/rendering/bidi.cpp:
(RenderBlock::bidiReorderLine):
(RenderBlock::layoutInlineChildren):
(RenderBlock::findNextLineBreak):
* khtml/rendering/render_block.cpp: Added.
(:RenderFlow):
(RenderBlock::~RenderBlock):
(RenderBlock::setStyle):
(RenderBlock::addChildToFlow):
(getInlineRun):
(RenderBlock::makeChildrenNonInline):
(RenderBlock::removeChild):
(RenderBlock::layout):
(RenderBlock::layoutBlockChildren):
(RenderBlock::layoutSpecialObjects):
(RenderBlock::paint):
(RenderBlock::paintObject):
(RenderBlock::paintFloats):
(RenderBlock::insertSpecialObject):
(RenderBlock::removeSpecialObject):
(RenderBlock::positionNewFloats):
(RenderBlock::newLine):
(RenderBlock::leftOffset):
(RenderBlock::leftRelOffset):
(RenderBlock::rightOffset):
(RenderBlock::rightRelOffset):
(RenderBlock::lineWidth):
(RenderBlock::nearestFloatBottom):
(RenderBlock::floatBottom):
(RenderBlock::lowestPosition):
(RenderBlock::rightmostPosition):
(RenderBlock::leftBottom):
(RenderBlock::rightBottom):
(RenderBlock::clearFloats):
(RenderBlock::addOverHangingFloats):
(RenderBlock::checkClear):
(RenderBlock::nodeAtPoint):
(RenderBlock::calcMinMaxWidth):
(next):
(RenderBlock::calcInlineMinMaxWidth):
(RenderBlock::calcBlockMinMaxWidth):
(RenderBlock::close):
(RenderBlock::printTree):
(RenderBlock::dump):
* khtml/rendering/render_block.h: Added.
* khtml/rendering/render_body.cpp:
(RenderBody::RenderBody):
(RenderBody::setStyle):
(RenderBody::layout):
(RenderBody::availableHeight):
* khtml/rendering/render_body.h:
* khtml/rendering/render_box.cpp:
(RenderBox::containingBlockWidth):
(RenderBox::calcWidth):
(RenderBox::calcHeight):
* khtml/rendering/render_container.cpp:
(RenderContainer::insertPseudoChild):
(RenderContainer::removeLeftoverAnonymousBoxes):
* khtml/rendering/render_flow.cpp:
(RenderFlow::createFlow):
(RenderFlow::addChildWithContinuation):
* khtml/rendering/render_flow.h:
* khtml/rendering/render_form.h:
* khtml/rendering/render_html.cpp:
(RenderHtml::RenderHtml):
(RenderHtml::setStyle):
(RenderHtml::layout):
* khtml/rendering/render_html.h:
* khtml/rendering/render_image.h:
* khtml/rendering/render_inline.cpp: Added.
(:RenderFlow):
(RenderInline::~RenderInline):
(RenderInline::setStyle):
(RenderInline::addChildToFlow):
(cloneInline):
(RenderInline::splitInlines):
(RenderInline::splitFlow):
(RenderInline::paint):
(RenderInline::paintObject):
(RenderInline::calcMinMaxWidth):
(RenderInline::offsetWidth):
(RenderInline::offsetHeight):
(RenderInline::offsetLeft):
(RenderInline::offsetTop):
* khtml/rendering/render_inline.h: Added.
* khtml/rendering/render_list.cpp:
(RenderListItem::RenderListItem):
(RenderListItem::setStyle):
(getParentOfFirstLineBox):
(RenderListItem::calcMinMaxWidth):
(RenderListItem::layout):
(RenderListItem::paint):
(RenderListItem::paintObject):
* khtml/rendering/render_list.h:
* khtml/rendering/render_object.cpp:
(RenderObject::createObject):
(RenderObject::containingBlock):
(RenderObject::setOverhangingContents):
(RenderObject::removeFromSpecialObjects):
* khtml/rendering/render_object.h:
* khtml/rendering/render_replaced.h:
* khtml/rendering/render_root.cpp:
(RenderRoot::RenderRoot):
(RenderRoot::calcMinMaxWidth):
(RenderRoot::layout):
(RenderRoot::paintObject):
* khtml/rendering/render_root.h:
* khtml/rendering/render_table.cpp:
(RenderTable::RenderTable):
(RenderTable::setStyle):
(RenderTable::lineHeight):
(RenderTable::baselinePosition):
(RenderTable::addChild):
(RenderTable::calcWidth):
(RenderTable::recalcSections):
(RenderTable::dump):
(RenderTableCell::RenderTableCell):
(RenderTableCell::detach):
(RenderTableCell::calcMinMaxWidth):
(RenderTableCell::close):
(RenderTableCell::repaintRectangle):
(RenderTableCell::absolutePosition):
(RenderTableCell::setStyle):
(RenderTableCell::dump):
* khtml/rendering/render_table.h:
* khtml/rendering/render_text.h:
* khtml/xml/dom_textimpl.cpp:
(TextImpl::rendererIsNeeded):
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@3527 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/WebCore/ChangeLog-2003-10-25 b/WebCore/ChangeLog-2003-10-25
index 17d30f9..b0cef32 100644
--- a/WebCore/ChangeLog-2003-10-25
+++ b/WebCore/ChangeLog-2003-10-25
@@ -1,3 +1,145 @@
+2003-01-31 David Hyatt <hyatt at apple.com>
+
+ Split RenderFlow into subclasses: RenderInline and RenderBlock.
+ This change should make inlines a lot smaller (since nearly all
+ of the member variables in RenderFlow moved into RenderBlock).
+
+ It also simplifies methods like containingBlock(), which can
+ now return a RenderBlock.
+
+ Reviewed by darin
+
+ * WebCore.pbproj/project.pbxproj:
+ * khtml/css/cssstyleselector.cpp:
+ * khtml/rendering/bidi.cpp:
+ (RenderBlock::bidiReorderLine):
+ (RenderBlock::layoutInlineChildren):
+ (RenderBlock::findNextLineBreak):
+ * khtml/rendering/render_block.cpp: Added.
+ (:RenderFlow):
+ (RenderBlock::~RenderBlock):
+ (RenderBlock::setStyle):
+ (RenderBlock::addChildToFlow):
+ (getInlineRun):
+ (RenderBlock::makeChildrenNonInline):
+ (RenderBlock::removeChild):
+ (RenderBlock::layout):
+ (RenderBlock::layoutBlockChildren):
+ (RenderBlock::layoutSpecialObjects):
+ (RenderBlock::paint):
+ (RenderBlock::paintObject):
+ (RenderBlock::paintFloats):
+ (RenderBlock::insertSpecialObject):
+ (RenderBlock::removeSpecialObject):
+ (RenderBlock::positionNewFloats):
+ (RenderBlock::newLine):
+ (RenderBlock::leftOffset):
+ (RenderBlock::leftRelOffset):
+ (RenderBlock::rightOffset):
+ (RenderBlock::rightRelOffset):
+ (RenderBlock::lineWidth):
+ (RenderBlock::nearestFloatBottom):
+ (RenderBlock::floatBottom):
+ (RenderBlock::lowestPosition):
+ (RenderBlock::rightmostPosition):
+ (RenderBlock::leftBottom):
+ (RenderBlock::rightBottom):
+ (RenderBlock::clearFloats):
+ (RenderBlock::addOverHangingFloats):
+ (RenderBlock::checkClear):
+ (RenderBlock::nodeAtPoint):
+ (RenderBlock::calcMinMaxWidth):
+ (next):
+ (RenderBlock::calcInlineMinMaxWidth):
+ (RenderBlock::calcBlockMinMaxWidth):
+ (RenderBlock::close):
+ (RenderBlock::printTree):
+ (RenderBlock::dump):
+ * khtml/rendering/render_block.h: Added.
+ * khtml/rendering/render_body.cpp:
+ (RenderBody::RenderBody):
+ (RenderBody::setStyle):
+ (RenderBody::layout):
+ (RenderBody::availableHeight):
+ * khtml/rendering/render_body.h:
+ * khtml/rendering/render_box.cpp:
+ (RenderBox::containingBlockWidth):
+ (RenderBox::calcWidth):
+ (RenderBox::calcHeight):
+ * khtml/rendering/render_container.cpp:
+ (RenderContainer::insertPseudoChild):
+ (RenderContainer::removeLeftoverAnonymousBoxes):
+ * khtml/rendering/render_flow.cpp:
+ (RenderFlow::createFlow):
+ (RenderFlow::addChildWithContinuation):
+ * khtml/rendering/render_flow.h:
+ * khtml/rendering/render_form.h:
+ * khtml/rendering/render_html.cpp:
+ (RenderHtml::RenderHtml):
+ (RenderHtml::setStyle):
+ (RenderHtml::layout):
+ * khtml/rendering/render_html.h:
+ * khtml/rendering/render_image.h:
+ * khtml/rendering/render_inline.cpp: Added.
+ (:RenderFlow):
+ (RenderInline::~RenderInline):
+ (RenderInline::setStyle):
+ (RenderInline::addChildToFlow):
+ (cloneInline):
+ (RenderInline::splitInlines):
+ (RenderInline::splitFlow):
+ (RenderInline::paint):
+ (RenderInline::paintObject):
+ (RenderInline::calcMinMaxWidth):
+ (RenderInline::offsetWidth):
+ (RenderInline::offsetHeight):
+ (RenderInline::offsetLeft):
+ (RenderInline::offsetTop):
+ * khtml/rendering/render_inline.h: Added.
+ * khtml/rendering/render_list.cpp:
+ (RenderListItem::RenderListItem):
+ (RenderListItem::setStyle):
+ (getParentOfFirstLineBox):
+ (RenderListItem::calcMinMaxWidth):
+ (RenderListItem::layout):
+ (RenderListItem::paint):
+ (RenderListItem::paintObject):
+ * khtml/rendering/render_list.h:
+ * khtml/rendering/render_object.cpp:
+ (RenderObject::createObject):
+ (RenderObject::containingBlock):
+ (RenderObject::setOverhangingContents):
+ (RenderObject::removeFromSpecialObjects):
+ * khtml/rendering/render_object.h:
+ * khtml/rendering/render_replaced.h:
+ * khtml/rendering/render_root.cpp:
+ (RenderRoot::RenderRoot):
+ (RenderRoot::calcMinMaxWidth):
+ (RenderRoot::layout):
+ (RenderRoot::paintObject):
+ * khtml/rendering/render_root.h:
+ * khtml/rendering/render_table.cpp:
+ (RenderTable::RenderTable):
+ (RenderTable::setStyle):
+ (RenderTable::lineHeight):
+ (RenderTable::baselinePosition):
+ (RenderTable::addChild):
+ (RenderTable::calcWidth):
+ (RenderTable::recalcSections):
+ (RenderTable::dump):
+ (RenderTableCell::RenderTableCell):
+ (RenderTableCell::detach):
+ (RenderTableCell::calcMinMaxWidth):
+ (RenderTableCell::close):
+ (RenderTableCell::repaintRectangle):
+ (RenderTableCell::absolutePosition):
+ (RenderTableCell::setStyle):
+ (RenderTableCell::dump):
+ * khtml/rendering/render_table.h:
+ * khtml/rendering/render_text.h:
+ * khtml/xml/dom_textimpl.cpp:
+ (TextImpl::rendererIsNeeded):
+
2003-01-31 Darin Adler <darin at apple.com>
Reviewed by me, Dave wrote the code.
diff --git a/WebCore/ChangeLog-2005-08-23 b/WebCore/ChangeLog-2005-08-23
index 17d30f9..b0cef32 100644
--- a/WebCore/ChangeLog-2005-08-23
+++ b/WebCore/ChangeLog-2005-08-23
@@ -1,3 +1,145 @@
+2003-01-31 David Hyatt <hyatt at apple.com>
+
+ Split RenderFlow into subclasses: RenderInline and RenderBlock.
+ This change should make inlines a lot smaller (since nearly all
+ of the member variables in RenderFlow moved into RenderBlock).
+
+ It also simplifies methods like containingBlock(), which can
+ now return a RenderBlock.
+
+ Reviewed by darin
+
+ * WebCore.pbproj/project.pbxproj:
+ * khtml/css/cssstyleselector.cpp:
+ * khtml/rendering/bidi.cpp:
+ (RenderBlock::bidiReorderLine):
+ (RenderBlock::layoutInlineChildren):
+ (RenderBlock::findNextLineBreak):
+ * khtml/rendering/render_block.cpp: Added.
+ (:RenderFlow):
+ (RenderBlock::~RenderBlock):
+ (RenderBlock::setStyle):
+ (RenderBlock::addChildToFlow):
+ (getInlineRun):
+ (RenderBlock::makeChildrenNonInline):
+ (RenderBlock::removeChild):
+ (RenderBlock::layout):
+ (RenderBlock::layoutBlockChildren):
+ (RenderBlock::layoutSpecialObjects):
+ (RenderBlock::paint):
+ (RenderBlock::paintObject):
+ (RenderBlock::paintFloats):
+ (RenderBlock::insertSpecialObject):
+ (RenderBlock::removeSpecialObject):
+ (RenderBlock::positionNewFloats):
+ (RenderBlock::newLine):
+ (RenderBlock::leftOffset):
+ (RenderBlock::leftRelOffset):
+ (RenderBlock::rightOffset):
+ (RenderBlock::rightRelOffset):
+ (RenderBlock::lineWidth):
+ (RenderBlock::nearestFloatBottom):
+ (RenderBlock::floatBottom):
+ (RenderBlock::lowestPosition):
+ (RenderBlock::rightmostPosition):
+ (RenderBlock::leftBottom):
+ (RenderBlock::rightBottom):
+ (RenderBlock::clearFloats):
+ (RenderBlock::addOverHangingFloats):
+ (RenderBlock::checkClear):
+ (RenderBlock::nodeAtPoint):
+ (RenderBlock::calcMinMaxWidth):
+ (next):
+ (RenderBlock::calcInlineMinMaxWidth):
+ (RenderBlock::calcBlockMinMaxWidth):
+ (RenderBlock::close):
+ (RenderBlock::printTree):
+ (RenderBlock::dump):
+ * khtml/rendering/render_block.h: Added.
+ * khtml/rendering/render_body.cpp:
+ (RenderBody::RenderBody):
+ (RenderBody::setStyle):
+ (RenderBody::layout):
+ (RenderBody::availableHeight):
+ * khtml/rendering/render_body.h:
+ * khtml/rendering/render_box.cpp:
+ (RenderBox::containingBlockWidth):
+ (RenderBox::calcWidth):
+ (RenderBox::calcHeight):
+ * khtml/rendering/render_container.cpp:
+ (RenderContainer::insertPseudoChild):
+ (RenderContainer::removeLeftoverAnonymousBoxes):
+ * khtml/rendering/render_flow.cpp:
+ (RenderFlow::createFlow):
+ (RenderFlow::addChildWithContinuation):
+ * khtml/rendering/render_flow.h:
+ * khtml/rendering/render_form.h:
+ * khtml/rendering/render_html.cpp:
+ (RenderHtml::RenderHtml):
+ (RenderHtml::setStyle):
+ (RenderHtml::layout):
+ * khtml/rendering/render_html.h:
+ * khtml/rendering/render_image.h:
+ * khtml/rendering/render_inline.cpp: Added.
+ (:RenderFlow):
+ (RenderInline::~RenderInline):
+ (RenderInline::setStyle):
+ (RenderInline::addChildToFlow):
+ (cloneInline):
+ (RenderInline::splitInlines):
+ (RenderInline::splitFlow):
+ (RenderInline::paint):
+ (RenderInline::paintObject):
+ (RenderInline::calcMinMaxWidth):
+ (RenderInline::offsetWidth):
+ (RenderInline::offsetHeight):
+ (RenderInline::offsetLeft):
+ (RenderInline::offsetTop):
+ * khtml/rendering/render_inline.h: Added.
+ * khtml/rendering/render_list.cpp:
+ (RenderListItem::RenderListItem):
+ (RenderListItem::setStyle):
+ (getParentOfFirstLineBox):
+ (RenderListItem::calcMinMaxWidth):
+ (RenderListItem::layout):
+ (RenderListItem::paint):
+ (RenderListItem::paintObject):
+ * khtml/rendering/render_list.h:
+ * khtml/rendering/render_object.cpp:
+ (RenderObject::createObject):
+ (RenderObject::containingBlock):
+ (RenderObject::setOverhangingContents):
+ (RenderObject::removeFromSpecialObjects):
+ * khtml/rendering/render_object.h:
+ * khtml/rendering/render_replaced.h:
+ * khtml/rendering/render_root.cpp:
+ (RenderRoot::RenderRoot):
+ (RenderRoot::calcMinMaxWidth):
+ (RenderRoot::layout):
+ (RenderRoot::paintObject):
+ * khtml/rendering/render_root.h:
+ * khtml/rendering/render_table.cpp:
+ (RenderTable::RenderTable):
+ (RenderTable::setStyle):
+ (RenderTable::lineHeight):
+ (RenderTable::baselinePosition):
+ (RenderTable::addChild):
+ (RenderTable::calcWidth):
+ (RenderTable::recalcSections):
+ (RenderTable::dump):
+ (RenderTableCell::RenderTableCell):
+ (RenderTableCell::detach):
+ (RenderTableCell::calcMinMaxWidth):
+ (RenderTableCell::close):
+ (RenderTableCell::repaintRectangle):
+ (RenderTableCell::absolutePosition):
+ (RenderTableCell::setStyle):
+ (RenderTableCell::dump):
+ * khtml/rendering/render_table.h:
+ * khtml/rendering/render_text.h:
+ * khtml/xml/dom_textimpl.cpp:
+ (TextImpl::rendererIsNeeded):
+
2003-01-31 Darin Adler <darin at apple.com>
Reviewed by me, Dave wrote the code.
diff --git a/WebCore/WebCore.pbproj/project.pbxproj b/WebCore/WebCore.pbproj/project.pbxproj
index 1ffebe5..ace0f22 100644
--- a/WebCore/WebCore.pbproj/project.pbxproj
+++ b/WebCore/WebCore.pbproj/project.pbxproj
@@ -484,6 +484,8 @@
931BFCD803D4AEFD008635CE,
93955A4303D72932008635CE,
6504A7BF03DCE19800000124,
+ BC7C965303E9EE7000A80004,
+ BC7C965503E9EE7000A80004,
);
isa = PBXHeadersBuildPhase;
runOnlyForDeploymentPostprocessing = 0;
@@ -725,6 +727,8 @@
931BFCD503D4AEE5008635CE,
931BFCD903D4AEFD008635CE,
93955A4403D72932008635CE,
+ BC7C965203E9EE7000A80004,
+ BC7C965403E9EE7000A80004,
);
isa = PBXSourcesBuildPhase;
runOnlyForDeploymentPostprocessing = 0;
@@ -1474,6 +1478,54 @@
settings = {
};
};
+ BC7C964E03E9EE7000A80004 = {
+ fileEncoding = 30;
+ isa = PBXFileReference;
+ path = render_block.cpp;
+ refType = 4;
+ };
+ BC7C964F03E9EE7000A80004 = {
+ fileEncoding = 30;
+ isa = PBXFileReference;
+ path = render_block.h;
+ refType = 4;
+ };
+ BC7C965003E9EE7000A80004 = {
+ fileEncoding = 30;
+ isa = PBXFileReference;
+ path = render_inline.cpp;
+ refType = 4;
+ };
+ BC7C965103E9EE7000A80004 = {
+ fileEncoding = 30;
+ isa = PBXFileReference;
+ path = render_inline.h;
+ refType = 4;
+ };
+ BC7C965203E9EE7000A80004 = {
+ fileRef = BC7C964E03E9EE7000A80004;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ BC7C965303E9EE7000A80004 = {
+ fileRef = BC7C964F03E9EE7000A80004;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ BC7C965403E9EE7000A80004 = {
+ fileRef = BC7C965003E9EE7000A80004;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ BC7C965503E9EE7000A80004 = {
+ fileRef = BC7C965103E9EE7000A80004;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
BCF0192403D3802200B2D04D = {
fileEncoding = 30;
isa = PBXFileReference;
@@ -4134,6 +4186,8 @@
F523D2A302DE4438018635CA,
BC7294FC03804B5600A80166,
BC7294FB03804B5600A80166,
+ BC7C964F03E9EE7000A80004,
+ BC7C964E03E9EE7000A80004,
F523D2A602DE4438018635CA,
F523D2A502DE4438018635CA,
F523D2A802DE4438018635CA,
@@ -4152,6 +4206,8 @@
F523D2B602DE4438018635CA,
F523D2B702DE4438018635CA,
F523D2B802DE4438018635CA,
+ BC7C965003E9EE7000A80004,
+ BC7C965103E9EE7000A80004,
F690CFEA031C47F401CA2AC4,
F690CFEB031C47F401CA2AC4,
F523D2B902DE4438018635CA,
diff --git a/WebCore/khtml/css/cssstyleselector.cpp b/WebCore/khtml/css/cssstyleselector.cpp
index 2c9ef3a..d2f6749 100644
--- a/WebCore/khtml/css/cssstyleselector.cpp
+++ b/WebCore/khtml/css/cssstyleselector.cpp
@@ -450,6 +450,12 @@ RenderStyle *CSSStyleSelector::styleForElement(ElementImpl *e)
}
}
+ // Mutate the display to BLOCK for certain cases, e.g., if someone attempts to
+ // position or float an inline.
+ if (style->display() == INLINE &&
+ (style->position() == ABSOLUTE || style->position() == FIXED || style->floating() != FNONE))
+ style->setDisplay(BLOCK);
+
return style;
}
diff --git a/WebCore/khtml/rendering/bidi.cpp b/WebCore/khtml/rendering/bidi.cpp
index 725995a..e3bfb64 100644
--- a/WebCore/khtml/rendering/bidi.cpp
+++ b/WebCore/khtml/rendering/bidi.cpp
@@ -22,7 +22,7 @@
*/
#include "bidi.h"
#include "break_lines.h"
-#include "render_flow.h"
+#include "render_block.h"
#include "render_text.h"
#include "render_arena.h"
#include "xml/dom_docimpl.h"
@@ -400,11 +400,11 @@ static void embed( QChar::Direction d )
// collects one line of the paragraph and transforms it to visual order
-void RenderFlow::bidiReorderLine(const BidiIterator &start, const BidiIterator &end)
+void RenderBlock::bidiReorderLine(const BidiIterator &start, const BidiIterator &end)
{
if ( start == end ) {
if ( start.current() == '\n' ) {
- m_height += lineHeight( firstLine );
+ m_height += lineHeight( m_firstLine );
}
return;
}
@@ -862,11 +862,11 @@ void RenderFlow::bidiReorderLine(const BidiIterator &start, const BidiIterator &
int maxDescent = 0;
r = runs.first();
while ( r ) {
- r->height = r->obj->lineHeight( firstLine );
- r->baseline = r->obj->baselinePosition( firstLine );
+ r->height = r->obj->lineHeight( m_firstLine );
+ r->baseline = r->obj->baselinePosition( m_firstLine );
// if ( r->baseline > r->height )
// r->baseline = r->height;
- r->vertical = r->obj->verticalPositionHint( firstLine );
+ r->vertical = r->obj->verticalPositionHint( m_firstLine );
//kdDebug(6041) << "object="<< r->obj << " height="<<r->height<<" baseline="<< r->baseline << " vertical=" << r->vertical <<endl;
//int ascent;
if ( r->vertical == PositionTop ) {
@@ -932,7 +932,7 @@ void RenderFlow::bidiReorderLine(const BidiIterator &start, const BidiIterator &
kdDebug(6040) << "object="<< r->obj << " placing at vertical=" << r->vertical <<endl;
#endif
if(r->obj->isText())
- r->width = static_cast<RenderText *>(r->obj)->width(r->start, r->stop-r->start, firstLine);
+ r->width = static_cast<RenderText *>(r->obj)->width(r->start, r->stop-r->start, m_firstLine);
else {
r->obj->calcWidth();
r->width = r->obj->width()+r->obj->marginLeft()+r->obj->marginRight();
@@ -990,7 +990,7 @@ void RenderFlow::bidiReorderLine(const BidiIterator &start, const BidiIterator &
totWidth += spaceAdd;
}
}
- r->obj->position(x, r->vertical, r->start, r->stop - r->start, r->width, r->level%2, firstLine, spaceAdd);
+ r->obj->position(x, r->vertical, r->start, r->stop - r->start, r->width, r->level%2, m_firstLine, spaceAdd);
x += r->width + spaceAdd;
r = runs.next();
}
@@ -1015,7 +1015,7 @@ static void deleteMidpoints(RenderArena* arena, QPtrList<BidiIterator>* midpoint
midpoints->clear();
}
-void RenderFlow::layoutInlineChildren(bool relayoutChildren)
+void RenderBlock::layoutInlineChildren(bool relayoutChildren)
{
m_overflowHeight = 0;
@@ -1045,7 +1045,7 @@ void RenderFlow::layoutInlineChildren(bool relayoutChildren)
if( !o->layouted() )
o->layout();
if(o->isPositioned())
- static_cast<RenderFlow*>(o->containingBlock())->insertSpecialObject(o);
+ o->containingBlock()->insertSpecialObject(o);
}
else if(o->isText())
static_cast<RenderText *>(o)->deleteSlaves();
@@ -1069,7 +1069,7 @@ void RenderFlow::layoutInlineChildren(bool relayoutChildren)
adjustEmbeddding = false;
BidiIterator end(this);
- firstLine = true;
+ m_firstLine = true;
if (!smidpoints) {
smidpoints = new QPtrList<BidiIterator>;
@@ -1097,7 +1097,7 @@ void RenderFlow::layoutInlineChildren(bool relayoutChildren)
newLine();
}
- firstLine = false;
+ m_firstLine = false;
deleteMidpoints(renderArena(), smidpoints);
}
startEmbed->deref();
@@ -1122,7 +1122,7 @@ void RenderFlow::layoutInlineChildren(bool relayoutChildren)
//kdDebug(6040) << "height = " << m_height <<endl;
}
-BidiIterator RenderFlow::findNextLineBreak(BidiIterator &start, QPtrList<BidiIterator>& midpoints)
+BidiIterator RenderBlock::findNextLineBreak(BidiIterator &start, QPtrList<BidiIterator>& midpoints)
{
int width = lineWidth(m_height);
int w = 0;
@@ -1155,7 +1155,7 @@ BidiIterator RenderFlow::findNextLineBreak(BidiIterator &start, QPtrList<BidiIte
width = lineWidth(m_height);
}
} else if(o->isPositioned()) {
- static_cast<RenderFlow*>(o->containingBlock())->insertSpecialObject(o);
+ o->containingBlock()->insertSpecialObject(o);
}
}
@@ -1223,7 +1223,7 @@ BidiIterator RenderFlow::findNextLineBreak(BidiIterator &start, QPtrList<BidiIte
width = lineWidth(m_height);
}
} else if(o->isPositioned()) {
- static_cast<RenderFlow*>(o->containingBlock())->insertSpecialObject(o);
+ o->containingBlock()->insertSpecialObject(o);
}
} else if ( o->isReplaced() ) {
if (o->style()->whiteSpace() != NOWRAP || last->style()->whiteSpace() != NOWRAP) {
@@ -1271,7 +1271,7 @@ BidiIterator RenderFlow::findNextLineBreak(BidiIterator &start, QPtrList<BidiIte
int len = strlen - pos;
QChar *str = t->text();
- const Font *f = t->htmlFont( firstLine );
+ const Font *f = t->htmlFont( m_firstLine );
// proportional font, needs a bit more work.
int lastSpace = pos;
bool isPre = o->style()->whiteSpace() == PRE;
diff --git a/WebCore/khtml/rendering/render_flow.cpp b/WebCore/khtml/rendering/render_block.cpp
similarity index 68%
copy from WebCore/khtml/rendering/render_flow.cpp
copy to WebCore/khtml/rendering/render_block.cpp
index 96cf835..eccc354 100644
--- a/WebCore/khtml/rendering/render_flow.cpp
+++ b/WebCore/khtml/rendering/render_block.cpp
@@ -1,8 +1,6 @@
-/**
- * This file is part of the html renderer for KDE.
+/*
+ * This file is part of the render object implementation for KHTML.
*
- * Copyright (C) 1999 Lars Knoll (knoll at kde.org)
- * (C) 1999 Antti Koivisto (koivisto at kde.org)
* Copyright (C) 2003 Apple Computer, Inc.
*
* This library is free software; you can redistribute it and/or
@@ -19,76 +17,62 @@
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
+ *
*/
-// -------------------------------------------------------------------------
+
//#define DEBUG
//#define DEBUG_LAYOUT
//#define BOX_DEBUG
//#define FLOAT_DEBUG
#include <kdebug.h>
-#include <assert.h>
-#include <qpainter.h>
-#include <kglobal.h>
-
-#include "rendering/render_flow.h"
#include "rendering/render_text.h"
#include "rendering/render_table.h"
#include "rendering/render_root.h"
#include "xml/dom_nodeimpl.h"
#include "xml/dom_docimpl.h"
#include "html/html_formimpl.h"
+#include "render_block.h"
#include "khtmlview.h"
#include "htmltags.h"
-using namespace DOM;
using namespace khtml;
+using namespace DOM;
-RenderFlow::RenderFlow(DOM::NodeImpl* node)
- : RenderBox(node)
+RenderBlock::RenderBlock(DOM::NodeImpl* node)
+:RenderFlow(node)
{
m_childrenInline = true;
+ m_specialObjects = 0;
m_pre = false;
- firstLine = false;
+ m_firstLine = false;
m_clearStatus = CNONE;
-
- specialObjects = 0;
-
m_maxTopPosMargin = m_maxTopNegMargin = m_maxBottomPosMargin = m_maxBottomNegMargin = 0;
m_topMarginQuirk = m_bottomMarginQuirk = false;
m_overflowHeight = 0;
m_overflowWidth = 0;
-
- m_continuation = 0;
}
-void RenderFlow::setStyle(RenderStyle *_style)
+RenderBlock::~RenderBlock()
{
+ delete m_specialObjects;
+}
-// kdDebug( 6040 ) << (void*)this<< " renderFlow(" << renderName() << ")::setstyle()" << endl;
-
- RenderBox::setStyle(_style);
-
- if(isPositioned())
- setInline(false);
-
- if(isFloating() || style()->display() != INLINE)
- setInline(false);
-
- if (isInline() && !m_childrenInline)
- setInline(false);
-
+void RenderBlock::setStyle(RenderStyle* _style)
+{
+ setInline(false);
+ RenderFlow::setStyle(_style);
m_pre = false;
- if(style()->whiteSpace() == PRE)
+ if (_style->whiteSpace() == PRE)
m_pre = true;
// ### we could save this call when the change only affected
// non inherited properties
RenderObject *child = firstChild();
- while(child != 0)
+ while (child != 0)
{
- if(child->isAnonymousBox())
+ if (child->isAnonymousBox())
{
RenderStyle* newStyle = new RenderStyle();
newStyle->inheritFrom(style());
@@ -97,167 +81,316 @@ void RenderFlow::setStyle(RenderStyle *_style)
child->setIsAnonymousBox(true);
}
child = child->nextSibling();
- }
-
- // Ensure that all of the split inlines pick up the new style. We
- // only do this if we're an inline, since we don't want to propagate
- // a block's style to the other inlines.
- // e.g., <font>foo <h4>goo</h4> moo</font>. The <font> inlines before
- // and after the block share the same style, but the block doesn't
- // need to pass its style on to anyone else.
- if (isInline()) {
- RenderFlow* currCont = continuation();
- while (currCont) {
- if (currCont->isInline()) {
- RenderFlow* nextCont = currCont->continuation();
- currCont->setContinuation(0);
- currCont->setStyle(style());
- currCont->setContinuation(nextCont);
+ }
+}
+
+void RenderBlock::addChildToFlow(RenderObject* newChild, RenderObject* beforeChild)
+{
+ setLayouted( false );
+
+ bool madeBoxesNonInline = FALSE;
+
+ RenderStyle* pseudoStyle=0;
+ if ((!firstChild() || firstChild() == beforeChild) && newChild->isText())
+ {
+ RenderText* newTextChild = static_cast<RenderText*>(newChild);
+ //kdDebug( 6040 ) << "first letter" << endl;
+
+ if ( (pseudoStyle=style()->getPseudoStyle(RenderStyle::FIRST_LETTER)) ) {
+ pseudoStyle->setDisplay( INLINE );
+ pseudoStyle->setPosition( STATIC ); // CSS2 says first-letter can't be positioned.
+
+ RenderObject* firstLetter = RenderFlow::createFlow(0, pseudoStyle, renderArena()); // anonymous box
+ addChild(firstLetter);
+
+ DOMStringImpl* oldText = newTextChild->string();
+
+ if(oldText->l >= 1) {
+ unsigned int length = 0;
+ while ( length < oldText->l &&
+ ( (oldText->s+length)->isSpace() || (oldText->s+length)->isPunct() ) )
+ length++;
+ length++;
+ //kdDebug( 6040 ) << "letter= '" << DOMString(oldText->substring(0,length)).string() << "'" << endl;
+ newTextChild->setText(oldText->substring(length,oldText->l-length));
+
+ RenderText* letter = new (renderArena()) RenderText(newTextChild->element(), oldText->substring(0,length));
+ RenderStyle* newStyle = new RenderStyle();
+ newStyle->inheritFrom(pseudoStyle);
+ letter->setStyle(newStyle);
+ firstLetter->addChild(letter);
}
- currCont = currCont->continuation();
+ firstLetter->close();
}
}
-}
-RenderFlow::~RenderFlow()
-{
- delete specialObjects;
-}
+ insertPseudoChild(RenderStyle::BEFORE, newChild, beforeChild);
-void RenderFlow::paint(QPainter *p, int _x, int _y, int _w, int _h,
- int _tx, int _ty, PaintAction paintAction)
-{
+ // If the requested beforeChild is not one of our children, then this is most likely because
+ // there is an anonymous block box within this object that contains the beforeChild. So
+ // just insert the child into the anonymous block box instead of here.
+ if (beforeChild && beforeChild->parent() != this) {
-#ifdef DEBUG_LAYOUT
-// kdDebug( 6040 ) << renderName() << "(RenderFlow) " << this << " ::print() x/y/w/h = (" << xPos() << "/" << yPos() << "/" << width() << "/" << height() << ")" << endl;
-#endif
+ KHTMLAssert(beforeChild->parent());
+ KHTMLAssert(beforeChild->parent()->isAnonymousBox());
- if(!isInline())
- {
- _tx += m_x;
- _ty += m_y;
+ if (newChild->isInline()) {
+ beforeChild->parent()->addChild(newChild,beforeChild);
+ newChild->setLayouted( false );
+ newChild->setMinMaxKnown( false );
+ return;
+ }
+ else if (beforeChild->parent()->firstChild() != beforeChild)
+ return beforeChild->parent()->addChild(newChild, beforeChild);
+ else
+ return addChildToFlow(newChild, beforeChild->parent());
}
- // check if we need to do anything at all...
- if(!isInline() && !overhangingContents() && !isRelPositioned() && !isPositioned() )
+ // prevent non-layouted elements from getting painted by pushing them far above the top of the
+ // page
+ if (!newChild->isInline())
+ newChild->setPos(newChild->xPos(), -500000);
+
+ if (!newChild->isText() && newChild->style()->position() != STATIC)
+ setOverhangingContents();
+
+ // A block has to either have all of its children inline, or all of its children as blocks.
+ // So, if our children are currently inline and a block child has to be inserted, we move all our
+ // inline children into anonymous block boxes
+ if ( m_childrenInline && !newChild->isInline() && !newChild->isSpecial() )
{
- int h = m_height;
- if(specialObjects && floatBottom() > h) h = floatBottom();
- if((_ty > _y + _h) || (_ty + h < _y))
- {
- //kdDebug( 6040 ) << "cut!" << endl;
+ // This is a block with inline content. Wrap the inline content in anonymous blocks.
+ makeChildrenNonInline(beforeChild);
+ madeBoxesNonInline = true;
+
+ if (beforeChild && beforeChild->parent() != this) {
+ beforeChild = beforeChild->parent();
+ KHTMLAssert(beforeChild->isAnonymousBox());
+ KHTMLAssert(beforeChild->parent() == this);
+ }
+ }
+ else if (!m_childrenInline && !newChild->isSpecial())
+ {
+ // If we're inserting an inline child but all of our children are blocks, then we have to make sure
+ // it is put into an anomyous block box. We try to use an existing anonymous box if possible, otherwise
+ // a new one is created and inserted into our list of children in the appropriate position.
+ if (newChild->isInline()) {
+ if (beforeChild) {
+ if (beforeChild->previousSibling() && beforeChild->previousSibling()->isAnonymousBox()) {
+ beforeChild->previousSibling()->addChild(newChild);
+ newChild->setLayouted( false );
+ newChild->setMinMaxKnown( false );
+ return;
+ }
+ }
+ else {
+ if (m_last && m_last->isAnonymousBox()) {
+ m_last->addChild(newChild);
+ newChild->setLayouted( false );
+ newChild->setMinMaxKnown( false );
+ return;
+ }
+ }
+
+ // no suitable existing anonymous box - create a new one
+ RenderStyle *newStyle = new RenderStyle();
+ newStyle->inheritFrom(style());
+ newStyle->setDisplay(BLOCK);
+
+ RenderFlow *newBox = new (renderArena()) RenderBlock(0 /* anonymous box */);
+ newBox->setStyle(newStyle);
+ newBox->setIsAnonymousBox(true);
+
+ RenderBox::addChild(newBox,beforeChild);
+ newBox->addChild(newChild);
+ newBox->setPos(newBox->xPos(), -500000);
+
+ newChild->setLayouted( false );
+ newChild->setMinMaxKnown( false );
return;
}
+ else {
+ // We are adding another block child... if the current last child is an anonymous box
+ // then it needs to be closed.
+ // ### get rid of the closing thing altogether this will only work during initial parsing
+ if (lastChild() && lastChild()->isAnonymousBox()) {
+ lastChild()->close();
+ }
+ }
}
- paintObject(p, _x, _y, _w, _h, _tx, _ty, paintAction);
+ RenderBox::addChild(newChild,beforeChild);
+ // ### care about aligned stuff
+
+ newChild->setLayouted( false );
+ newChild->setMinMaxKnown( false );
+ insertPseudoChild(RenderStyle::AFTER, newChild, beforeChild);
+
+ if ( madeBoxesNonInline )
+ removeLeftoverAnonymousBoxes();
}
-void RenderFlow::paintObject(QPainter *p, int _x, int _y,
- int _w, int _h, int _tx, int _ty, PaintAction paintAction)
+static void getInlineRun(RenderObject* start, RenderObject* stop,
+ RenderObject*& inlineRunStart,
+ RenderObject*& inlineRunEnd)
{
+ // Beginning at |start| we find the largest contiguous run of inlines that
+ // we can. We denote the run with start and end points, |inlineRunStart|
+ // and |inlineRunEnd|. Note that these two values may be the same if
+ // we encounter only one inline.
+ //
+ // We skip any non-inlines we encounter as long as we haven't found any
+ // inlines yet.
+ //
+ // |stop| indicates a non-inclusive stop point. Regardless of whether |stop|
+ // is inline or not, we will not include it. It's as though we encountered
+ // a non-inline.
+ inlineRunStart = inlineRunEnd = 0;
-#ifdef DEBUG_LAYOUT
-// kdDebug( 6040 ) << renderName() << "(RenderFlow) " << this << " ::paintObject() w/h = (" << width() << "/" << height() << ")" << endl;
-#endif
-
- // 1. paint background, borders etc
- if (paintAction == PaintActionBackground &&
- shouldPaintBackgroundOrBorder() && !isInline() && style()->visibility() == VISIBLE )
- paintBoxDecorations(p, _x, _y, _w, _h, _tx, _ty);
+ // Start by skipping as many non-inlines as we can.
+ RenderObject * curr = start;
+ while (curr && !curr->isInline())
+ curr = curr->nextSibling();
- // 2. paint contents
- RenderObject *child = firstChild();
- while(child != 0)
- {
- if(!child->layer() && !child->isFloating())
- child->paint(p, _x, _y, _w, _h, _tx, _ty, paintAction);
- child = child->nextSibling();
+ if (!curr)
+ return; // No more inline children to be found.
+
+ inlineRunStart = inlineRunEnd = curr;
+ curr = curr->nextSibling();
+ while (curr && curr->isInline() && (curr != stop)) {
+ inlineRunEnd = curr;
+ curr = curr->nextSibling();
}
+}
- // 3. paint floats.
- if (paintAction == PaintActionFloat || paintAction == PaintActionSelection)
- paintFloats(p, _x, _y, _w, _h, _tx, _ty, paintAction == PaintActionSelection);
-
- if (paintAction == PaintActionBackground &&
- !isInline() && !childrenInline() && style()->outlineWidth())
- paintOutline(p, _tx, _ty, width(), height(), style());
+void RenderBlock::makeChildrenNonInline(RenderObject *insertionPoint)
+{
+ // makeChildrenNonInline takes a block whose children are *all* inline and it
+ // makes sure that inline children are coalesced under anonymous
+ // blocks. If |insertionPoint| is defined, then it represents the insertion point for
+ // the new block child that is causing us to have to wrap all the inlines. This
+ // means that we cannot coalesce inlines before |insertionPoint| with inlines following
+ // |insertionPoint|, because the new child is going to be inserted in between the inlines,
+ // splitting them.
+ KHTMLAssert(!isInline());
+ KHTMLAssert(!insertionPoint || insertionPoint->parent() == this);
-#ifdef BOX_DEBUG
- if ( style() && style()->visibility() == VISIBLE ) {
- if(isAnonymousBox())
- outlineBox(p, _tx, _ty, "green");
- if(isFloating())
- outlineBox(p, _tx, _ty, "yellow");
- else
- outlineBox(p, _tx, _ty);
+ m_childrenInline = false;
+
+ RenderObject *child = firstChild();
+
+ while (child) {
+ RenderObject *inlineRunStart, *inlineRunEnd;
+ getInlineRun(child, insertionPoint, inlineRunStart, inlineRunEnd);
+
+ if (!inlineRunStart)
+ break;
+
+ child = inlineRunEnd->nextSibling();
+
+ RenderStyle *newStyle = new RenderStyle();
+ newStyle->inheritFrom(style());
+ newStyle->setDisplay(BLOCK);
+
+ RenderBlock *box = new (renderArena()) RenderBlock(0 /* anonymous box */);
+ box->setStyle(newStyle);
+ box->setIsAnonymousBox(true);
+
+ insertChildNode(box, inlineRunStart);
+ RenderObject* o = inlineRunStart;
+ while(o != inlineRunEnd)
+ {
+ RenderObject* no = o;
+ o = no->nextSibling();
+ box->appendChildNode(removeChildNode(no));
+ }
+ box->appendChildNode(removeChildNode(inlineRunEnd));
+ box->close();
+ box->setPos(box->xPos(), -500000);
+ box->setLayouted(false);
}
-#endif
+ setLayouted(false);
}
-void RenderFlow::paintFloats(QPainter *p, int _x, int _y,
- int _w, int _h, int _tx, int _ty, bool paintSelection)
+void RenderBlock::removeChild(RenderObject *oldChild)
{
- if (!specialObjects)
- return;
+ // If this child is a block, and if our previous and next siblings are
+ // both anonymous blocks with inline content, then we can go ahead and
+ // fold the inline content back together.
+ RenderObject* prev = oldChild->previousSibling();
+ RenderObject* next = oldChild->nextSibling();
+ bool mergedBlocks = false;
+ if (!isInline() && !oldChild->isInline() && !oldChild->continuation() &&
+ prev && prev->isAnonymousBox() && prev->childrenInline() &&
+ next && next->isAnonymousBox() && next->childrenInline()) {
+ // Take all the children out of the |next| block and put them in
+ // the |prev| block.
+ RenderObject* o = next->firstChild();
+ while (o) {
+ RenderObject* no = o;
+ o = no->nextSibling();
+ prev->appendChildNode(next->removeChildNode(no));
+ no->setLayouted(false);
+ no->setMinMaxKnown(false);
+ }
+ prev->setLayouted(false);
+ prev->setMinMaxKnown(false);
- SpecialObject* r;
- QPtrListIterator<SpecialObject> it(*specialObjects);
- for ( ; (r = it.current()); ++it) {
- // Only paint the object if our noPaint flag isn't set.
- if (r->node->isFloating() && !r->noPaint) {
- if (paintSelection) {
- r->node->paint(p, _x, _y, _w, _h,
- _tx + r->left - r->node->xPos() + r->node->marginLeft(),
- _ty + r->startY - r->node->yPos() + r->node->marginTop(),
- PaintActionSelection);
- }
- else {
- r->node->paint(p, _x, _y, _w, _h,
- _tx + r->left - r->node->xPos() + r->node->marginLeft(),
- _ty + r->startY - r->node->yPos() + r->node->marginTop(),
- PaintActionBackground);
- r->node->paint(p, _x, _y, _w, _h,
- _tx + r->left - r->node->xPos() + r->node->marginLeft(),
- _ty + r->startY - r->node->yPos() + r->node->marginTop(),
- PaintActionFloat);
- r->node->paint(p, _x, _y, _w, _h,
- _tx + r->left - r->node->xPos() + r->node->marginLeft(),
- _ty + r->startY - r->node->yPos() + r->node->marginTop(),
- PaintActionForeground);
- }
+ // Nuke the now-empty block.
+ next->detach(renderArena());
+
+ mergedBlocks = true;
+ }
+
+ RenderFlow::removeChild(oldChild);
+
+ if (mergedBlocks && prev && !prev->previousSibling() && !prev->nextSibling()) {
+ // The remerge has knocked us down to containing only a single anonymous
+ // box. We can go ahead and pull the content right back up into our
+ // box.
+ RenderObject* anonBlock = removeChildNode(prev);
+ m_childrenInline = true;
+ RenderObject* o = anonBlock->firstChild();
+ while (o) {
+ RenderObject* no = o;
+ o = no->nextSibling();
+ appendChildNode(anonBlock->removeChildNode(no));
+ no->setLayouted(false);
+ no->setMinMaxKnown(false);
}
+ setLayouted(false);
+ setMinMaxKnown(false);
}
}
-void RenderFlow::layout()
+void RenderBlock::layout()
{
-// kdDebug( 6040 ) << renderName() << " " << this << "::layout() start" << endl;
-// QTime t;
-// t.start();
+ // kdDebug( 6040 ) << renderName() << " " << this << "::layout() start" << endl;
+ // QTime t;
+ // t.start();
KHTMLAssert( !layouted() );
KHTMLAssert( minMaxKnown() );
if (isInline()) // Inline <form>s inside various table elements can cause us to
return; // come in here. Just bail. -dwh
-
+
int oldWidth = m_width;
calcWidth();
m_overflowWidth = m_width;
-
+
bool relayoutChildren = false;
if ( oldWidth != m_width )
relayoutChildren = true;
// need a small hack here, as tables are done a bit differently
- if ( isTableCell() ) //&& static_cast<RenderTableCell *>(this)->widthChanged() )
+ if ( isTableCell() )
relayoutChildren = true;
-// kdDebug( 6040 ) << specialObjects << "," << oldWidth << ","
-// << m_width << ","<< layouted() << "," << isAnonymousBox() << ","
-// << overhangingContents() << "," << isPositioned() << endl;
+ // kdDebug( 6040 ) << specialObjects << "," << oldWidth << ","
+ // << m_width << ","<< layouted() << "," << isAnonymousBox() << ","
+ // << overhangingContents() << "," << isPositioned() << endl;
#ifdef DEBUG_LAYOUT
kdDebug( 6040 ) << renderName() << "(RenderFlow) " << this << " ::layout() width=" << m_width << ", layouted=" << layouted() << endl;
@@ -265,24 +398,6 @@ void RenderFlow::layout()
kdDebug( 6040 ) << renderName() << ": containingBlock == this" << endl;
#endif
- // This is an incorrect optimization. You cannot know at this point whether or not a child will overhang
- // in the horizontal direction without laying out your children. The following test case illustrates this
- // point, as it will fail with this code commented back in.
- // <html>
- // <body style="width:0px">
- // Hello world!
- // </body>
- // </html>
- //
- // In the real world, this affects (as of 7/24/2002) http://viamichelin.com/. -- dwh
- //
- /* if(m_width<=0 && !isPositioned() && !overhangingContents()) {
- if(m_y < 0) m_y = 0;
- setLayouted();
- return;
- }
- */
-
clearFloats();
m_height = 0;
@@ -301,22 +416,22 @@ void RenderFlow::layout()
// no margins, so we don't fill in the values for table cells.
if (!isTableCell()) {
initMaxMarginValues();
-
+
m_topMarginQuirk = style()->marginTop().quirk;
m_bottomMarginQuirk = style()->marginBottom().quirk;
-
+
if (element() && element()->id() == ID_FORM && element()->isMalformed())
// See if this form is malformed (i.e., unclosed). If so, don't give the form
// a bottom margin.
m_maxBottomPosMargin = m_maxBottomNegMargin = 0;
}
-
+
// A quirk that has become an unfortunate standard. Positioned elements, floating elements
// and table cells don't ever collapse their margins with either themselves or their
// children.
bool canCollapseOwnMargins = !isPositioned() && !isFloating() && !isTableCell();
-
-// kdDebug( 6040 ) << "childrenInline()=" << childrenInline() << endl;
+
+ // kdDebug( 6040 ) << "childrenInline()=" << childrenInline() << endl;
if(childrenInline())
layoutInlineChildren( relayoutChildren );
else
@@ -326,29 +441,29 @@ void RenderFlow::layout()
calcHeight();
if (oldHeight != m_height) {
relayoutChildren = true;
-
+
// If the block got expanded in size, then increase our overflowheight to match.
if (m_overflowHeight > m_height)
m_overflowHeight -= (borderBottom()+paddingBottom());
if (m_overflowHeight < m_height)
m_overflowHeight = m_height;
}
-
+
if (isTableCell()) {
// Table cells need to grow to accommodate both overhanging floats and
// blocks that have overflowed content.
// Check for an overhanging float first.
// FIXME: This needs to look at the last flow, not the last child.
if (lastChild() && lastChild()->hasOverhangingFloats() ) {
- KHTMLAssert(lastChild()->isFlow());
- m_height = lastChild()->yPos() + static_cast<RenderFlow*>(lastChild())->floatBottom();
+ KHTMLAssert(lastChild()->isRenderBlock());
+ m_height = lastChild()->yPos() + static_cast<RenderBlock*>(lastChild())->floatBottom();
m_height += borderBottom() + paddingBottom();
}
-
+
if (m_overflowHeight > m_height)
m_height = m_overflowHeight + borderBottom() + paddingBottom();
}
-
+
if( hasOverhangingFloats() && (isFloating() || isTableCell())) {
m_height = floatBottom();
m_height += borderBottom() + paddingBottom();
@@ -364,7 +479,7 @@ void RenderFlow::layout()
// together.
// When blocks are self-collapsing, we just use the top margin values and set the
// bottom margin max values to 0. This way we don't factor in the values
- // twice when we collapse with our previous vertically adjacent and
+ // twice when we collapse with our previous vertically adjacent and
// following vertically adjacent blocks.
if (m_maxBottomPosMargin > m_maxTopPosMargin)
m_maxTopPosMargin = m_maxBottomPosMargin;
@@ -376,7 +491,7 @@ void RenderFlow::layout()
// Always ensure our overflow width is at least as large as our width.
if (m_overflowWidth < m_width)
m_overflowWidth = m_width;
-
+
// overflow:hidden will just clip, so we don't have overflow.
if (style()->overflow()==OHIDDEN) {
m_overflowHeight = m_height;
@@ -386,26 +501,7 @@ void RenderFlow::layout()
setLayouted();
}
-void RenderFlow::layoutSpecialObjects( bool relayoutChildren )
-{
- if(specialObjects) {
- //kdDebug( 6040 ) << renderName() << " " << this << "::layoutSpecialObjects() start" << endl;
- SpecialObject* r;
- QPtrListIterator<SpecialObject> it(*specialObjects);
- for ( ; (r = it.current()); ++it ) {
- //kdDebug(6040) << " have a positioned object" << endl;
- if (r->type == SpecialObject::Positioned) {
- if ( relayoutChildren )
- r->node->setLayouted( false );
- if ( !r->node->layouted() )
- r->node->layout();
- }
- }
- specialObjects->sort();
- }
-}
-
-void RenderFlow::layoutBlockChildren( bool relayoutChildren )
+void RenderBlock::layoutBlockChildren( bool relayoutChildren )
{
#ifdef DEBUG_LAYOUT
kdDebug( 6040 ) << renderName() << " layoutBlockChildren( " << this <<" ), relayoutChildren="<< relayoutChildren << endl;
@@ -419,64 +515,66 @@ void RenderFlow::layoutBlockChildren( bool relayoutChildren )
xPos += borderLeft() + paddingLeft();
m_height += borderTop() + paddingTop();
toAdd += borderBottom() + paddingBottom();
-
+
int minHeight = m_height + toAdd;
m_overflowHeight = m_height;
-
+
if( style()->direction() == RTL ) {
xPos = marginLeft() + m_width - paddingRight() - borderRight();
}
RenderObject *child = firstChild();
- RenderFlow *prevFlow = 0;
+ RenderBlock *prevFlow = 0;
// Whether or not we can collapse our own margins with our children. We don't do this
// if we had any border/padding (obviously), if we're the root or HTML elements, or if
// we're positioned, floating, a table cell.
- bool canCollapseWithChildren = !isRoot() && !isHtml() && !isPositioned() &&
- !isFloating() && !isTableCell() && (m_height == 0);
-
+ // For now we only worry about the top border/padding. We will update the variable's
+ // value when it comes time to check against the bottom border/padding.
+ bool canCollapseWithChildren = !isRoot() && !isHtml() && !isPositioned() &&
+ !isFloating() && !isTableCell() && (m_height == 0);
+
// Whether or not we are a quirky container, i.e., do we collapse away top and bottom
// margins in our container.
bool quirkContainer = isTableCell() || isBody();
-
+
// Sometimes an element will be shoved down away from a previous sibling, e.g., when
// clearing to pass beyond a float. In this case, you don't need to collapse. This
// boolean is updated with each iteration through our child list to reflect whether
// that particular child should be collapsed with its previous sibling (or with the top
// of the block).
bool shouldCollapseChild = true;
-
+
// This flag tracks whether the child should collapse with the top margins of the block.
- // It can remain set through multiple iterations as long as we keep encountering
+ // It can remain set through multiple iterations as long as we keep encountering
// self-collapsing blocks.
bool topMarginContributor = true;
-
+
// These flags track the previous maximal positive and negative margins.
int prevPosMargin = canCollapseWithChildren ? maxTopMargin(true) : 0;
int prevNegMargin = canCollapseWithChildren ? maxTopMargin(false) : 0;
-
+
// Whether or not we encountered an element with clear set that actually had to
// be pushed down below a float.
int clearOccurred = false;
-
+
int oldPosMargin = prevPosMargin;
int oldNegMargin = prevNegMargin;
-
+
bool topChildQuirk = false;
bool bottomChildQuirk = false;
bool determinedTopQuirk = false;
-
+
bool strictMode = isAnonymousBox() ? true : (!element()->getDocument()->inQuirksMode());
-
+
//kdDebug() << "RenderFlow::layoutBlockChildren " << prevMargin << endl;
// take care in case we inherited floats
if (child && floatBottom() > m_height)
child->setLayouted(false);
-// QTime t;
-// t.start();
+ // QTime t;
+ // t.start();
while( child != 0 )
{
@@ -484,26 +582,26 @@ void RenderFlow::layoutBlockChildren( bool relayoutChildren )
if ( relayoutChildren || floatBottom() > m_y ||
(child->isReplaced() && (child->style()->width().isPercent() || child->style()->height().isPercent())))
child->setLayouted(false);
-
-// kdDebug( 6040 ) << " " << child->renderName() << " loop " << child << ", " << child->isInline() << ", " << child->layouted() << endl;
-// kdDebug( 6040 ) << t.elapsed() << endl;
+
+ // kdDebug( 6040 ) << " " << child->renderName() << " loop " << child << ", " << child->isInline() << ", " << child->layouted() << endl;
+ // kdDebug( 6040 ) << t.elapsed() << endl;
// ### might be some layouts are done two times... FIX that.
if (child->isPositioned())
{
- static_cast<RenderFlow*>(child->containingBlock())->insertSpecialObject(child);
- //kdDebug() << "RenderFlow::layoutBlockChildren inserting positioned into " << child->containingBlock()->renderName() << endl;
-
+ static_cast<RenderBlock*>(child->containingBlock())->insertSpecialObject(child);
+ //kdDebug() << "RenderFlow::layoutBlockChildren inserting positioned into " << child->containingBlock()->renderName() << endl;
+
child = child->nextSibling();
continue;
} else if ( child->isReplaced() ) {
if ( !child->layouted() )
child->layout();
}
-
+
if ( child->isFloating() ) {
insertSpecialObject( child );
-
+
// The float should be positioned taking into account the bottom margin
// of the previous flow. We add that margin into the height, get the
// float positioned properly, and then subtract the margin out of the
@@ -513,7 +611,7 @@ void RenderFlow::layoutBlockChildren( bool relayoutChildren )
positionNewFloats();
if (prevFlow)
m_height -= prevFlow->collapsedMarginBottom();
-
+
//kdDebug() << "RenderFlow::layoutBlockChildren inserting float at "<< m_height <<" prevMargin="<<prevMargin << endl;
child = child->nextSibling();
continue;
@@ -523,14 +621,14 @@ void RenderFlow::layoutBlockChildren( bool relayoutChildren )
// we want to ensure that we don't artificially increase our height because of
// a positioned or floating child.
if ( child->style()->flowAroundFloats() && !child->isFloating() &&
- style()->width().isFixed() && child->minWidth() > lineWidth( m_height ) ) {
+ style()->width().isFixed() && child->minWidth() > lineWidth( m_height ) ) {
m_height = QMAX( m_height, floatBottom() );
shouldCollapseChild = false;
clearOccurred = true;
}
-
+
child->calcVerticalMargins();
-
+
//kdDebug(0) << "margin = " << margin << " yPos = " << m_height << endl;
// Try to guess our correct y position. In most cases this guess will
@@ -559,17 +657,17 @@ void RenderFlow::layoutBlockChildren( bool relayoutChildren )
// Get our max pos and neg top margins.
int posTop = child->maxTopMargin(true);
int negTop = child->maxTopMargin(false);
-
+
// XXX A hack we have to put in to deal with the fact
// that KHTML morphs inlines with blocks
// inside them into blocks themselves. -dwh
if (!strictMode && child->style()->display() == INLINE && child->marginTop())
posTop = negTop = 0;
-
+
// See if the top margin is quirky. We only care if this child has
// margins that will collapse with us.
bool topQuirk = child->isTopMarginQuirk();
-
+
if (canCollapseWithChildren && topMarginContributor && !clearOccurred) {
// This child is collapsing with the top of the
// block. If it has larger margin values, then we need to update
@@ -577,11 +675,11 @@ void RenderFlow::layoutBlockChildren( bool relayoutChildren )
if (strictMode || !quirkContainer || !topQuirk) {
if (posTop > m_maxTopPosMargin)
m_maxTopPosMargin = posTop;
-
+
if (negTop > m_maxTopNegMargin)
m_maxTopNegMargin = negTop;
}
-
+
// The minute any of the margins involved isn't a quirk, don't
// collapse it away, even if the margin is smaller (www.webreference.com
// has an example of this, a <dt> with 0.8em author-specified inside
@@ -590,7 +688,7 @@ void RenderFlow::layoutBlockChildren( bool relayoutChildren )
m_topMarginQuirk = false;
determinedTopQuirk = true;
}
-
+
if (!determinedTopQuirk && topQuirk && marginTop() == 0)
// We have no top margin and our top child has a quirky margin.
// We will pick up this quirky margin and pass it through.
@@ -599,10 +697,10 @@ void RenderFlow::layoutBlockChildren( bool relayoutChildren )
// still apply margins in this case.
m_topMarginQuirk = true;
}
-
+
if (quirkContainer && topMarginContributor && (posTop-negTop))
topChildQuirk = topQuirk;
-
+
int ypos = m_height;
if (child->isSelfCollapsingBlock()) {
// This child has no height. Update our previous pos and neg
@@ -611,7 +709,7 @@ void RenderFlow::layoutBlockChildren( bool relayoutChildren )
prevPosMargin = posTop;
if (negTop > prevNegMargin)
prevNegMargin = negTop;
-
+
if (!topMarginContributor)
// We need to make sure that the position of the self-collapsing block
// is correct, since it could have overflowing content
@@ -620,10 +718,10 @@ void RenderFlow::layoutBlockChildren( bool relayoutChildren )
ypos = m_height + prevPosMargin - prevNegMargin;
}
else {
- if (!topMarginContributor ||
- (!canCollapseWithChildren
- && (strictMode || !quirkContainer || !topChildQuirk)
- )) {
+ if (!topMarginContributor ||
+ (!canCollapseWithChildren
+ && (strictMode || !quirkContainer || !topChildQuirk)
+ )) {
// We're collapsing with a previous sibling's margins and not
// with the top of the block.
int absPos = prevPosMargin > posTop ? prevPosMargin : posTop;
@@ -634,18 +732,18 @@ void RenderFlow::layoutBlockChildren( bool relayoutChildren )
}
prevPosMargin = child->maxBottomMargin(true);
prevNegMargin = child->maxBottomMargin(false);
-
+
// XXX A hack we have to put in to deal with the fact
// that KHTML morphs inlines with blocks
// inside them into blocks themselves.
if (!strictMode && child->style()->display() == INLINE && child->marginBottom())
prevPosMargin = prevNegMargin = 0;
-
+
if (prevPosMargin-prevNegMargin) {
bottomChildQuirk = child->isBottomMarginQuirk();
}
}
-
+
child->setPos(child->xPos(), ypos);
if (ypos != yPosEstimate && (child->containsSpecial() || containsSpecial())) {
// Our guess was wrong. Make the child lay itself out again.
@@ -661,7 +759,7 @@ void RenderFlow::layoutBlockChildren( bool relayoutChildren )
// The child needs to be lowered. Move the child so that it just clears the float.
child->setPos(child->xPos(), m_height);
clearOccurred = true;
-
+
if (topMarginContributor) {
// We can no longer collapse with the top of the block since a clear
// occurred. The empty blocks collapse into the cleared block.
@@ -671,20 +769,20 @@ void RenderFlow::layoutBlockChildren( bool relayoutChildren )
m_maxTopPosMargin = oldPosMargin;
m_maxTopNegMargin = oldNegMargin;
}
-
+
// If our value of clear caused us to be repositioned vertically to be
// underneath a float, we have to do another layout to take into account
// the extra space we now have available.
child->setLayouted(false);
child->layout();
}
-
+
// Reset the top margin contributor to false if we encountered
// a non-empty child. This has to be done after checking for clear,
// so that margins can be reset if a clear occurred.
if (topMarginContributor && !child->isSelfCollapsingBlock())
topMarginContributor = false;
-
+
int chPos = xPos + child->marginLeft();
if(style()->direction() == LTR) {
@@ -692,20 +790,15 @@ void RenderFlow::layoutBlockChildren( bool relayoutChildren )
if ( ( style()->htmlHacks() || child->isTable() ) && child->style()->flowAroundFloats() ) {
int leftOff = leftOffset(m_height);
if (leftOff != xPos) {
- // The object is shifting right. The object might be centered, so we need to
+ // 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|
- // so that we can just pass the content width in directly to the |calcHorizontalMargins|
- // function.
+ // width computation will take into account the delta between |leftOff| and |xPos|
+ // so that we can just pass the content width in directly to the |calcHorizontalMargins|
+ // function.
// -dwh
- int cw;
- RenderObject *cb = child->containingBlock();
- if ( cb->isFlow() )
- cw = static_cast<RenderFlow *>(cb)->lineWidth( child->yPos() );
- else
- cw = cb->contentWidth();
- static_cast<RenderBox*>(child)->calcHorizontalMargins ( child->style()->marginLeft(), child->style()->marginRight(),
- cw);
+ int cw = lineWidth( child->yPos() );
+ static_cast<RenderBox*>(child)->calcHorizontalMargins
+ ( child->style()->marginLeft(), child->style()->marginRight(), cw);
chPos = leftOff + child->marginLeft();
}
}
@@ -714,7 +807,7 @@ void RenderFlow::layoutBlockChildren( bool relayoutChildren )
if ( ( style()->htmlHacks() || child->isTable() ) && child->style()->flowAroundFloats() )
chPos -= leftOffset(m_height);
}
-
+
child->setPos(chPos, child->yPos());
m_height += child->height();
@@ -723,13 +816,13 @@ void RenderFlow::layoutBlockChildren( bool relayoutChildren )
if (m_height + overflowDelta > m_overflowHeight)
m_overflowHeight = m_height + overflowDelta;
}
-
- if (child->isFlow())
- prevFlow = static_cast<RenderFlow*>(child);
+
+ if (child->isRenderBlock())
+ prevFlow = static_cast<RenderBlock*>(child);
if ( child->hasOverhangingFloats() ) {
// need to add the float to our special objects
- addOverHangingFloats( static_cast<RenderFlow *>(child), -child->xPos(), -child->yPos(), true );
+ addOverHangingFloats( static_cast<RenderBlock *>(child), -child->xPos(), -child->yPos(), true );
}
// See if this child has made our overflow need to grow.
@@ -737,101 +830,191 @@ void RenderFlow::layoutBlockChildren( bool relayoutChildren )
int rightChildPos = child->overflowWidth() + child->xPos();
if (rightChildPos > m_overflowWidth)
m_overflowWidth = rightChildPos;
-
+
child = child->nextSibling();
}
bool autoHeight = style()->height().isVariable() && style()->height().value == 0;
-
+
// If any height other than auto is specified in CSS, then we don't collapse our bottom
- // margins with our children's margins. To do otherwise would be to risk odd visual
+ // margins with our children's margins. To do otherwise would be to risk odd visual
// effects when the children overflow out of the parent block and yet still collapse
- // with it. We also don't collapse if we had any bottom border/padding (represented by
- // |toAdd|.
+ // with it. We also don't collapse if we had any bottom border/padding (represented by
+ // |toAdd|).
if (canCollapseWithChildren && (toAdd || !autoHeight))
canCollapseWithChildren = false;
-
+
// If we can't collapse with children then go ahead and add in the bottom margins.
- if (!canCollapseWithChildren
- && (strictMode || !quirkContainer || !bottomChildQuirk))
+ if (!canCollapseWithChildren
+ && (strictMode || !quirkContainer || !bottomChildQuirk))
m_height += prevPosMargin - prevNegMargin;
-
+
m_height += toAdd;
-
+
// Negative margins can cause our height to shrink below our minimal height (border/padding).
// If this happens, ensure that the computed height is increased to the minimal height.
if (m_height < minHeight)
m_height = minHeight;
-
+
// Always make sure our overflowheight is at least our height.
if (m_overflowHeight < m_height)
m_overflowHeight = m_height;
-
+
if (canCollapseWithChildren && !topMarginContributor) {
// Update our max pos/neg bottom margins, since we collapsed our bottom margins
// with our children.
if (prevPosMargin > m_maxBottomPosMargin)
m_maxBottomPosMargin = prevPosMargin;
-
+
if (prevNegMargin > m_maxBottomNegMargin)
m_maxBottomNegMargin = prevNegMargin;
-
+
if (!bottomChildQuirk)
m_bottomMarginQuirk = false;
-
+
if (bottomChildQuirk && marginBottom() == 0)
// We have no bottom margin and our last child has a quirky margin.
// We will pick up this quirky margin and pass it through.
// This deals with the <td><div><p> case.
m_bottomMarginQuirk = true;
}
-
+
setLayouted();
// kdDebug( 6040 ) << "layouted = " << layouted_ << endl;
}
-bool RenderFlow::checkClear(RenderObject *child)
+void RenderBlock::layoutSpecialObjects( bool relayoutChildren )
{
- //kdDebug( 6040 ) << "checkClear oldheight=" << m_height << endl;
- int bottom = 0;
- switch(child->style()->clear())
+ if (m_specialObjects) {
+ //kdDebug( 6040 ) << renderName() << " " << this << "::layoutSpecialObjects() start" << endl;
+ SpecialObject* r;
+ QPtrListIterator<SpecialObject> it(*m_specialObjects);
+ for ( ; (r = it.current()); ++it ) {
+ //kdDebug(6040) << " have a positioned object" << endl;
+ if (r->type == SpecialObject::Positioned) {
+ if ( relayoutChildren )
+ r->node->setLayouted( false );
+ if ( !r->node->layouted() )
+ r->node->layout();
+ }
+ }
+ m_specialObjects->sort();
+ }
+}
+
+void RenderBlock::paint(QPainter* p, int _x, int _y, int _w, int _h, int _tx, int _ty, PaintAction paintAction)
+{
+ _tx += m_x;
+ _ty += m_y;
+
+ // check if we need to do anything at all...
+ if (!overhangingContents() && !isRelPositioned() && !isPositioned() )
{
- case CNONE:
- return false;
- case CLEFT:
- bottom = leftBottom();
- break;
- case CRIGHT:
- bottom = rightBottom();
- break;
- case CBOTH:
- bottom = floatBottom();
- break;
+ int h = m_height;
+ if(m_specialObjects && floatBottom() > h) h = floatBottom();
+ if((_ty > _y + _h) || (_ty + h < _y))
+ {
+ //kdDebug( 6040 ) << "cut!" << endl;
+ return;
+ }
}
-
- if (m_height < bottom) {
- m_height = bottom;
- return true;
+
+ paintObject(p, _x, _y, _w, _h, _tx, _ty, paintAction);
+}
+
+void RenderBlock::paintObject(QPainter *p, int _x, int _y,
+ int _w, int _h, int _tx, int _ty, PaintAction paintAction)
+{
+
+#ifdef DEBUG_LAYOUT
+ // kdDebug( 6040 ) << renderName() << "(RenderBlock) " << this << " ::paintObject() w/h = (" << width() << "/" << height() << ")" << endl;
+#endif
+
+ // 1. paint background, borders etc
+ if (paintAction == PaintActionBackground &&
+ shouldPaintBackgroundOrBorder() && style()->visibility() == VISIBLE )
+ paintBoxDecorations(p, _x, _y, _w, _h, _tx, _ty);
+
+ // 2. paint contents
+ RenderObject *child = firstChild();
+ while(child != 0)
+ {
+ if(!child->layer() && !child->isFloating())
+ child->paint(p, _x, _y, _w, _h, _tx, _ty, paintAction);
+ child = child->nextSibling();
}
- return false;
+
+ // 3. paint floats.
+ if (paintAction == PaintActionFloat || paintAction == PaintActionSelection)
+ paintFloats(p, _x, _y, _w, _h, _tx, _ty, paintAction == PaintActionSelection);
+
+ if (paintAction == PaintActionBackground &&
+ !childrenInline() && style()->outlineWidth())
+ paintOutline(p, _tx, _ty, width(), height(), style());
+
+#ifdef BOX_DEBUG
+ if ( style() && style()->visibility() == VISIBLE ) {
+ if(isAnonymousBox())
+ outlineBox(p, _tx, _ty, "green");
+ if(isFloating())
+ outlineBox(p, _tx, _ty, "yellow");
+ else
+ outlineBox(p, _tx, _ty);
+ }
+#endif
}
-void RenderFlow::insertSpecialObject(RenderObject *o)
+void RenderBlock::paintFloats(QPainter *p, int _x, int _y,
+ int _w, int _h, int _tx, int _ty, bool paintSelection)
+{
+ if (!m_specialObjects)
+ return;
+
+ SpecialObject* r;
+ QPtrListIterator<SpecialObject> it(*m_specialObjects);
+ for ( ; (r = it.current()); ++it) {
+ // Only paint the object if our noPaint flag isn't set.
+ if (r->node->isFloating() && !r->noPaint) {
+ if (paintSelection) {
+ r->node->paint(p, _x, _y, _w, _h,
+ _tx + r->left - r->node->xPos() + r->node->marginLeft(),
+ _ty + r->startY - r->node->yPos() + r->node->marginTop(),
+ PaintActionSelection);
+ }
+ else {
+ r->node->paint(p, _x, _y, _w, _h,
+ _tx + r->left - r->node->xPos() + r->node->marginLeft(),
+ _ty + r->startY - r->node->yPos() + r->node->marginTop(),
+ PaintActionBackground);
+ r->node->paint(p, _x, _y, _w, _h,
+ _tx + r->left - r->node->xPos() + r->node->marginLeft(),
+ _ty + r->startY - r->node->yPos() + r->node->marginTop(),
+ PaintActionFloat);
+ r->node->paint(p, _x, _y, _w, _h,
+ _tx + r->left - r->node->xPos() + r->node->marginLeft(),
+ _ty + r->startY - r->node->yPos() + r->node->marginTop(),
+ PaintActionForeground);
+ }
+ }
+ }
+}
+
+void RenderBlock::insertSpecialObject(RenderObject *o)
{
// Create the list of special objects if we don't aleady have one
- if (!specialObjects) {
- specialObjects = new QSortedList<SpecialObject>;
- specialObjects->setAutoDelete(true);
+ if (!m_specialObjects) {
+ m_specialObjects = new QSortedList<SpecialObject>;
+ m_specialObjects->setAutoDelete(true);
}
else {
- // Don't insert the object again if it's already in the list
- QPtrListIterator<SpecialObject> it(*specialObjects);
- SpecialObject* f;
- while ( (f = it.current()) ) {
- if (f->node == o) return;
- ++it;
- }
+ // Don't insert the object again if it's already in the list
+ QPtrListIterator<SpecialObject> it(*m_specialObjects);
+ SpecialObject* f;
+ while ( (f = it.current()) ) {
+ if (f->node == o) return;
+ ++it;
+ }
}
// Create the special object entry & append it to the list
@@ -843,55 +1026,55 @@ void RenderFlow::insertSpecialObject(RenderObject *o)
setOverhangingContents();
}
else if (o->isFloating()) {
- // floating object
- if ( !o->layouted() )
- o->layout();
-
- if(o->style()->floating() == FLEFT)
- newObj = new SpecialObject(SpecialObject::FloatLeft);
- else
- newObj = new SpecialObject(SpecialObject::FloatRight);
-
- newObj->startY = -1;
- newObj->endY = -1;
- newObj->width = o->width() + o->marginLeft() + o->marginRight();
+ // floating object
+ if ( !o->layouted() )
+ o->layout();
+
+ if(o->style()->floating() == FLEFT)
+ newObj = new SpecialObject(SpecialObject::FloatLeft);
+ else
+ newObj = new SpecialObject(SpecialObject::FloatRight);
+
+ newObj->startY = -1;
+ newObj->endY = -1;
+ newObj->width = o->width() + o->marginLeft() + o->marginRight();
}
else {
- // We should never get here, as insertSpecialObject() should only ever be called with positioned or floating
- // objects.
- KHTMLAssert(false);
+ // We should never get here, as insertSpecialObject() should only ever be called with positioned or floating
+ // objects.
+ KHTMLAssert(false);
newObj = 0; // keep gcc's uninitialized variable warnings happy
}
- newObj->count = specialObjects->count();
+ newObj->count = m_specialObjects->count();
newObj->node = o;
- specialObjects->append(newObj);
+ m_specialObjects->append(newObj);
}
-void RenderFlow::removeSpecialObject(RenderObject *o)
+void RenderBlock::removeSpecialObject(RenderObject *o)
{
- if (specialObjects) {
- QPtrListIterator<SpecialObject> it(*specialObjects);
- while (it.current()) {
- if (it.current()->node == o)
- specialObjects->removeRef(it.current());
- ++it;
- }
+ if (m_specialObjects) {
+ QPtrListIterator<SpecialObject> it(*m_specialObjects);
+ while (it.current()) {
+ if (it.current()->node == o)
+ m_specialObjects->removeRef(it.current());
+ ++it;
+ }
}
}
-void RenderFlow::positionNewFloats()
+void RenderBlock::positionNewFloats()
{
- if(!specialObjects) return;
- SpecialObject *f = specialObjects->getLast();
+ if(!m_specialObjects) return;
+ SpecialObject *f = m_specialObjects->getLast();
if(!f || f->startY != -1) return;
SpecialObject *lastFloat;
while(1)
{
- lastFloat = specialObjects->prev();
+ lastFloat = m_specialObjects->prev();
if(!lastFloat || (lastFloat->startY != -1 && !(lastFloat->type==SpecialObject::Positioned) )) {
- specialObjects->next();
+ m_specialObjects->next();
break;
}
f = lastFloat;
@@ -910,7 +1093,7 @@ void RenderFlow::positionNewFloats()
//skip elements copied from elsewhere and positioned elements
if (f->node->containingBlock()!=this || f->type==SpecialObject::Positioned)
{
- f = specialObjects->next();
+ f = m_specialObjects->next();
continue;
}
@@ -920,15 +1103,15 @@ void RenderFlow::positionNewFloats()
int ro = rightOffset(); // Constant part of right offset.
int lo = leftOffset(); // Constat part of left offset.
int fwidth = f->width; // The width we look for.
- //kdDebug( 6040 ) << " Object width: " << fwidth << " available width: " << ro - lo << endl;
+ //kdDebug( 6040 ) << " Object width: " << fwidth << " available width: " << ro - lo << endl;
if (ro - lo < fwidth)
fwidth = ro - lo; // Never look for more than what will be available.
if (o->style()->floating() == FLEFT)
{
- if ( o->style()->clear() & CLEFT )
- y = QMAX( leftBottom(), y );
- int heightRemainingLeft = 1;
- int heightRemainingRight = 1;
+ if ( o->style()->clear() & CLEFT )
+ y = QMAX( leftBottom(), y );
+ int heightRemainingLeft = 1;
+ int heightRemainingRight = 1;
int fx = leftRelOffset(y,lo, &heightRemainingLeft);
while (rightRelOffset(y,ro, &heightRemainingRight)-fx < fwidth)
{
@@ -942,10 +1125,10 @@ void RenderFlow::positionNewFloats()
}
else
{
- if ( o->style()->clear() & CRIGHT )
- y = QMAX( rightBottom(), y );
- int heightRemainingLeft = 1;
- int heightRemainingRight = 1;
+ if ( o->style()->clear() & CRIGHT )
+ y = QMAX( rightBottom(), y );
+ int heightRemainingLeft = 1;
+ int heightRemainingRight = 1;
int fx = rightRelOffset(y,ro, &heightRemainingRight);
while (fx - leftRelOffset(y,lo, &heightRemainingLeft) < fwidth)
{
@@ -957,51 +1140,50 @@ void RenderFlow::positionNewFloats()
//kdDebug( 6040 ) << "positioning right aligned float at (" << fx - o->marginRight() - o->width() << "/" << y + o->marginTop() << ")" << endl;
o->setPos(fx - o->marginRight() - o->width(), y + o->marginTop());
}
- f->startY = y;
+ f->startY = y;
f->endY = f->startY + _height;
- //kdDebug( 6040 ) << "specialObject x/y= (" << f->left << "/" << f->startY << "-" << f->width << "/" << f->endY - f->startY << ")" << endl;
+ //kdDebug( 6040 ) << "specialObject x/y= (" << f->left << "/" << f->startY << "-" << f->width << "/" << f->endY - f->startY << ")" << endl;
- f = specialObjects->next();
+ f = m_specialObjects->next();
}
}
-void RenderFlow::newLine()
+void RenderBlock::newLine()
{
positionNewFloats();
// set y position
int newY = 0;
switch(m_clearStatus)
{
- case CLEFT:
- newY = leftBottom();
- break;
- case CRIGHT:
- newY = rightBottom();
- break;
- case CBOTH:
- newY = floatBottom();
- default:
- break;
+ case CLEFT:
+ newY = leftBottom();
+ break;
+ case CRIGHT:
+ newY = rightBottom();
+ break;
+ case CBOTH:
+ newY = floatBottom();
+ default:
+ break;
}
if(m_height < newY)
{
-// kdDebug( 6040 ) << "adjusting y position" << endl;
+ // kdDebug( 6040 ) << "adjusting y position" << endl;
m_height = newY;
}
m_clearStatus = CNONE;
}
-
int
-RenderFlow::leftOffset() const
+RenderBlock::leftOffset() const
{
int left = 0;
left += borderLeft() + paddingLeft();
- if ( firstLine && style()->direction() == LTR ) {
+ if ( m_firstLine && style()->direction() == LTR ) {
int cw=0;
if (style()->textIndent().isPercent())
cw = containingBlock()->contentWidth();
@@ -1012,37 +1194,37 @@ RenderFlow::leftOffset() const
}
int
-RenderFlow::leftRelOffset(int y, int fixedOffset, int *heightRemaining ) const
+RenderBlock::leftRelOffset(int y, int fixedOffset, int *heightRemaining ) const
{
int left = fixedOffset;
- if(!specialObjects)
- return left;
+ if(!m_specialObjects)
+ return left;
if ( heightRemaining ) *heightRemaining = 1;
SpecialObject* r;
- QPtrListIterator<SpecialObject> it(*specialObjects);
+ QPtrListIterator<SpecialObject> it(*m_specialObjects);
for ( ; (r = it.current()); ++it )
{
- //kdDebug( 6040 ) <<(void *)this << " left: sy, ey, x, w " << r->startY << "," << r->endY << "," << r->left << "," << r->width << " " << endl;
+ //kdDebug( 6040 ) <<(void *)this << " left: sy, ey, x, w " << r->startY << "," << r->endY << "," << r->left << "," << r->width << " " << endl;
if (r->startY <= y && r->endY > y &&
r->type == SpecialObject::FloatLeft &&
r->left + r->width > left) {
- left = r->left + r->width;
- if ( heightRemaining ) *heightRemaining = r->endY - y;
- }
+ left = r->left + r->width;
+ if ( heightRemaining ) *heightRemaining = r->endY - y;
+ }
}
//kdDebug( 6040 ) << "leftOffset(" << y << ") = " << left << endl;
return left;
}
int
-RenderFlow::rightOffset() const
+RenderBlock::rightOffset() const
{
int right = m_width;
right -= borderRight() + paddingRight();
- if ( firstLine && style()->direction() == RTL ) {
+ if ( m_firstLine && style()->direction() == RTL ) {
int cw=0;
if (style()->textIndent().isPercent())
cw = containingBlock()->contentWidth();
@@ -1053,43 +1235,43 @@ RenderFlow::rightOffset() const
}
int
-RenderFlow::rightRelOffset(int y, int fixedOffset, int *heightRemaining ) const
+RenderBlock::rightRelOffset(int y, int fixedOffset, int *heightRemaining ) const
{
int right = fixedOffset;
- if (!specialObjects) return right;
+ if (!m_specialObjects) return right;
if (heightRemaining) *heightRemaining = 1;
SpecialObject* r;
- QPtrListIterator<SpecialObject> it(*specialObjects);
+ QPtrListIterator<SpecialObject> it(*m_specialObjects);
for ( ; (r = it.current()); ++it )
{
- //kdDebug( 6040 ) << "right: sy, ey, x, w " << r->startY << "," << r->endY << "," << r->left << "," << r->width << " " << endl;
+ //kdDebug( 6040 ) << "right: sy, ey, x, w " << r->startY << "," << r->endY << "," << r->left << "," << r->width << " " << endl;
if (r->startY <= y && r->endY > y &&
r->type == SpecialObject::FloatRight &&
r->left < right) {
- right = r->left;
- if ( heightRemaining ) *heightRemaining = r->endY - y;
- }
+ right = r->left;
+ if ( heightRemaining ) *heightRemaining = r->endY - y;
+ }
}
//kdDebug( 6040 ) << "rightOffset(" << y << ") = " << right << endl;
return right;
}
unsigned short
-RenderFlow::lineWidth(int y) const
+RenderBlock::lineWidth(int y) const
{
//kdDebug( 6040 ) << "lineWidth(" << y << ")=" << rightOffset(y) - leftOffset(y) << endl;
return rightOffset(y) - leftOffset(y);
}
int
-RenderFlow::nearestFloatBottom(int height) const
+RenderBlock::nearestFloatBottom(int height) const
{
- if (!specialObjects) return 0;
+ if (!m_specialObjects) return 0;
int bottom=0;
SpecialObject* r;
- QPtrListIterator<SpecialObject> it(*specialObjects);
+ QPtrListIterator<SpecialObject> it(*m_specialObjects);
for ( ; (r = it.current()); ++it )
if (r->endY>height && (r->endY<bottom || bottom==0) && (int)r->type <= (int)SpecialObject::FloatRight)
bottom=r->endY;
@@ -1097,12 +1279,12 @@ RenderFlow::nearestFloatBottom(int height) const
}
int
-RenderFlow::floatBottom() const
+RenderBlock::floatBottom() const
{
- if (!specialObjects) return 0;
+ if (!m_specialObjects) return 0;
int bottom=0;
SpecialObject* r;
- QPtrListIterator<SpecialObject> it(*specialObjects);
+ QPtrListIterator<SpecialObject> it(*m_specialObjects);
for ( ; (r = it.current()); ++it )
if (r->endY>bottom && (int)r->type <= (int)SpecialObject::FloatRight)
bottom=r->endY;
@@ -1110,7 +1292,7 @@ RenderFlow::floatBottom() const
}
int
-RenderFlow::lowestPosition() const
+RenderBlock::lowestPosition() const
{
int bottom = RenderBox::lowestPosition();
//kdDebug(0) << renderName() << "("<<this<<") lowest = " << bottom << endl;
@@ -1129,9 +1311,9 @@ RenderFlow::lowestPosition() const
//kdDebug(0) << " bottom = " << bottom << endl;
- if (specialObjects) {
+ if (m_specialObjects) {
SpecialObject* r;
- QPtrListIterator<SpecialObject> it(*specialObjects);
+ QPtrListIterator<SpecialObject> it(*m_specialObjects);
for ( ; (r = it.current()); ++it ) {
lp = 0;
if ( r->type == SpecialObject::FloatLeft || r->type == SpecialObject::FloatRight ){
@@ -1148,19 +1330,19 @@ RenderFlow::lowestPosition() const
if ( overhangingContents() ) {
RenderObject *child = firstChild();
while( child ) {
- if ( child != last && child->overhangingContents() ) {
- int lp = child->yPos() + child->lowestPosition();
- if ( lp > bottom ) bottom = lp;
- }
- child = child->nextSibling();
- }
+ if ( child != last && child->overhangingContents() ) {
+ int lp = child->yPos() + child->lowestPosition();
+ if ( lp > bottom ) bottom = lp;
+ }
+ child = child->nextSibling();
+ }
}
//kdDebug(0) << renderName() << " bottom final = " << bottom << endl;
return bottom;
}
-int RenderFlow::rightmostPosition() const
+int RenderBlock::rightmostPosition() const
{
int right = RenderBox::rightmostPosition();
@@ -1173,9 +1355,9 @@ int RenderFlow::rightmostPosition() const
}
}
- if (specialObjects) {
+ if (m_specialObjects) {
SpecialObject* r;
- QPtrListIterator<SpecialObject> it(*specialObjects);
+ QPtrListIterator<SpecialObject> it(*m_specialObjects);
for ( ; (r = it.current()); ++it ) {
int specialRight=0;
if ( r->type == SpecialObject::FloatLeft || r->type == SpecialObject::FloatRight ){
@@ -1184,19 +1366,19 @@ int RenderFlow::rightmostPosition() const
specialRight = r->node->xPos() + r->node->rightmostPosition();
}
if (specialRight > right)
- right = specialRight;
+ right = specialRight;
}
}
if ( overhangingContents() ) {
RenderObject *child = firstChild();
while( child ) {
- if ( (child->isPositioned() || child->isFloating()) && child->overhangingContents() ) {
- int r = child->xPos() + child->rightmostPosition();
- if ( r > right ) right = r;
- }
- child = child->nextSibling();
- }
+ if ( (child->isPositioned() || child->isFloating()) && child->overhangingContents() ) {
+ int r = child->xPos() + child->rightmostPosition();
+ if ( r > right ) right = r;
+ }
+ child = child->nextSibling();
+ }
}
return right;
@@ -1204,12 +1386,12 @@ int RenderFlow::rightmostPosition() const
int
-RenderFlow::leftBottom()
+RenderBlock::leftBottom()
{
- if (!specialObjects) return 0;
+ if (!m_specialObjects) return 0;
int bottom=0;
SpecialObject* r;
- QPtrListIterator<SpecialObject> it(*specialObjects);
+ QPtrListIterator<SpecialObject> it(*m_specialObjects);
for ( ; (r = it.current()); ++it )
if (r->endY>bottom && r->type == SpecialObject::FloatLeft)
bottom=r->endY;
@@ -1218,12 +1400,12 @@ RenderFlow::leftBottom()
}
int
-RenderFlow::rightBottom()
+RenderBlock::rightBottom()
{
- if (!specialObjects) return 0;
+ if (!m_specialObjects) return 0;
int bottom=0;
SpecialObject* r;
- QPtrListIterator<SpecialObject> it(*specialObjects);
+ QPtrListIterator<SpecialObject> it(*m_specialObjects);
for ( ; (r = it.current()); ++it )
if (r->endY>bottom && r->type == SpecialObject::FloatRight)
bottom=r->endY;
@@ -1232,21 +1414,20 @@ RenderFlow::rightBottom()
}
void
-RenderFlow::clearFloats()
+RenderBlock::clearFloats()
{
//kdDebug( 6040 ) << this <<" clearFloats" << endl;
-
- if (specialObjects) {
- if( overhangingContents() ) {
- specialObjects->first();
- while ( specialObjects->current()) {
- if ( !(specialObjects->current()->type == SpecialObject::Positioned) )
- specialObjects->remove();
+ if (m_specialObjects) {
+ if( overhangingContents() ) {
+ m_specialObjects->first();
+ while ( m_specialObjects->current()) {
+ if ( !(m_specialObjects->current()->type == SpecialObject::Positioned) )
+ m_specialObjects->remove();
else
- specialObjects->next();
- }
- } else
- specialObjects->clear();
+ m_specialObjects->next();
+ }
+ } else
+ m_specialObjects->clear();
}
if (isFloating() || isPositioned()) return;
@@ -1258,23 +1439,23 @@ RenderFlow::clearFloats()
// pass fAF's unless they contain overhanging stuff
bool parentHasFloats = false;
while (prev) {
- if (!prev->isFlow() || prev->isFloating() ||
- (prev->style()->flowAroundFloats() &&
- // A <table> or <ul> can have a height of 0, so its ypos may be the same
- // as m_y. That's why we have a <= and not a < here. -dwh
- (static_cast<RenderFlow *>(prev)->floatBottom()+prev->yPos() <= m_y ))) {
- if ( prev->isFloating() && parent()->isFlow() ) {
- parentHasFloats = true;
- }
- prev = prev->previousSibling();
- } else
- break;
+ if (!(prev->isRenderBlock() && prev->isRenderInline()) || prev->isFloating() ||
+ (prev->style()->flowAroundFloats() &&
+ // A <table> or <ul> can have a height of 0, so its ypos may be the same
+ // as m_y. That's why we have a <= and not a < here. -dwh
+ (static_cast<RenderBlock *>(prev)->floatBottom()+prev->yPos() <= m_y ))) {
+ if ( prev->isFloating() && parent()->isRenderBlock() ) {
+ parentHasFloats = true;
+ }
+ prev = prev->previousSibling();
+ } else
+ break;
}
int offset = m_y;
if ( parentHasFloats ) {
- addOverHangingFloats( static_cast<RenderFlow *>( parent() ), parent()->borderLeft() + parent()->paddingLeft() , offset, false );
+ addOverHangingFloats( static_cast<RenderBlock *>( parent() ), parent()->borderLeft() + parent()->paddingLeft() , offset, false );
}
if(prev ) {
@@ -1283,63 +1464,63 @@ RenderFlow::clearFloats()
offset -= prev->yPos();
} else {
prev = parent();
- if(!prev) return;
+ if(!prev) return;
}
//kdDebug() << "RenderFlow::clearFloats found previous "<< (void *)this << " prev=" << (void *)prev<< endl;
// add overhanging special objects from the previous RenderFlow
- if(!prev->isFlow()) return;
- RenderFlow * flow = static_cast<RenderFlow *>(prev);
- if(!flow->specialObjects) return;
+ if(!prev->isRenderBlock()) return;
+ RenderBlock * flow = static_cast<RenderBlock *>(prev);
+ if(!flow->m_specialObjects) return;
if( ( style()->htmlHacks() || isTable() ) && style()->flowAroundFloats())
return; //html tables and lists flow as blocks
if(flow->floatBottom() > offset)
- addOverHangingFloats( flow, 0, offset );
+ addOverHangingFloats( flow, 0, offset );
}
-void RenderFlow::addOverHangingFloats( RenderFlow *flow, int xoff, int offset, bool child )
+void RenderBlock::addOverHangingFloats( RenderBlock *flow, int xoff, int offset, bool child )
{
#ifdef DEBUG_LAYOUT
kdDebug( 6040 ) << (void *)this << ": adding overhanging floats xoff=" << xoff << " offset=" << offset << " child=" << child << endl;
#endif
- if ( !flow->specialObjects || (child && flow->layer()) )
+ if ( !flow->m_specialObjects || (child && flow->layer()) )
return;
// we have overhanging floats
- if(!specialObjects) {
- specialObjects = new QSortedList<SpecialObject>;
- specialObjects->setAutoDelete(true);
+ if (!m_specialObjects) {
+ m_specialObjects = new QSortedList<SpecialObject>;
+ m_specialObjects->setAutoDelete(true);
}
- QPtrListIterator<SpecialObject> it(*flow->specialObjects);
+ QPtrListIterator<SpecialObject> it(*flow->m_specialObjects);
SpecialObject *r;
for ( ; (r = it.current()); ++it ) {
if ( (int)r->type <= (int)SpecialObject::FloatRight &&
- ( ( !child && r->endY > offset ) ||
- ( child && flow->yPos() + r->endY > height() ) ) ) {
-
+ ( ( !child && r->endY > offset ) ||
+ ( child && flow->yPos() + r->endY > height() ) ) ) {
+
if (child)
r->noPaint = true;
-
+
SpecialObject* f = 0;
// don't insert it twice!
- QPtrListIterator<SpecialObject> it(*specialObjects);
+ QPtrListIterator<SpecialObject> it(*m_specialObjects);
while ( (f = it.current()) ) {
- if (f->node == r->node) break;
- ++it;
+ if (f->node == r->node) break;
+ ++it;
}
if ( !f ) {
SpecialObject *special = new SpecialObject(r->type);
- special->count = specialObjects->count();
+ special->count = m_specialObjects->count();
special->startY = r->startY - offset;
special->endY = r->endY - offset;
special->left = r->left - xoff;
- // Applying the child's margin makes no sense in the case where the child was passed in.
+ // Applying the child's margin makes no sense in the case where the child was passed in.
// since his own margin was added already through the subtraction of the |xoff| variable
// above. |xoff| will equal -flow->marginLeft() in this case, so it's already been taken
- // into account. Only apply this code if |child| is false, since otherwise the left margin
- // will get applied twice. -dwh
+ // into account. Only apply this code if |child| is false, since otherwise the left margin
+ // will get applied twice. -dwh
if (!child && flow != parent())
special->left += flow->marginLeft();
if ( !child ) {
@@ -1348,7 +1529,7 @@ void RenderFlow::addOverHangingFloats( RenderFlow *flow, int xoff, int offset, b
}
special->width = r->width;
special->node = r->node;
- specialObjects->append(special);
+ m_specialObjects->append(special);
#ifdef DEBUG_LAYOUT
kdDebug( 6040 ) << "addOverHangingFloats x/y= (" << special->left << "/" << special->startY << "-" << special->width << "/" << special->endY - special->startY << ")" << endl;
#endif
@@ -1357,6 +1538,96 @@ void RenderFlow::addOverHangingFloats( RenderFlow *flow, int xoff, int offset, b
}
}
+bool RenderBlock::checkClear(RenderObject *child)
+{
+ //kdDebug( 6040 ) << "checkClear oldheight=" << m_height << endl;
+ int bottom = 0;
+ switch(child->style()->clear())
+ {
+ case CNONE:
+ return false;
+ case CLEFT:
+ bottom = leftBottom();
+ break;
+ case CRIGHT:
+ bottom = rightBottom();
+ break;
+ case CBOTH:
+ bottom = floatBottom();
+ break;
+ }
+
+ if (m_height < bottom) {
+ m_height = bottom;
+ return true;
+ }
+ return false;
+}
+
+bool RenderBlock::nodeAtPoint(NodeInfo& info, int _x, int _y, int _tx, int _ty, bool inBox)
+{
+ if (m_specialObjects) {
+ int stx = _tx + xPos();
+ int sty = _ty + yPos();
+ if (isRoot()) {
+ stx += static_cast<RenderRoot*>(this)->view()->contentsX();
+ sty += static_cast<RenderRoot*>(this)->view()->contentsY();
+ }
+ SpecialObject* o;
+ QPtrListIterator<SpecialObject> it(*m_specialObjects);
+ for (it.toLast(); (o = it.current()); --it)
+ if (o->node->isFloating() && !o->noPaint)
+ inBox |= o->node->nodeAtPoint(info, _x, _y,
+ stx+o->left + o->node->marginLeft() - o->node->xPos(),
+ sty+o->startY + o->node->marginTop() - o->node->yPos());
+ }
+
+ inBox |= RenderFlow::nodeAtPoint(info, _x, _y, _tx, _ty, inBox);
+ return inBox;
+}
+
+void RenderBlock::calcMinMaxWidth()
+{
+ KHTMLAssert( !minMaxKnown() );
+
+#ifdef DEBUG_LAYOUT
+ kdDebug( 6040 ) << renderName() << "(RenderBlock)::calcMinMaxWidth() this=" << this << endl;
+#endif
+
+ m_minWidth = 0;
+ m_maxWidth = 0;
+
+ bool preOrNowrap = style()->whiteSpace() != NORMAL;
+ if (childrenInline())
+ calcInlineMinMaxWidth();
+ else
+ calcBlockMinMaxWidth();
+
+ if(m_maxWidth < m_minWidth) m_maxWidth = m_minWidth;
+
+ if (preOrNowrap && childrenInline())
+ m_minWidth = m_maxWidth;
+
+ if (style()->width().isFixed() && style()->width().value > 0)
+ m_maxWidth = KMAX(m_minWidth,short(style()->width().value));
+
+ int toAdd = 0;
+ toAdd = borderLeft() + borderRight() + paddingLeft() + paddingRight();
+
+ m_minWidth += toAdd;
+ m_maxWidth += toAdd;
+
+ // Scrolling marquees like to use this trick:
+ // <td><div style="overflow:hidden; width:300px"><nobr>.....[lots of text].....</nobr></div></td>
+ // We need to sanity-check our m_minWidth, and not let it exceed our clipped boundary. -dwh
+ if (style()->overflow() == OHIDDEN && m_minWidth > m_width)
+ m_minWidth = m_width;
+
+ setMinMaxKnown();
+
+ //kdDebug( 6040 ) << "Text::calcMinMaxWidth(" << this << "): min = " << m_minWidth << " max = " << m_maxWidth << endl;
+ // ### compare with min/max width set in style sheet...
+}
static inline RenderObject *next(RenderObject *par, RenderObject *current)
{
@@ -1383,23 +1654,23 @@ static inline RenderObject *next(RenderObject *par, RenderObject *current)
return next;
}
-void RenderFlow::calcInlineMinMaxWidth()
+void RenderBlock::calcInlineMinMaxWidth()
{
int inlineMax=0;
int inlineMin=0;
-
+
int cw = containingBlock()->contentWidth();
RenderObject *child = firstChild();
-
+
// If we are at the start of a line, we want to ignore all white-space.
// Also strip spaces if we previously had text that ended in a trailing space.
bool stripFrontSpaces = true;
RenderObject* trailingSpaceChild = 0;
-
+
bool nowrap, oldnowrap;
nowrap = oldnowrap = style()->whiteSpace() == NOWRAP;
-
+
while(child != 0)
{
// positioned children don't affect the minmaxwidth
@@ -1410,14 +1681,14 @@ void RenderFlow::calcInlineMinMaxWidth()
}
nowrap = child->style()->whiteSpace() == NOWRAP;
-
+
if( !child->isBR() )
{
// Step One: determine whether or not we need to go ahead and
// terminate our current line. Each discrete chunk can become
// the new min-width, if it is the widest chunk seen so far, and
- // it can also become the max-width.
-
+ // it can also become the max-width.
+
// Children fall into three categories:
// (1) An inline flow object. These objects always have a min/max of 0,
// and are included in the iteration solely so that their margins can
@@ -1435,14 +1706,14 @@ void RenderFlow::calcInlineMinMaxWidth()
// (3) A text object. Text runs can have breakable characters at the start,
// the middle or the end. They may also lose whitespace off the front if
// we're already ignoring whitespace. In order to compute accurate min-width
- // information, we need three pieces of information.
+ // information, we need three pieces of information.
// (a) the min-width of the first non-breakable run. Should be 0 if the text string
// starts with whitespace.
// (b) the min-width of the last non-breakable run. Should be 0 if the text string
// ends with whitespace.
// (c) the min/max width of the string (trimmed for whitespace).
//
- // If the text string starts with whitespace, then we need to go ahead and
+ // If the text string starts with whitespace, then we need to go ahead and
// terminate our current line (unless we're already in a whitespace stripping
// mode.
//
@@ -1455,7 +1726,7 @@ void RenderFlow::calcInlineMinMaxWidth()
RenderStyle* cstyle = child->style();
short childMin = 0;
short childMax = 0;
-
+
if (!child->isText()) {
// Case (1) and (2). Inline replaced and inline flow elements. Both
// add in their margins to their min/max values.
@@ -1468,8 +1739,8 @@ void RenderFlow::calcInlineMinMaxWidth()
margins += (type == Fixed ? cstyle->marginRight().value : child->marginRight());
childMin += margins;
childMax += margins;
-
- if (child->isInline() && child->isFlow()) {
+
+ if (child->isRenderInline()) {
// Add in padding for inline flow elements. This is wrong in the
// same way the margin addition is wrong. XXXdwh fixme.
int padding = 0;
@@ -1481,38 +1752,38 @@ void RenderFlow::calcInlineMinMaxWidth()
padding += (type == Fixed ? cstyle->paddingRight().value : child->paddingRight());
childMin += padding;
childMax += padding;
-
+
inlineMin += childMin;
inlineMax += childMax;
}
}
-
- if (!(child->isInline() && child->isFlow()) && !child->isText()) {
+
+ if (!child->isRenderInline() && !child->isText()) {
// Case (2). Inline replaced elements.
// Go ahead and terminate the current line as far as
// minwidth is concerned.
childMin += child->minWidth();
childMax += child->maxWidth();
-
+
if (!nowrap || !oldnowrap) {
if(m_minWidth < inlineMin) m_minWidth = inlineMin;
inlineMin = 0;
}
-
+
// Add our width to the max.
inlineMax += childMax;
-
+
if (nowrap)
inlineMin += childMin;
else {
// Now check our line.
inlineMin = childMin;
if(m_minWidth < inlineMin) m_minWidth = inlineMin;
-
+
// Now start a new line.
inlineMin = 0;
}
-
+
// We are no longer stripping whitespace at the start of
// a line.
if (!child->isFloating())
@@ -1521,9 +1792,9 @@ void RenderFlow::calcInlineMinMaxWidth()
}
else if (child->isText())
{
- // Case (3). Text.
+ // Case (3). Text.
RenderText* t = static_cast<RenderText *>(child);
-
+
// Determine if we have a breakable character. Pass in
// whether or not we should ignore any spaces at the front
// of the string. If those are going to be stripped out,
@@ -1564,9 +1835,9 @@ void RenderFlow::calcInlineMinMaxWidth()
if(m_minWidth < inlineMin) m_minWidth = inlineMin;
childMin -= ti;
}
-
+
inlineMin = childMin;
-
+
if (endWS) {
// We end in whitespace, which means we can go ahead
// and end our current line.
@@ -1578,7 +1849,7 @@ void RenderFlow::calcInlineMinMaxWidth()
inlineMin = endMin;
}
}
-
+
if (hasBreak) {
inlineMax += beginMax;
if (m_maxWidth < inlineMax) m_maxWidth = inlineMax;
@@ -1590,21 +1861,21 @@ void RenderFlow::calcInlineMinMaxWidth()
}
}
else
- {
+ {
if(m_minWidth < inlineMin) m_minWidth = inlineMin;
if(m_maxWidth < inlineMax) m_maxWidth = inlineMax;
inlineMin = inlineMax = 0;
stripFrontSpaces = true;
trailingSpaceChild = 0;
}
-
+
oldnowrap = nowrap;
-
+
child = next(this, child);
}
-
+
if (trailingSpaceChild && trailingSpaceChild->isText() && !m_pre) {
- // Collapse away the trailing space at the end of a block.
+ // Collapse away the trailing space at the end of a block.
RenderText* t = static_cast<RenderText *>(trailingSpaceChild);
const Font *f = t->htmlFont( false );
QChar space[1]; space[0] = ' ';
@@ -1616,14 +1887,14 @@ void RenderFlow::calcInlineMinMaxWidth()
if(m_minWidth < inlineMin) m_minWidth = inlineMin;
if(m_maxWidth < inlineMax) m_maxWidth = inlineMax;
-// kdDebug( 6040 ) << "m_minWidth=" << m_minWidth
-// << " m_maxWidth=" << m_maxWidth << endl;
+ // kdDebug( 6040 ) << "m_minWidth=" << m_minWidth
+ // << " m_maxWidth=" << m_maxWidth << endl;
}
-void RenderFlow::calcBlockMinMaxWidth()
+void RenderBlock::calcBlockMinMaxWidth()
{
- bool nowrap = style()->whiteSpace() == NOWRAP;
-
+ bool nowrap = style()->whiteSpace() == NOWRAP;
+
RenderObject *child = firstChild();
while(child != 0)
{
@@ -1651,7 +1922,7 @@ void RenderFlow::calcBlockMinMaxWidth()
// up to date. This method can be called before the child has actually
// calculated its margins (which are computed inside calcWidth).
child->calcWidth();
-
+
if (!(ml.type==Variable) && !(mr.type==Variable))
{
if (!(child->style()->width().type==Variable))
@@ -1676,664 +1947,31 @@ void RenderFlow::calcBlockMinMaxWidth()
int w = child->minWidth() + margin;
if(m_minWidth < w) m_minWidth = w;
// IE ignores tables for calculation of nowrap. Makes some sense.
- if ( nowrap && !child->isTable() && m_maxWidth < w )
+ if ( nowrap && !child->isTable() && m_maxWidth < w )
m_maxWidth = w;
-
+
w = child->maxWidth() + margin;
if(m_maxWidth < w) m_maxWidth = w;
child = child->nextSibling();
}
}
-void RenderFlow::calcMinMaxWidth()
-{
- KHTMLAssert( !minMaxKnown() );
-
-#ifdef DEBUG_LAYOUT
- kdDebug( 6040 ) << renderName() << "(RenderBox)::calcMinMaxWidth() this=" << this << endl;
-#endif
-
- m_minWidth = 0;
- m_maxWidth = 0;
-
- if (isInline()) {
- // Irrelevant, since some enclosing block will actually flow our children.
- setMinMaxKnown();
- return;
- }
-
- bool preOrNowrap = style()->whiteSpace() != NORMAL;
- if (childrenInline())
- calcInlineMinMaxWidth();
- else
- calcBlockMinMaxWidth();
-
- if(m_maxWidth < m_minWidth) m_maxWidth = m_minWidth;
-
- if (preOrNowrap && childrenInline())
- m_minWidth = m_maxWidth;
-
- if (style()->width().isFixed() && style()->width().value > 0)
- m_maxWidth = KMAX(m_minWidth,short(style()->width().value));
-
- int toAdd = 0;
- toAdd = borderLeft() + borderRight() + paddingLeft() + paddingRight();
-
- m_minWidth += toAdd;
- m_maxWidth += toAdd;
-
- // Scrolling marquees like to use this trick:
- // <td><div style="overflow:hidden; width:300px"><nobr>.....[lots of text].....</nobr></div></td>
- // We need to sanity-check our m_minWidth, and not let it exceed our clipped boundary. -dwh
- if (style()->overflow() == OHIDDEN && m_minWidth > m_width)
- m_minWidth = m_width;
-
- setMinMaxKnown();
-
- //kdDebug( 6040 ) << "Text::calcMinMaxWidth(" << this << "): min = " << m_minWidth << " max = " << m_maxWidth << endl;
- // ### compare with min/max width set in style sheet...
-}
-
-void RenderFlow::close()
+void RenderBlock::close()
{
- if(lastChild() && lastChild()->isAnonymousBox()) {
+ if (lastChild() && lastChild()->isAnonymousBox())
lastChild()->close();
- }
-
- RenderBox::close();
-}
-
-short RenderFlow::offsetWidth() const
-{
- if (isInline() && !isText()) {
- short w = 0;
- RenderObject* object = firstChild();
- while (object) {
- w += object->offsetWidth();
- object = object->nextSibling();
- }
- return w;
- }
- return width();
-}
-
-int RenderFlow::offsetHeight() const
-{
- if (isInline() && !isText() && firstChild())
- return firstChild()->offsetHeight();
- return height();
-}
-
-int RenderFlow::offsetLeft() const
-{
- int x = RenderBox::offsetLeft();
- RenderObject* textChild = (RenderObject*)this;
- while (textChild && textChild->isInline() && !textChild->isText())
- textChild = textChild->firstChild();
- if (textChild && textChild != this)
- x += textChild->xPos() - textChild->borderLeft() - textChild->paddingLeft();
- return x;
-}
-
-int RenderFlow::offsetTop() const
-{
- RenderObject* textChild = (RenderObject*)this;
- while (textChild && textChild->isInline() && !textChild->isText())
- textChild = textChild->firstChild();
- int y = RenderBox::offsetTop();
- if (textChild && textChild != this)
- y += textChild->yPos() - textChild->borderTop() - textChild->paddingTop();
- return y;
-}
-
-RenderFlow* RenderFlow::continuationBefore(RenderObject* beforeChild)
-{
- if (beforeChild && beforeChild->parent() == this)
- return this;
-
- RenderFlow* curr = continuation();
- RenderFlow* nextToLast = this;
- RenderFlow* last = this;
- while (curr) {
- if (beforeChild && beforeChild->parent() == curr) {
- if (curr->firstChild() == beforeChild)
- return last;
- return curr;
- }
-
- nextToLast = last;
- last = curr;
- curr = curr->continuation();
- }
-
- if (!beforeChild && !last->firstChild())
- return nextToLast;
- return last;
-}
-
-static RenderFlow* cloneInline(RenderFlow* src)
-{
- RenderFlow *o = new (src->renderArena()) RenderFlow(src->element());
- o->setStyle(src->style());
- return o;
-}
-void RenderFlow::splitInlines(RenderFlow* fromBlock, RenderFlow* toBlock,
- RenderFlow* middleBlock,
- RenderObject* beforeChild, RenderFlow* oldCont)
-{
- // Create a clone of this inline.
- RenderFlow* clone = cloneInline(this);
- clone->setContinuation(oldCont);
-
- // Now take all of the children from beforeChild to the end and remove
- // then from |this| and place them in the clone.
- RenderObject* o = beforeChild;
- while (o) {
- RenderObject* tmp = o;
- o = tmp->nextSibling();
- clone->appendChildNode(removeChildNode(tmp));
- tmp->setLayouted(false);
- tmp->setMinMaxKnown(false);
- }
-
- // Hook |clone| up as the continuation of the middle block.
- middleBlock->setContinuation(clone);
-
- // We have been reparented and are now under the fromBlock. We need
- // to walk up our inline parent chain until we hit the containing block.
- // Once we hit the containing block we're done.
- KHTMLAssert(parent()->isFlow());
- RenderFlow* curr = static_cast<RenderFlow*>(parent());
- RenderFlow* currChild = this;
- while (curr && curr != fromBlock) {
- // Create a new clone.
- RenderFlow* cloneChild = clone;
- clone = cloneInline(curr);
-
- // Insert our child clone as the first child.
- clone->appendChildNode(cloneChild);
-
- // Hook the clone up as a continuation of |curr|.
- RenderFlow* oldCont = curr->continuation();
- curr->setContinuation(clone);
- clone->setContinuation(oldCont);
-
- // Now we need to take all of the children starting from the first child
- // *after* currChild and append them all to the clone.
- o = currChild->nextSibling();
- while (o) {
- RenderObject* tmp = o;
- o = tmp->nextSibling();
- clone->appendChildNode(curr->removeChildNode(tmp));
- tmp->setLayouted(false);
- tmp->setMinMaxKnown(false);
- }
-
- // Keep walking up the chain.
- currChild = curr;
- KHTMLAssert(curr->parent()->isFlow());
- curr = static_cast<RenderFlow*>(curr->parent());
- }
-
- // Now we are at the block level. We need to put the clone into the toBlock.
- toBlock->appendChildNode(clone);
-
- // Now take all the children after currChild and remove them from the fromBlock
- // and put them in the toBlock.
- o = currChild->nextSibling();
- while (o) {
- RenderObject* tmp = o;
- o = tmp->nextSibling();
- toBlock->appendChildNode(fromBlock->removeChildNode(tmp));
- }
+ RenderFlow::close();
}
-void RenderFlow::splitFlow(RenderObject* beforeChild, RenderFlow* newBlockBox,
- RenderObject* newChild, RenderFlow* oldCont)
-{
- RenderObject* block = containingBlock();
- RenderFlow* pre = 0;
- RenderFlow* post = 0;
-
- RenderStyle* newStyle = new RenderStyle();
- newStyle->inheritFrom(block->style());
- newStyle->setDisplay(BLOCK);
- pre = new (renderArena()) RenderFlow(0 /* anonymous box */);
- pre->setStyle(newStyle);
- pre->setIsAnonymousBox(true);
- pre->setChildrenInline(true);
-
- newStyle = new RenderStyle();
- newStyle->inheritFrom(block->style());
- newStyle->setDisplay(BLOCK);
- post = new (renderArena()) RenderFlow(0 /* anonymous box */);
- post->setStyle(newStyle);
- post->setIsAnonymousBox(true);
- post->setChildrenInline(true);
-
- RenderObject* boxFirst = block->firstChild();
- block->insertChildNode(pre, boxFirst);
- block->insertChildNode(newBlockBox, boxFirst);
- block->insertChildNode(post, boxFirst);
- block->setChildrenInline(false);
-
- RenderObject* o = boxFirst;
- while (o)
- {
- RenderObject* no = o;
- o = no->nextSibling();
- pre->appendChildNode(block->removeChildNode(no));
- no->setLayouted(false);
- no->setMinMaxKnown(false);
- }
-
- splitInlines(pre, post, newBlockBox, beforeChild, oldCont);
-
- // We already know the newBlockBox isn't going to contain inline kids, so avoid wasting
- // time in makeChildrenNonInline by just setting this explicitly up front.
- newBlockBox->setChildrenInline(false);
-
- // We don't just call addChild, since it would pass things off to the
- // continuation, so we call addChildToFlow explicitly instead. We delayed
- // adding the newChild until now so that the |newBlockBox| would be fully
- // connected, thus allowing newChild access to a renderArena should it need
- // to wrap itself in additional boxes (e.g., table construction).
- newBlockBox->addChildToFlow(newChild, 0);
-
- // XXXdwh is any of this even necessary? I don't think it is.
- pre->close();
- pre->setPos(0, -500000);
- pre->setLayouted(false);
- newBlockBox->close();
- newBlockBox->setPos(0, -500000);
- newBlockBox->setLayouted(false);
- post->close();
- post->setPos(0, -500000);
- post->setLayouted(false);
-
- block->setLayouted(false);
- block->setMinMaxKnown(false);
-}
-
-void RenderFlow::addChildWithContinuation(RenderObject* newChild, RenderObject* beforeChild)
-{
- RenderFlow* flow = continuationBefore(beforeChild);
- KHTMLAssert(!beforeChild || beforeChild->parent()->isFlow());
- RenderFlow* beforeChildParent = beforeChild ? static_cast<RenderFlow*>(beforeChild->parent()) :
- (flow->continuation() ? flow->continuation() : flow);
-
- if (newChild->isSpecial())
- return beforeChildParent->addChildToFlow(newChild, beforeChild);
-
- // A continuation always consists of two potential candidates: an inline or an anonymous
- // block box holding block children.
- bool childInline = newChild->isInline();
- bool bcpInline = beforeChildParent->isInline();
- bool flowInline = flow->isInline();
-
- if (flow == beforeChildParent)
- return flow->addChildToFlow(newChild, beforeChild);
- else {
- // The goal here is to match up if we can, so that we can coalesce and create the
- // minimal # of continuations needed for the inline.
- if (childInline == bcpInline)
- return beforeChildParent->addChildToFlow(newChild, beforeChild);
- else if (flowInline == childInline)
- return flow->addChildToFlow(newChild, 0); // Just treat like an append.
- else
- return beforeChildParent->addChildToFlow(newChild, beforeChild);
- }
-}
-
-void RenderFlow::addChild(RenderObject *newChild, RenderObject *beforeChild)
-{
-#ifdef DEBUG_LAYOUT
- kdDebug( 6040 ) << renderName() << "(RenderFlow)::addChild( " << newChild->renderName() <<
- ", " << (beforeChild ? beforeChild->renderName() : "0") << " )" << endl;
- kdDebug( 6040 ) << "current height = " << m_height << endl;
-#endif
-
- if (continuation())
- return addChildWithContinuation(newChild, beforeChild);
- return addChildToFlow(newChild, beforeChild);
-}
-
-void RenderFlow::addChildToFlow(RenderObject* newChild, RenderObject* beforeChild)
-{
- setLayouted( false );
-
- bool madeBoxesNonInline = FALSE;
-
- RenderStyle* pseudoStyle=0;
- if (!isInline() && (!firstChild() || firstChild() == beforeChild) && newChild->isText())
- {
- RenderText* newTextChild = static_cast<RenderText*>(newChild);
- //kdDebug( 6040 ) << "first letter" << endl;
-
- if ( (pseudoStyle=style()->getPseudoStyle(RenderStyle::FIRST_LETTER)) ) {
- RenderFlow* firstLetter = new (renderArena()) RenderFlow(0 /* anonymous box */);
- pseudoStyle->setDisplay( INLINE );
- pseudoStyle->setPosition( STATIC ); // CSS2 says first-letter can't be positioned.
- firstLetter->setStyle(pseudoStyle);
- addChild(firstLetter);
-
- DOMStringImpl* oldText = newTextChild->string();
-
- if(oldText->l >= 1) {
- unsigned int length = 0;
- while ( length < oldText->l &&
- ( (oldText->s+length)->isSpace() || (oldText->s+length)->isPunct() ) )
- length++;
- length++;
- //kdDebug( 6040 ) << "letter= '" << DOMString(oldText->substring(0,length)).string() << "'" << endl;
- newTextChild->setText(oldText->substring(length,oldText->l-length));
-
- RenderText* letter = new (renderArena()) RenderText(newTextChild->element(), oldText->substring(0,length));
- RenderStyle* newStyle = new RenderStyle();
- newStyle->inheritFrom(pseudoStyle);
- letter->setStyle(newStyle);
- firstLetter->addChild(letter);
- }
- firstLetter->close();
- }
- }
-
- insertPseudoChild(RenderStyle::BEFORE, newChild, beforeChild);
-
- // If the requested beforeChild is not one of our children, then this is most likely because
- // there is an anonymous block box within this object that contains the beforeChild. So
- // just insert the child into the anonymous block box instead of here.
- if (beforeChild && beforeChild->parent() != this) {
-
- KHTMLAssert(beforeChild->parent());
- KHTMLAssert(beforeChild->parent()->isAnonymousBox());
-
- if (newChild->isInline()) {
- beforeChild->parent()->addChild(newChild,beforeChild);
- newChild->setLayouted( false );
- newChild->setMinMaxKnown( false );
- return;
- }
- else if (beforeChild->parent()->firstChild() != beforeChild)
- return beforeChild->parent()->addChild(newChild, beforeChild);
- else
- return addChildToFlow(newChild, beforeChild->parent());
- }
-
- // prevent non-layouted elements from getting painted by pushing them far above the top of the
- // page
- if (!newChild->isInline())
- newChild->setPos(newChild->xPos(), -500000);
-
- if (!newChild->isText())
- {
- if (newChild->style()->position() != STATIC)
- setOverhangingContents();
- }
-
- // RenderFlow has to either have all of its children inline, or all of its children as blocks.
- // So, if our children are currently inline and a block child has to be inserted, we move all our
- // inline children into anonymous block boxes
- if ( m_childrenInline && !newChild->isInline() && !newChild->isSpecial() )
- {
- if (isInline()) {
- // We are placing a block inside an inline. We have to perform a split of this
- // inline into continuations. This involves creating an anonymous block box to hold
- // |newChild|. We then make that block box a continuation of this inline. We take all of
- // the children after |beforeChild| and put them in a clone of this object.
- RenderStyle *newStyle = new RenderStyle();
- newStyle->inheritFrom(style());
- newStyle->setDisplay(BLOCK);
-
- RenderFlow *newBox = new (renderArena()) RenderFlow(0 /* anonymous box */);
- newBox->setStyle(newStyle);
- newBox->setIsAnonymousBox(true);
- RenderFlow* oldContinuation = continuation();
- setContinuation(newBox);
- splitFlow(beforeChild, newBox, newChild, oldContinuation);
- return;
- }
- else {
- // This is a block with inline content. Wrap the inline content in anonymous blocks.
- makeChildrenNonInline(beforeChild);
- madeBoxesNonInline = true;
- }
-
- if (beforeChild) {
- if ( beforeChild->parent() != this ) {
- beforeChild = beforeChild->parent();
- KHTMLAssert(beforeChild->isAnonymousBox());
- KHTMLAssert(beforeChild->parent() == this);
- }
- }
- }
- else if (!m_childrenInline && !newChild->isSpecial())
- {
- // If we're inserting an inline child but all of our children are blocks, then we have to make sure
- // it is put into an anomyous block box. We try to use an existing anonymous box if possible, otherwise
- // a new one is created and inserted into our list of children in the appropriate position.
- if(newChild->isInline()) {
- if (beforeChild) {
- if (beforeChild->previousSibling() && beforeChild->previousSibling()->isAnonymousBox()) {
- beforeChild->previousSibling()->addChild(newChild);
- newChild->setLayouted( false );
- newChild->setMinMaxKnown( false );
- return;
- }
- }
- else{
- if (m_last && m_last->isAnonymousBox()) {
- m_last->addChild(newChild);
- newChild->setLayouted( false );
- newChild->setMinMaxKnown( false );
- return;
- }
- }
-
- // no suitable existing anonymous box - create a new one
- RenderStyle *newStyle = new RenderStyle();
- newStyle->inheritFrom(style());
- newStyle->setDisplay(BLOCK);
-
- RenderFlow *newBox = new (renderArena()) RenderFlow(0 /* anonymous box */);
- newBox->setStyle(newStyle);
- newBox->setIsAnonymousBox(true);
-
- RenderBox::addChild(newBox,beforeChild);
- newBox->addChild(newChild);
- newBox->setPos(newBox->xPos(), -500000);
-
- newChild->setLayouted( false );
- newChild->setMinMaxKnown( false );
- return;
- }
- else {
- // We are adding another block child... if the current last child is an anonymous box
- // then it needs to be closed.
- // ### get rid of the closing thing altogether this will only work during initial parsing
- if (lastChild() && lastChild()->isAnonymousBox()) {
- lastChild()->close();
- }
- }
- }
-
- RenderBox::addChild(newChild,beforeChild);
- // ### care about aligned stuff
-
- newChild->setLayouted( false );
- newChild->setMinMaxKnown( false );
- insertPseudoChild(RenderStyle::AFTER, newChild, beforeChild);
-
- if ( madeBoxesNonInline )
- removeLeftoverAnonymousBoxes();
-}
-
-static void getInlineRun(RenderObject* start, RenderObject* stop,
- RenderObject*& inlineRunStart,
- RenderObject*& inlineRunEnd)
-{
- // Beginning at |start| we find the largest contiguous run of inlines that
- // we can. We denote the run with start and end points, |inlineRunStart|
- // and |inlineRunEnd|. Note that these two values may be the same if
- // we encounter only one inline.
- //
- // We skip any non-inlines we encounter as long as we haven't found any
- // inlines yet.
- //
- // |stop| indicates a non-inclusive stop point. Regardless of whether |stop|
- // is inline or not, we will not include it. It's as though we encountered
- // a non-inline.
- inlineRunStart = inlineRunEnd = 0;
-
- // Start by skipping as many non-inlines as we can.
- RenderObject * curr = start;
- while (curr && !curr->isInline())
- curr = curr->nextSibling();
-
- if (!curr)
- return; // No more inline children to be found.
-
- inlineRunStart = inlineRunEnd = curr;
- curr = curr->nextSibling();
- while (curr && curr->isInline() && (curr != stop)) {
- inlineRunEnd = curr;
- curr = curr->nextSibling();
- }
-}
-
-void RenderFlow::makeChildrenNonInline(RenderObject *insertionPoint)
-{
- // makeChildrenNonInline takes a block whose children are *all* inline and it
- // makes sure that inline children are coalesced under anonymous
- // blocks. If |insertionPoint| is defined, then it represents the insertion point for
- // the new block child that is causing us to have to wrap all the inlines. This
- // means that we cannot coalesce inlines before |insertionPoint| with inlines following
- // |insertionPoint|, because the new child is going to be inserted in between the inlines,
- // splitting them.
- KHTMLAssert(!isInline());
- KHTMLAssert(!insertionPoint || insertionPoint->parent() == this);
-
- m_childrenInline = false;
-
- RenderObject *child = firstChild();
-
- while (child) {
- RenderObject *inlineRunStart, *inlineRunEnd;
- getInlineRun(child, insertionPoint, inlineRunStart, inlineRunEnd);
-
- if (!inlineRunStart)
- break;
-
- child = inlineRunEnd->nextSibling();
-
- RenderStyle *newStyle = new RenderStyle();
- newStyle->inheritFrom(style());
- newStyle->setDisplay(BLOCK);
-
- RenderFlow *box = new (renderArena()) RenderFlow(0 /* anonymous box */);
- box->setStyle(newStyle);
- box->setIsAnonymousBox(true);
-
- insertChildNode(box, inlineRunStart);
- RenderObject* o = inlineRunStart;
- while(o != inlineRunEnd)
- {
- RenderObject* no = o;
- o = no->nextSibling();
- box->appendChildNode(removeChildNode(no));
- }
- box->appendChildNode(removeChildNode(inlineRunEnd));
- box->close();
- box->setPos(box->xPos(), -500000);
- box->setLayouted(false);
- }
-
- setLayouted(false);
-}
-
-void RenderFlow::removeChild(RenderObject *oldChild)
-{
- // If this child is a block, and if our previous and next siblings are
- // both anonymous blocks with inline content, then we can go ahead and
- // fold the inline content back together.
- RenderObject* prev = oldChild->previousSibling();
- RenderObject* next = oldChild->nextSibling();
- bool mergedBlocks = false;
- if (!isInline() && !oldChild->isInline() && !oldChild->continuation() &&
- prev && prev->isAnonymousBox() && prev->childrenInline() &&
- next && next->isAnonymousBox() && next->childrenInline()) {
- // Take all the children out of the |next| block and put them in
- // the |prev| block.
- RenderObject* o = next->firstChild();
- while (o) {
- RenderObject* no = o;
- o = no->nextSibling();
- prev->appendChildNode(next->removeChildNode(no));
- no->setLayouted(false);
- no->setMinMaxKnown(false);
- }
- prev->setLayouted(false);
- prev->setMinMaxKnown(false);
-
- // Nuke the now-empty block.
- next->detach(renderArena());
-
- mergedBlocks = true;
- }
-
- RenderBox::removeChild(oldChild);
-
- if (mergedBlocks && prev && !prev->previousSibling() && !prev->nextSibling()) {
- // The remerge has knocked us down to containing only a single anonymous
- // box. We can go ahead and pull the content right back up into our
- // box.
- RenderObject* anonBlock = removeChildNode(prev);
- m_childrenInline = true;
- RenderObject* o = anonBlock->firstChild();
- while (o) {
- RenderObject* no = o;
- o = no->nextSibling();
- appendChildNode(anonBlock->removeChildNode(no));
- no->setLayouted(false);
- no->setMinMaxKnown(false);
- }
- setLayouted(false);
- setMinMaxKnown(false);
- }
-}
-
-bool RenderFlow::nodeAtPoint(NodeInfo& info, int _x, int _y, int _tx, int _ty, bool inBox)
-{
- if (specialObjects) {
- int stx = _tx + xPos();
- int sty = _ty + yPos();
- if (isRoot()) {
- stx += static_cast<RenderRoot*>(this)->view()->contentsX();
- sty += static_cast<RenderRoot*>(this)->view()->contentsY();
- }
- SpecialObject* o;
- QPtrListIterator<SpecialObject> it(*specialObjects);
- for (it.toLast(); (o = it.current()); --it)
- if (o->node->isFloating() && !o->noPaint)
- inBox |= o->node->nodeAtPoint(info, _x, _y,
- stx+o->left + o->node->marginLeft() - o->node->xPos(),
- sty+o->startY + o->node->marginTop() - o->node->yPos());
- }
-
- inBox |= RenderBox::nodeAtPoint(info, _x, _y, _tx, _ty, inBox);
- return inBox;
-}
-
-
#ifndef NDEBUG
-void RenderFlow::printTree(int indent) const
+void RenderBlock::printTree(int indent) const
{
- RenderBox::printTree(indent);
+ RenderFlow::printTree(indent);
- if(specialObjects)
+ if (m_specialObjects)
{
- QPtrListIterator<SpecialObject> it(*specialObjects);
+ QPtrListIterator<SpecialObject> it(*m_specialObjects);
SpecialObject *r;
for ( ; (r = it.current()); ++it )
{
@@ -2347,34 +1985,36 @@ void RenderFlow::printTree(int indent) const
}
}
-void RenderFlow::dump(QTextStream *stream, QString ind) const
+void RenderBlock::dump(QTextStream *stream, QString ind) const
{
if (m_childrenInline) { *stream << " childrenInline"; }
if (m_pre) { *stream << " pre"; }
- if (firstLine) { *stream << " firstLine"; }
+ if (m_firstLine) { *stream << " firstLine"; }
- if(specialObjects && !specialObjects->isEmpty())
+ if (m_specialObjects && !m_specialObjects->isEmpty())
{
- *stream << " special(";
- QPtrListIterator<SpecialObject> it(*specialObjects);
+ *stream << " special(";
+ QPtrListIterator<SpecialObject> it(*m_specialObjects);
SpecialObject *r;
- bool first = true;
+ bool first = true;
for ( ; (r = it.current()); ++it )
{
if (!first)
- *stream << ",";
+ *stream << ",";
*stream << r->node->renderName();
- first = false;
+ first = false;
}
- *stream << ")";
+ *stream << ")";
}
// ### EClear m_clearStatus
- RenderBox::dump(stream,ind);
+ RenderFlow::dump(stream,ind);
}
#endif
#undef DEBUG
#undef DEBUG_LAYOUT
#undef BOX_DEBUG
+
+
diff --git a/WebCore/khtml/rendering/render_flow.h b/WebCore/khtml/rendering/render_block.h
similarity index 65%
copy from WebCore/khtml/rendering/render_flow.h
copy to WebCore/khtml/rendering/render_block.h
index 18112b3..c1660d7 100644
--- a/WebCore/khtml/rendering/render_flow.h
+++ b/WebCore/khtml/rendering/render_block.h
@@ -1,8 +1,6 @@
/*
- * This file is part of the DOM implementation for KDE.
+ * This file is part of the render object implementation for KHTML.
*
- * Copyright (C) 1999 Lars Knoll (knoll at kde.org)
- * (C) 1999 Antti Koivisto (koivisto at kde.org)
* Copyright (C) 2003 Apple Computer, Inc.
*
* This library is free software; you can redistribute it and/or
@@ -21,154 +19,39 @@
* Boston, MA 02111-1307, USA.
*
*/
-#ifndef RENDER_FLOW_H
-#define RENDER_FLOW_H
-#include <qsortedlist.h>
+#ifndef RENDER_BLOCK_H
+#define RENDER_BLOCK_H
-#include "render_box.h"
-#include "bidi.h"
+#include "render_flow.h"
namespace khtml {
-/**
- * all geometry managing stuff is only in the block elements.
- *
- * Inline elements don't layout themselves, but the whole paragraph
- * gets layouted by the surrounding block element. This is, because
- * one needs to know the whole paragraph to calculate bidirectional
- * behaviour of text, so putting the layouting routines in the inline
- * elements is impossible.
- */
-class RenderFlow : public RenderBox
+class RenderBlock : public RenderFlow
{
-
public:
- RenderFlow(DOM::NodeImpl* node);
+ RenderBlock(DOM::NodeImpl* node);
+ virtual ~RenderBlock();
- virtual ~RenderFlow();
-
- virtual const char *renderName() const
+ virtual const char *renderName() const
{
if (isFloating())
return "Block (Floating)";
if (isPositioned())
return "Block (Positioned)";
- if (isAnonymousBox())
+ if (isAnonymousBox())
return "Block (Anonymous)";
- if (isInline()) {
- if (isRelPositioned())
- return "Inline (Rel Positioned)";
- return "Inline";
- }
if (isRelPositioned())
return "Block (Rel Positioned)";
return "Block";
};
-
- virtual void setStyle(RenderStyle *style);
- virtual bool isFlow() const { return true; }
+ virtual bool isRenderBlock() const { return true; }
+ virtual bool containsSpecial() { return m_specialObjects!=0; }
+
virtual bool childrenInline() const { return m_childrenInline; }
virtual void setChildrenInline(bool b) { m_childrenInline = b; }
-
- virtual bool isRendered() const { return true; }
-
- virtual RenderFlow* continuation() const { return m_continuation; }
- void setContinuation(RenderFlow* c) { m_continuation = c; }
- RenderFlow* continuationBefore(RenderObject* beforeChild);
-
- void splitInlines(RenderFlow* fromBlock, RenderFlow* toBlock, RenderFlow* middleBlock,
- RenderObject* beforeChild, RenderFlow* oldCont);
- void splitFlow(RenderObject* beforeChild, RenderFlow* newBlockBox,
- RenderObject* newChild, RenderFlow* oldCont);
- void addChildWithContinuation(RenderObject* newChild, RenderObject* beforeChild);
- void addChildToFlow(RenderObject* newChild, RenderObject* beforeChild);
- void removeChild(RenderObject *oldChild);
-
- void makeChildrenNonInline(RenderObject *box2Start = 0);
-
- // overrides RenderObject
-
- virtual void paint(QPainter *, int x, int y, int w, int h,
- int tx, int ty, PaintAction paintAction);
- virtual void paintObject(QPainter *, int x, int y, int w, int h,
- int tx, int ty, PaintAction paintAction);
- void paintFloats(QPainter *p, int _x, int _y,
- int _w, int _h, int _tx, int _ty, bool paintSelection = false);
-
- virtual bool requiresLayer() { return !isTableCell() &&
- (isPositioned() || isRelPositioned() || style()->overflow()==OHIDDEN); }
-
- virtual void layout( );
-
- virtual void close();
-
- virtual void addChild(RenderObject *newChild, RenderObject *beforeChild = 0);
-
- virtual unsigned short lineWidth(int y) const;
-
- virtual int lowestPosition() const;
- virtual int rightmostPosition() const;
-
- int rightOffset() const;
- int rightRelOffset(int y, int fixedOffset, int *heightRemaining = 0) const;
- int rightOffset(int y) const { return rightRelOffset(y, rightOffset()); }
-
- int leftOffset() const;
- int leftRelOffset(int y, int fixedOffset, int *heightRemaining = 0) const;
- int leftOffset(int y) const { return leftRelOffset(y, leftOffset()); }
-
-#ifndef NDEBUG
- virtual void printTree(int indent=0) const;
- virtual void dump(QTextStream *stream, QString ind = "") const;
-#endif
-
- virtual bool nodeAtPoint(NodeInfo& info, int x, int y, int tx, int ty, bool inside=false);
-
-protected:
-
- virtual void newLine();
-
- void layoutBlockChildren( bool relayoutChildren );
- void layoutInlineChildren( bool relayoutChildren );
- void layoutSpecialObjects( bool relayoutChildren );
-
-public:
- int nearestFloatBottom(int height) const;
- int floatBottom() const;
- inline int leftBottom();
- inline int rightBottom();
- bool checkClear(RenderObject *child);
-
- // used to calculate offsetWidth/Height. Overridden by inlines (render_flow) to return
- // the remaining width on a given line (and the height of a single line).
- virtual short offsetWidth() const;
- virtual int offsetHeight() const;
- virtual int offsetLeft() const;
- virtual int offsetTop() const;
-
- void insertSpecialObject(RenderObject *o);
-
- // from BiDiParagraph
- virtual void closeParagraph() { positionNewFloats(); }
-
- void removeSpecialObject(RenderObject *o);
- // called from lineWidth, to position the floats added in the last line.
- void positionNewFloats();
- void clearFloats();
- virtual void calcMinMaxWidth();
- void calcInlineMinMaxWidth();
- void calcBlockMinMaxWidth();
-
- virtual bool containsSpecial() { return specialObjects!=0; }
- virtual bool hasOverhangingFloats() { return floatBottom() > m_height; }
-
- void addOverHangingFloats( RenderFlow *flow, int xoffset, int yoffset, bool child = false );
-
- // implementation of the following functions is in bidi.cpp
- void bidiReorderLine(const BidiIterator &start, const BidiIterator &end);
- BidiIterator findNextLineBreak(BidiIterator &start, QPtrList<BidiIterator>& midpoints);
+ void makeChildrenNonInline(RenderObject* insertionPoint = 0);
// The height (and width) of a block when you include overflow spillage out of the bottom
// of the block (e.g., a <div style="height:25px"> that has a 100px tall image inside
@@ -177,11 +60,11 @@ public:
virtual int overflowWidth() const { return m_overflowWidth; }
virtual void setOverflowHeight(int h) { m_overflowHeight = h; }
virtual void setOverflowWidth(int w) { m_overflowWidth = w; }
-
+
virtual bool isSelfCollapsingBlock() const { return m_height == 0; }
virtual bool isTopMarginQuirk() const { return m_topMarginQuirk; }
virtual bool isBottomMarginQuirk() const { return m_bottomMarginQuirk; }
-
+
virtual short maxTopMargin(bool positive) const {
if (positive)
return m_maxTopPosMargin;
@@ -205,9 +88,77 @@ public:
else
m_maxBottomNegMargin = -m_marginBottom;
}
+
+ virtual void addChildToFlow(RenderObject* newChild, RenderObject* beforeChild);
+ virtual void removeChild(RenderObject *oldChild);
+
+ virtual void setStyle(RenderStyle* _style);
-protected:
+ virtual void layout();
+ void layoutBlockChildren( bool relayoutChildren );
+ void layoutInlineChildren( bool relayoutChildren );
+ void layoutSpecialObjects( bool relayoutChildren );
+
+ // the implementation of the following two functions is in bidi.cpp
+ void bidiReorderLine(const BidiIterator &start, const BidiIterator &end);
+ BidiIterator findNextLineBreak(BidiIterator &start, QPtrList<BidiIterator>& midpoints);
+
+ virtual void paint(QPainter *, int x, int y, int w, int h,
+ int tx, int ty, PaintAction paintAction);
+ virtual void paintObject(QPainter *, int x, int y, int w, int h,
+ int tx, int ty, PaintAction paintAction);
+ void paintFloats(QPainter *p, int _x, int _y,
+ int _w, int _h, int _tx, int _ty, bool paintSelection = false);
+
+
+ void insertSpecialObject(RenderObject *o);
+ void removeSpecialObject(RenderObject *o);
+
+ // called from lineWidth, to position the floats added in the last line.
+ void positionNewFloats();
+ void clearFloats();
+ bool checkClear(RenderObject *child);
+ virtual bool hasOverhangingFloats() { return floatBottom() > m_height; }
+ void addOverHangingFloats( RenderBlock *block, int xoffset, int yoffset, bool child = false );
+
+ int nearestFloatBottom(int height) const;
+ int floatBottom() const;
+ inline int leftBottom();
+ inline int rightBottom();
+
+ virtual unsigned short lineWidth(int y) const;
+ virtual int lowestPosition() const;
+ virtual int rightmostPosition() const;
+
+ int rightOffset() const;
+ int rightRelOffset(int y, int fixedOffset, int *heightRemaining = 0) const;
+ int rightOffset(int y) const { return rightRelOffset(y, rightOffset()); }
+
+ int leftOffset() const;
+ int leftRelOffset(int y, int fixedOffset, int *heightRemaining = 0) const;
+ int leftOffset(int y) const { return leftRelOffset(y, leftOffset()); }
+
+ virtual bool nodeAtPoint(NodeInfo& info, int x, int y, int tx, int ty, bool inside=false);
+
+ virtual void calcMinMaxWidth();
+ void calcInlineMinMaxWidth();
+ void calcBlockMinMaxWidth();
+
+ virtual void close();
+ // overrides RenderObject
+ virtual bool requiresLayer() { return !isTableCell() &&
+ (isPositioned() || isRelPositioned() || style()->overflow()==OHIDDEN); }
+
+#ifndef NDEBUG
+ virtual void printTree(int indent=0) const;
+ virtual void dump(QTextStream *stream, QString ind = "") const;
+#endif
+
+protected:
+ void newLine();
+
+protected:
struct SpecialObject {
enum Type {
FloatLeft,
@@ -225,7 +176,7 @@ protected:
count = 0;
noPaint = false;
}
-
+
RenderObject* node;
int startY;
int endY;
@@ -234,7 +185,7 @@ protected:
short count;
Type type : 2; // left or right aligned
bool noPaint: 1;
-
+
bool operator==(const SpecialObject& ) const
{
return false;
@@ -246,36 +197,29 @@ protected:
return node->style()->zIndex() < o.node->style()->zIndex();
}
};
-
- QSortedList<SpecialObject>* specialObjects;
-
-private:
+
+protected:
+ QSortedList<SpecialObject>* m_specialObjects;
bool m_childrenInline : 1;
bool m_pre : 1;
- bool firstLine : 1; // used in inline layouting
+ bool m_firstLine : 1; // used in inline layouting
EClear m_clearStatus : 2; // used during layuting of paragraphs
bool m_topMarginQuirk : 1;
bool m_bottomMarginQuirk : 1;
-
+
short m_maxTopPosMargin;
short m_maxTopNegMargin;
short m_maxBottomPosMargin;
short m_maxBottomNegMargin;
-
+
// How much content overflows out of our block vertically or horizontally (all we support
// for now is spillage out of the bottom and the right, which are the common cases).
// XXX Generalize to work with top and left as well.
int m_overflowHeight;
- int m_overflowWidth;
-
- // An inline can be split with blocks occurring in between the inline content.
- // When this occurs we need a pointer to our next object. We can basically be
- // split into a sequence of inlines and blocks. The continuation will either be
- // an anonymous block (that houses other blocks) or it will be an inline flow.
- RenderFlow* m_continuation;
+ int m_overflowWidth;
};
-
-}; //namespace
+}; // namespace
+
+#endif // RENDER_BLOCK_H
-#endif
diff --git a/WebCore/khtml/rendering/render_body.cpp b/WebCore/khtml/rendering/render_body.cpp
index eb0cceb..e27e3a5 100644
--- a/WebCore/khtml/rendering/render_body.cpp
+++ b/WebCore/khtml/rendering/render_body.cpp
@@ -33,7 +33,7 @@ using namespace khtml;
using namespace DOM;
RenderBody::RenderBody(HTMLBodyElementImpl* element)
- : RenderFlow(element)
+ : RenderBlock(element)
{
scrollbarsStyled = false;
}
@@ -45,7 +45,8 @@ RenderBody::~RenderBody()
void RenderBody::setStyle(RenderStyle* style)
{
// qDebug("RenderBody::setStyle()");
- RenderFlow::setStyle(style);
+ style->setDisplay(BLOCK); // Don't allow RenderBody to be inline at the moment.
+ RenderBlock::setStyle(style);
element()->getDocument()->setTextColor( DOMString( style->color().name() ) );
scrollbarsStyled = false;
}
@@ -88,7 +89,7 @@ void RenderBody::repaint(bool immediate)
void RenderBody::layout()
{
- RenderFlow::layout();
+ RenderBlock::layout();
#if !APPLE_CHANGES
if (!scrollbarsStyled)
@@ -105,7 +106,7 @@ void RenderBody::layout()
int RenderBody::availableHeight() const
{
- int h = RenderFlow::availableHeight();
+ int h = RenderBlock::availableHeight();
if( style()->marginTop().isFixed() )
h -= style()->marginTop().value;
diff --git a/WebCore/khtml/rendering/render_body.h b/WebCore/khtml/rendering/render_body.h
index ceb0a5e..5ef14af 100644
--- a/WebCore/khtml/rendering/render_body.h
+++ b/WebCore/khtml/rendering/render_body.h
@@ -22,7 +22,7 @@
#ifndef RENDER_BODY
#define RENDER_BODY
-#include "rendering/render_flow.h"
+#include "render_block.h"
namespace DOM
{
@@ -31,7 +31,7 @@ namespace DOM
namespace khtml {
-class RenderBody : public RenderFlow
+class RenderBody : public RenderBlock
{
public:
RenderBody(DOM::HTMLBodyElementImpl* node);
diff --git a/WebCore/khtml/rendering/render_box.cpp b/WebCore/khtml/rendering/render_box.cpp
index 84f66f7..2934b3a 100644
--- a/WebCore/khtml/rendering/render_box.cpp
+++ b/WebCore/khtml/rendering/render_box.cpp
@@ -408,11 +408,12 @@ void RenderBox::close()
short RenderBox::containingBlockWidth() const
{
- if ( ( style()->htmlHacks() || isTable() ) && style()->flowAroundFloats() && containingBlock()->isFlow()
+ RenderBlock* cb = containingBlock();
+ if (( style()->htmlHacks() || isTable() ) && style()->flowAroundFloats()
&& style()->width().isVariable())
- return static_cast<RenderFlow*>(containingBlock())->lineWidth(m_y);
+ return cb->lineWidth(m_y);
else
- return containingBlock()->contentWidth();
+ return cb->contentWidth();
}
bool RenderBox::absolutePosition(int &xPos, int &yPos, bool f)
@@ -511,9 +512,9 @@ void RenderBox::calcWidth()
Length mr = style()->marginRight();
int cw;
- RenderObject *cb = containingBlock();
- if ( style()->flowAroundFloats() && cb->isFlow() )
- cw = static_cast<RenderFlow *>(cb)->lineWidth( m_y );
+ RenderBlock *cb = containingBlock();
+ if (style()->flowAroundFloats())
+ cw = cb->lineWidth( m_y );
else
cw = cb->contentWidth();
@@ -691,7 +692,7 @@ void RenderBox::calcHeight()
// Handle a common case: nested 100% height <div>s.
// This is kind of a one-off hack rather than doing it right.
// Makes dbaron's z-index root bg testcases work. Bad dave. - dwh
- RenderObject* cb = containingBlock();
+ RenderBlock* cb = containingBlock();
Length ch = containingBlock()->style()->height();
while (cb && !cb->isTableCell() && ch.isPercent() && ch.value == 100) {
cb = cb->containingBlock();
diff --git a/WebCore/khtml/rendering/render_container.cpp b/WebCore/khtml/rendering/render_container.cpp
index f326851..5d3aa43 100644
--- a/WebCore/khtml/rendering/render_container.cpp
+++ b/WebCore/khtml/rendering/render_container.cpp
@@ -227,8 +227,7 @@ void RenderContainer::insertPseudoChild(RenderStyle::PseudoId type, RenderObject
if (pseudo->contentType()==CONTENT_TEXT)
{
- RenderObject* po = new (renderArena()) RenderFlow(0 /* anonymous box */);
- po->setStyle(pseudo);
+ RenderObject* po = RenderFlow::createFlow(0, pseudo, renderArena()); /* anonymous box */
addChild(po, beforeChild);
RenderText* t = new (renderArena()) RenderText(0 /*anonymous object */, pseudo->contentText());
@@ -331,7 +330,7 @@ void RenderContainer::removeLeftoverAnonymousBoxes()
while( child ) {
RenderObject *next = child->nextSibling();
- if ( child->isFlow() && child->isAnonymousBox() && !child->continuation() && !child->childrenInline() && !child->isTableCell() ) {
+ if ( child->isRenderBlock() && child->isAnonymousBox() && !child->continuation() && !child->childrenInline() && !child->isTableCell() ) {
RenderObject *firstAnChild = child->firstChild();
RenderObject *lastAnChild = child->lastChild();
if ( firstAnChild ) {
diff --git a/WebCore/khtml/rendering/render_flow.cpp b/WebCore/khtml/rendering/render_flow.cpp
index 96cf835..1873660 100644
--- a/WebCore/khtml/rendering/render_flow.cpp
+++ b/WebCore/khtml/rendering/render_flow.cpp
@@ -21,10 +21,6 @@
* Boston, MA 02111-1307, USA.
*/
// -------------------------------------------------------------------------
-//#define DEBUG
-//#define DEBUG_LAYOUT
-//#define BOX_DEBUG
-//#define FLOAT_DEBUG
#include <kdebug.h>
#include <assert.h>
@@ -38,6 +34,8 @@
#include "xml/dom_nodeimpl.h"
#include "xml/dom_docimpl.h"
#include "html/html_formimpl.h"
+#include "render_inline.h"
+#include "render_block.h"
#include "khtmlview.h"
#include "htmltags.h"
@@ -45,1745 +43,14 @@
using namespace DOM;
using namespace khtml;
-RenderFlow::RenderFlow(DOM::NodeImpl* node)
- : RenderBox(node)
+RenderObject* RenderFlow::createFlow(DOM::NodeImpl* node, RenderStyle* style, RenderArena* arena)
{
- m_childrenInline = true;
- m_pre = false;
- firstLine = false;
- m_clearStatus = CNONE;
-
- specialObjects = 0;
-
- m_maxTopPosMargin = m_maxTopNegMargin = m_maxBottomPosMargin = m_maxBottomNegMargin = 0;
- m_topMarginQuirk = m_bottomMarginQuirk = false;
- m_overflowHeight = 0;
- m_overflowWidth = 0;
-
- m_continuation = 0;
-}
-
-void RenderFlow::setStyle(RenderStyle *_style)
-{
-
-// kdDebug( 6040 ) << (void*)this<< " renderFlow(" << renderName() << ")::setstyle()" << endl;
-
- RenderBox::setStyle(_style);
-
- if(isPositioned())
- setInline(false);
-
- if(isFloating() || style()->display() != INLINE)
- setInline(false);
-
- if (isInline() && !m_childrenInline)
- setInline(false);
-
- m_pre = false;
- if(style()->whiteSpace() == PRE)
- m_pre = true;
-
- // ### we could save this call when the change only affected
- // non inherited properties
- RenderObject *child = firstChild();
- while(child != 0)
- {
- if(child->isAnonymousBox())
- {
- RenderStyle* newStyle = new RenderStyle();
- newStyle->inheritFrom(style());
- newStyle->setDisplay(BLOCK);
- child->setStyle(newStyle);
- child->setIsAnonymousBox(true);
- }
- child = child->nextSibling();
- }
-
- // Ensure that all of the split inlines pick up the new style. We
- // only do this if we're an inline, since we don't want to propagate
- // a block's style to the other inlines.
- // e.g., <font>foo <h4>goo</h4> moo</font>. The <font> inlines before
- // and after the block share the same style, but the block doesn't
- // need to pass its style on to anyone else.
- if (isInline()) {
- RenderFlow* currCont = continuation();
- while (currCont) {
- if (currCont->isInline()) {
- RenderFlow* nextCont = currCont->continuation();
- currCont->setContinuation(0);
- currCont->setStyle(style());
- currCont->setContinuation(nextCont);
- }
- currCont = currCont->continuation();
- }
- }
-}
-
-RenderFlow::~RenderFlow()
-{
- delete specialObjects;
-}
-
-void RenderFlow::paint(QPainter *p, int _x, int _y, int _w, int _h,
- int _tx, int _ty, PaintAction paintAction)
-{
-
-#ifdef DEBUG_LAYOUT
-// kdDebug( 6040 ) << renderName() << "(RenderFlow) " << this << " ::print() x/y/w/h = (" << xPos() << "/" << yPos() << "/" << width() << "/" << height() << ")" << endl;
-#endif
-
- if(!isInline())
- {
- _tx += m_x;
- _ty += m_y;
- }
-
- // check if we need to do anything at all...
- if(!isInline() && !overhangingContents() && !isRelPositioned() && !isPositioned() )
- {
- int h = m_height;
- if(specialObjects && floatBottom() > h) h = floatBottom();
- if((_ty > _y + _h) || (_ty + h < _y))
- {
- //kdDebug( 6040 ) << "cut!" << endl;
- return;
- }
- }
-
- paintObject(p, _x, _y, _w, _h, _tx, _ty, paintAction);
-}
-
-void RenderFlow::paintObject(QPainter *p, int _x, int _y,
- int _w, int _h, int _tx, int _ty, PaintAction paintAction)
-{
-
-#ifdef DEBUG_LAYOUT
-// kdDebug( 6040 ) << renderName() << "(RenderFlow) " << this << " ::paintObject() w/h = (" << width() << "/" << height() << ")" << endl;
-#endif
-
- // 1. paint background, borders etc
- if (paintAction == PaintActionBackground &&
- shouldPaintBackgroundOrBorder() && !isInline() && style()->visibility() == VISIBLE )
- paintBoxDecorations(p, _x, _y, _w, _h, _tx, _ty);
-
- // 2. paint contents
- RenderObject *child = firstChild();
- while(child != 0)
- {
- if(!child->layer() && !child->isFloating())
- child->paint(p, _x, _y, _w, _h, _tx, _ty, paintAction);
- child = child->nextSibling();
- }
-
- // 3. paint floats.
- if (paintAction == PaintActionFloat || paintAction == PaintActionSelection)
- paintFloats(p, _x, _y, _w, _h, _tx, _ty, paintAction == PaintActionSelection);
-
- if (paintAction == PaintActionBackground &&
- !isInline() && !childrenInline() && style()->outlineWidth())
- paintOutline(p, _tx, _ty, width(), height(), style());
-
-#ifdef BOX_DEBUG
- if ( style() && style()->visibility() == VISIBLE ) {
- if(isAnonymousBox())
- outlineBox(p, _tx, _ty, "green");
- if(isFloating())
- outlineBox(p, _tx, _ty, "yellow");
- else
- outlineBox(p, _tx, _ty);
- }
-#endif
-
-}
-
-void RenderFlow::paintFloats(QPainter *p, int _x, int _y,
- int _w, int _h, int _tx, int _ty, bool paintSelection)
-{
- if (!specialObjects)
- return;
-
- SpecialObject* r;
- QPtrListIterator<SpecialObject> it(*specialObjects);
- for ( ; (r = it.current()); ++it) {
- // Only paint the object if our noPaint flag isn't set.
- if (r->node->isFloating() && !r->noPaint) {
- if (paintSelection) {
- r->node->paint(p, _x, _y, _w, _h,
- _tx + r->left - r->node->xPos() + r->node->marginLeft(),
- _ty + r->startY - r->node->yPos() + r->node->marginTop(),
- PaintActionSelection);
- }
- else {
- r->node->paint(p, _x, _y, _w, _h,
- _tx + r->left - r->node->xPos() + r->node->marginLeft(),
- _ty + r->startY - r->node->yPos() + r->node->marginTop(),
- PaintActionBackground);
- r->node->paint(p, _x, _y, _w, _h,
- _tx + r->left - r->node->xPos() + r->node->marginLeft(),
- _ty + r->startY - r->node->yPos() + r->node->marginTop(),
- PaintActionFloat);
- r->node->paint(p, _x, _y, _w, _h,
- _tx + r->left - r->node->xPos() + r->node->marginLeft(),
- _ty + r->startY - r->node->yPos() + r->node->marginTop(),
- PaintActionForeground);
- }
- }
- }
-}
-
-void RenderFlow::layout()
-{
-// kdDebug( 6040 ) << renderName() << " " << this << "::layout() start" << endl;
-// QTime t;
-// t.start();
-
- KHTMLAssert( !layouted() );
- KHTMLAssert( minMaxKnown() );
- if (isInline()) // Inline <form>s inside various table elements can cause us to
- return; // come in here. Just bail. -dwh
-
- int oldWidth = m_width;
-
- calcWidth();
- m_overflowWidth = m_width;
-
- bool relayoutChildren = false;
- if ( oldWidth != m_width )
- relayoutChildren = true;
-
- // need a small hack here, as tables are done a bit differently
- if ( isTableCell() ) //&& static_cast<RenderTableCell *>(this)->widthChanged() )
- relayoutChildren = true;
-
-// kdDebug( 6040 ) << specialObjects << "," << oldWidth << ","
-// << m_width << ","<< layouted() << "," << isAnonymousBox() << ","
-// << overhangingContents() << "," << isPositioned() << endl;
-
-#ifdef DEBUG_LAYOUT
- kdDebug( 6040 ) << renderName() << "(RenderFlow) " << this << " ::layout() width=" << m_width << ", layouted=" << layouted() << endl;
- if(containingBlock() == static_cast<RenderObject *>(this))
- kdDebug( 6040 ) << renderName() << ": containingBlock == this" << endl;
-#endif
-
- // This is an incorrect optimization. You cannot know at this point whether or not a child will overhang
- // in the horizontal direction without laying out your children. The following test case illustrates this
- // point, as it will fail with this code commented back in.
- // <html>
- // <body style="width:0px">
- // Hello world!
- // </body>
- // </html>
- //
- // In the real world, this affects (as of 7/24/2002) http://viamichelin.com/. -- dwh
- //
- /* if(m_width<=0 && !isPositioned() && !overhangingContents()) {
- if(m_y < 0) m_y = 0;
- setLayouted();
- return;
- }
- */
-
- clearFloats();
-
- m_height = 0;
- m_overflowHeight = 0;
- m_clearStatus = CNONE;
-
- // We use four values, maxTopPos, maxPosNeg, maxBottomPos, and maxBottomNeg, to track
- // our current maximal positive and negative margins. These values are used when we
- // are collapsed with adjacent blocks, so for example, if you have block A and B
- // collapsing together, then you'd take the maximal positive margin from both A and B
- // and subtract it from the maximal negative margin from both A and B to get the
- // true collapsed margin. This algorithm is recursive, so when we finish layout()
- // our block knows its current maximal positive/negative values.
- //
- // Start out by setting our margin values to our current margins. Table cells have
- // no margins, so we don't fill in the values for table cells.
- if (!isTableCell()) {
- initMaxMarginValues();
-
- m_topMarginQuirk = style()->marginTop().quirk;
- m_bottomMarginQuirk = style()->marginBottom().quirk;
-
- if (element() && element()->id() == ID_FORM && element()->isMalformed())
- // See if this form is malformed (i.e., unclosed). If so, don't give the form
- // a bottom margin.
- m_maxBottomPosMargin = m_maxBottomNegMargin = 0;
- }
-
- // A quirk that has become an unfortunate standard. Positioned elements, floating elements
- // and table cells don't ever collapse their margins with either themselves or their
- // children.
- bool canCollapseOwnMargins = !isPositioned() && !isFloating() && !isTableCell();
-
-// kdDebug( 6040 ) << "childrenInline()=" << childrenInline() << endl;
- if(childrenInline())
- layoutInlineChildren( relayoutChildren );
- else
- layoutBlockChildren( relayoutChildren );
-
- int oldHeight = m_height;
- calcHeight();
- if (oldHeight != m_height) {
- relayoutChildren = true;
-
- // If the block got expanded in size, then increase our overflowheight to match.
- if (m_overflowHeight > m_height)
- m_overflowHeight -= (borderBottom()+paddingBottom());
- if (m_overflowHeight < m_height)
- m_overflowHeight = m_height;
- }
-
- if (isTableCell()) {
- // Table cells need to grow to accommodate both overhanging floats and
- // blocks that have overflowed content.
- // Check for an overhanging float first.
- // FIXME: This needs to look at the last flow, not the last child.
- if (lastChild() && lastChild()->hasOverhangingFloats() ) {
- KHTMLAssert(lastChild()->isFlow());
- m_height = lastChild()->yPos() + static_cast<RenderFlow*>(lastChild())->floatBottom();
- m_height += borderBottom() + paddingBottom();
- }
-
- if (m_overflowHeight > m_height)
- m_height = m_overflowHeight + borderBottom() + paddingBottom();
- }
-
- if( hasOverhangingFloats() && (isFloating() || isTableCell())) {
- m_height = floatBottom();
- m_height += borderBottom() + paddingBottom();
- }
-
- layoutSpecialObjects( relayoutChildren );
-
- //kdDebug() << renderName() << " layout width=" << m_width << " height=" << m_height << endl;
-
- if (canCollapseOwnMargins && m_height == 0) {
- // We are a block with no border and padding and a computed height
- // of 0. The CSS spec states that zero-height blocks collapse their margins
- // together.
- // When blocks are self-collapsing, we just use the top margin values and set the
- // bottom margin max values to 0. This way we don't factor in the values
- // twice when we collapse with our previous vertically adjacent and
- // following vertically adjacent blocks.
- if (m_maxBottomPosMargin > m_maxTopPosMargin)
- m_maxTopPosMargin = m_maxBottomPosMargin;
- if (m_maxBottomNegMargin > m_maxTopNegMargin)
- m_maxTopNegMargin = m_maxBottomNegMargin;
- m_maxBottomNegMargin = m_maxBottomPosMargin = 0;
- }
-
- // Always ensure our overflow width is at least as large as our width.
- if (m_overflowWidth < m_width)
- m_overflowWidth = m_width;
-
- // overflow:hidden will just clip, so we don't have overflow.
- if (style()->overflow()==OHIDDEN) {
- m_overflowHeight = m_height;
- m_overflowWidth = m_width;
- }
-
- setLayouted();
-}
-
-void RenderFlow::layoutSpecialObjects( bool relayoutChildren )
-{
- if(specialObjects) {
- //kdDebug( 6040 ) << renderName() << " " << this << "::layoutSpecialObjects() start" << endl;
- SpecialObject* r;
- QPtrListIterator<SpecialObject> it(*specialObjects);
- for ( ; (r = it.current()); ++it ) {
- //kdDebug(6040) << " have a positioned object" << endl;
- if (r->type == SpecialObject::Positioned) {
- if ( relayoutChildren )
- r->node->setLayouted( false );
- if ( !r->node->layouted() )
- r->node->layout();
- }
- }
- specialObjects->sort();
- }
-}
-
-void RenderFlow::layoutBlockChildren( bool relayoutChildren )
-{
-#ifdef DEBUG_LAYOUT
- kdDebug( 6040 ) << renderName() << " layoutBlockChildren( " << this <<" ), relayoutChildren="<< relayoutChildren << endl;
-#endif
-
- int xPos = 0;
- int toAdd = 0;
-
- m_height = 0;
-
- xPos += borderLeft() + paddingLeft();
- m_height += borderTop() + paddingTop();
- toAdd += borderBottom() + paddingBottom();
-
- int minHeight = m_height + toAdd;
- m_overflowHeight = m_height;
-
- if( style()->direction() == RTL ) {
- xPos = marginLeft() + m_width - paddingRight() - borderRight();
- }
-
- RenderObject *child = firstChild();
- RenderFlow *prevFlow = 0;
-
- // Whether or not we can collapse our own margins with our children. We don't do this
- // if we had any border/padding (obviously), if we're the root or HTML elements, or if
- // we're positioned, floating, a table cell.
- bool canCollapseWithChildren = !isRoot() && !isHtml() && !isPositioned() &&
- !isFloating() && !isTableCell() && (m_height == 0);
-
- // Whether or not we are a quirky container, i.e., do we collapse away top and bottom
- // margins in our container.
- bool quirkContainer = isTableCell() || isBody();
-
- // Sometimes an element will be shoved down away from a previous sibling, e.g., when
- // clearing to pass beyond a float. In this case, you don't need to collapse. This
- // boolean is updated with each iteration through our child list to reflect whether
- // that particular child should be collapsed with its previous sibling (or with the top
- // of the block).
- bool shouldCollapseChild = true;
-
- // This flag tracks whether the child should collapse with the top margins of the block.
- // It can remain set through multiple iterations as long as we keep encountering
- // self-collapsing blocks.
- bool topMarginContributor = true;
-
- // These flags track the previous maximal positive and negative margins.
- int prevPosMargin = canCollapseWithChildren ? maxTopMargin(true) : 0;
- int prevNegMargin = canCollapseWithChildren ? maxTopMargin(false) : 0;
-
- // Whether or not we encountered an element with clear set that actually had to
- // be pushed down below a float.
- int clearOccurred = false;
-
- int oldPosMargin = prevPosMargin;
- int oldNegMargin = prevNegMargin;
-
- bool topChildQuirk = false;
- bool bottomChildQuirk = false;
- bool determinedTopQuirk = false;
-
- bool strictMode = isAnonymousBox() ? true : (!element()->getDocument()->inQuirksMode());
-
- //kdDebug() << "RenderFlow::layoutBlockChildren " << prevMargin << endl;
-
- // take care in case we inherited floats
- if (child && floatBottom() > m_height)
- child->setLayouted(false);
-
-// QTime t;
-// t.start();
-
- while( child != 0 )
- {
- // make sure we relayout children if we need it.
- if ( relayoutChildren || floatBottom() > m_y ||
- (child->isReplaced() && (child->style()->width().isPercent() || child->style()->height().isPercent())))
- child->setLayouted(false);
-
-// kdDebug( 6040 ) << " " << child->renderName() << " loop " << child << ", " << child->isInline() << ", " << child->layouted() << endl;
-// kdDebug( 6040 ) << t.elapsed() << endl;
- // ### might be some layouts are done two times... FIX that.
-
- if (child->isPositioned())
- {
- static_cast<RenderFlow*>(child->containingBlock())->insertSpecialObject(child);
- //kdDebug() << "RenderFlow::layoutBlockChildren inserting positioned into " << child->containingBlock()->renderName() << endl;
-
- child = child->nextSibling();
- continue;
- } else if ( child->isReplaced() ) {
- if ( !child->layouted() )
- child->layout();
- }
-
- if ( child->isFloating() ) {
- insertSpecialObject( child );
-
- // The float should be positioned taking into account the bottom margin
- // of the previous flow. We add that margin into the height, get the
- // float positioned properly, and then subtract the margin out of the
- // height again. -dwh
- if (prevFlow)
- m_height += prevFlow->collapsedMarginBottom();
- positionNewFloats();
- if (prevFlow)
- m_height -= prevFlow->collapsedMarginBottom();
-
- //kdDebug() << "RenderFlow::layoutBlockChildren inserting float at "<< m_height <<" prevMargin="<<prevMargin << endl;
- child = child->nextSibling();
- continue;
- }
-
- // Note this occurs after the test for positioning and floating above, since
- // we want to ensure that we don't artificially increase our height because of
- // a positioned or floating child.
- if ( child->style()->flowAroundFloats() && !child->isFloating() &&
- style()->width().isFixed() && child->minWidth() > lineWidth( m_height ) ) {
- m_height = QMAX( m_height, floatBottom() );
- shouldCollapseChild = false;
- clearOccurred = true;
- }
-
- child->calcVerticalMargins();
-
- //kdDebug(0) << "margin = " << margin << " yPos = " << m_height << endl;
-
- // Try to guess our correct y position. In most cases this guess will
- // be correct. Only if we're wrong (when we compute the real y position)
- // will we have to relayout.
- int yPosEstimate = m_height;
- if (prevFlow)
- {
- yPosEstimate += QMAX(prevFlow->collapsedMarginBottom(), child->marginTop());
- if (prevFlow->yPos()+prevFlow->floatBottom() > yPosEstimate)
- child->setLayouted(false);
- else
- prevFlow=0;
- }
- else if (!canCollapseWithChildren || !topMarginContributor)
- yPosEstimate += child->marginTop();
-
- // Go ahead and position the child as though it didn't collapse with the top.
- child->setPos(child->xPos(), yPosEstimate);
- if ( !child->layouted() )
- child->layout();
-
- // Now determine the correct ypos based off examination of collapsing margin
- // values.
- if (shouldCollapseChild) {
- // Get our max pos and neg top margins.
- int posTop = child->maxTopMargin(true);
- int negTop = child->maxTopMargin(false);
-
- // XXX A hack we have to put in to deal with the fact
- // that KHTML morphs inlines with blocks
- // inside them into blocks themselves. -dwh
- if (!strictMode && child->style()->display() == INLINE && child->marginTop())
- posTop = negTop = 0;
-
- // See if the top margin is quirky. We only care if this child has
- // margins that will collapse with us.
- bool topQuirk = child->isTopMarginQuirk();
-
- if (canCollapseWithChildren && topMarginContributor && !clearOccurred) {
- // This child is collapsing with the top of the
- // block. If it has larger margin values, then we need to update
- // our own maximal values.
- if (strictMode || !quirkContainer || !topQuirk) {
- if (posTop > m_maxTopPosMargin)
- m_maxTopPosMargin = posTop;
-
- if (negTop > m_maxTopNegMargin)
- m_maxTopNegMargin = negTop;
- }
-
- // The minute any of the margins involved isn't a quirk, don't
- // collapse it away, even if the margin is smaller (www.webreference.com
- // has an example of this, a <dt> with 0.8em author-specified inside
- // a <dl> inside a <td>.
- if (!determinedTopQuirk && !topQuirk && (posTop-negTop)) {
- m_topMarginQuirk = false;
- determinedTopQuirk = true;
- }
-
- if (!determinedTopQuirk && topQuirk && marginTop() == 0)
- // We have no top margin and our top child has a quirky margin.
- // We will pick up this quirky margin and pass it through.
- // This deals with the <td><div><p> case.
- // Don't do this for a block that split two inlines though. You do
- // still apply margins in this case.
- m_topMarginQuirk = true;
- }
-
- if (quirkContainer && topMarginContributor && (posTop-negTop))
- topChildQuirk = topQuirk;
-
- int ypos = m_height;
- if (child->isSelfCollapsingBlock()) {
- // This child has no height. Update our previous pos and neg
- // values and just keep going.
- if (posTop > prevPosMargin)
- prevPosMargin = posTop;
- if (negTop > prevNegMargin)
- prevNegMargin = negTop;
-
- if (!topMarginContributor)
- // We need to make sure that the position of the self-collapsing block
- // is correct, since it could have overflowing content
- // that needs to be positioned correctly (e.g., a block that
- // had a specified height of 0 but that actually had subcontent).
- ypos = m_height + prevPosMargin - prevNegMargin;
- }
- else {
- if (!topMarginContributor ||
- (!canCollapseWithChildren
- && (strictMode || !quirkContainer || !topChildQuirk)
- )) {
- // We're collapsing with a previous sibling's margins and not
- // with the top of the block.
- int absPos = prevPosMargin > posTop ? prevPosMargin : posTop;
- int absNeg = prevNegMargin > negTop ? prevNegMargin : negTop;
- int collapsedMargin = absPos - absNeg;
- m_height += collapsedMargin;
- ypos = m_height;
- }
- prevPosMargin = child->maxBottomMargin(true);
- prevNegMargin = child->maxBottomMargin(false);
-
- // XXX A hack we have to put in to deal with the fact
- // that KHTML morphs inlines with blocks
- // inside them into blocks themselves.
- if (!strictMode && child->style()->display() == INLINE && child->marginBottom())
- prevPosMargin = prevNegMargin = 0;
-
- if (prevPosMargin-prevNegMargin) {
- bottomChildQuirk = child->isBottomMarginQuirk();
- }
- }
-
- child->setPos(child->xPos(), ypos);
- if (ypos != yPosEstimate && (child->containsSpecial() || containsSpecial())) {
- // Our guess was wrong. Make the child lay itself out again.
- // XXXdwh some debugging code for this.
- // printf("WE WERE WRONG for object %d (%d, %d)!\n", (int)child, yPosEstimate, ypos);
- child->setLayouted(false);
- child->layout();
- }
- }
-
- // Now check for clear.
- if (checkClear(child)) {
- // The child needs to be lowered. Move the child so that it just clears the float.
- child->setPos(child->xPos(), m_height);
- clearOccurred = true;
-
- if (topMarginContributor) {
- // We can no longer collapse with the top of the block since a clear
- // occurred. The empty blocks collapse into the cleared block.
- // XXX This isn't quite correct. Need clarification for what to do
- // if the height the cleared block is offset by is smaller than the
- // margins involved. -dwh
- m_maxTopPosMargin = oldPosMargin;
- m_maxTopNegMargin = oldNegMargin;
- }
-
- // If our value of clear caused us to be repositioned vertically to be
- // underneath a float, we have to do another layout to take into account
- // the extra space we now have available.
- child->setLayouted(false);
- child->layout();
- }
-
- // Reset the top margin contributor to false if we encountered
- // a non-empty child. This has to be done after checking for clear,
- // so that margins can be reset if a clear occurred.
- if (topMarginContributor && !child->isSelfCollapsingBlock())
- topMarginContributor = false;
-
- int chPos = xPos + child->marginLeft();
-
- if(style()->direction() == LTR) {
- // html blocks flow around floats
- if ( ( style()->htmlHacks() || child->isTable() ) && child->style()->flowAroundFloats() ) {
- int leftOff = leftOffset(m_height);
- 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|
- // so that we can just pass the content width in directly to the |calcHorizontalMargins|
- // function.
- // -dwh
- int cw;
- RenderObject *cb = child->containingBlock();
- if ( cb->isFlow() )
- cw = static_cast<RenderFlow *>(cb)->lineWidth( child->yPos() );
- else
- cw = cb->contentWidth();
- static_cast<RenderBox*>(child)->calcHorizontalMargins ( child->style()->marginLeft(), child->style()->marginRight(),
- cw);
- chPos = leftOff + child->marginLeft();
- }
- }
- } else {
- chPos -= child->width() + child->marginLeft() + child->marginRight();
- if ( ( style()->htmlHacks() || child->isTable() ) && child->style()->flowAroundFloats() )
- chPos -= leftOffset(m_height);
- }
-
- child->setPos(chPos, child->yPos());
-
- m_height += child->height();
- if (m_overflowHeight < m_height) {
- int overflowDelta = child->overflowHeight() - child->height();
- if (m_height + overflowDelta > m_overflowHeight)
- m_overflowHeight = m_height + overflowDelta;
- }
-
- if (child->isFlow())
- prevFlow = static_cast<RenderFlow*>(child);
-
- if ( child->hasOverhangingFloats() ) {
- // need to add the float to our special objects
- addOverHangingFloats( static_cast<RenderFlow *>(child), -child->xPos(), -child->yPos(), true );
- }
-
- // See if this child has made our overflow need to grow.
- // XXXdwh Work with left overflow as well as right overflow.
- int rightChildPos = child->overflowWidth() + child->xPos();
- if (rightChildPos > m_overflowWidth)
- m_overflowWidth = rightChildPos;
-
- child = child->nextSibling();
- }
-
- bool autoHeight = style()->height().isVariable() && style()->height().value == 0;
-
- // If any height other than auto is specified in CSS, then we don't collapse our bottom
- // margins with our children's margins. To do otherwise would be to risk odd visual
- // effects when the children overflow out of the parent block and yet still collapse
- // with it. We also don't collapse if we had any bottom border/padding (represented by
- // |toAdd|.
- if (canCollapseWithChildren && (toAdd || !autoHeight))
- canCollapseWithChildren = false;
-
- // If we can't collapse with children then go ahead and add in the bottom margins.
- if (!canCollapseWithChildren
- && (strictMode || !quirkContainer || !bottomChildQuirk))
- m_height += prevPosMargin - prevNegMargin;
-
- m_height += toAdd;
-
- // Negative margins can cause our height to shrink below our minimal height (border/padding).
- // If this happens, ensure that the computed height is increased to the minimal height.
- if (m_height < minHeight)
- m_height = minHeight;
-
- // Always make sure our overflowheight is at least our height.
- if (m_overflowHeight < m_height)
- m_overflowHeight = m_height;
-
- if (canCollapseWithChildren && !topMarginContributor) {
- // Update our max pos/neg bottom margins, since we collapsed our bottom margins
- // with our children.
- if (prevPosMargin > m_maxBottomPosMargin)
- m_maxBottomPosMargin = prevPosMargin;
-
- if (prevNegMargin > m_maxBottomNegMargin)
- m_maxBottomNegMargin = prevNegMargin;
-
- if (!bottomChildQuirk)
- m_bottomMarginQuirk = false;
-
- if (bottomChildQuirk && marginBottom() == 0)
- // We have no bottom margin and our last child has a quirky margin.
- // We will pick up this quirky margin and pass it through.
- // This deals with the <td><div><p> case.
- m_bottomMarginQuirk = true;
- }
-
- setLayouted();
-
- // kdDebug( 6040 ) << "layouted = " << layouted_ << endl;
-}
-
-bool RenderFlow::checkClear(RenderObject *child)
-{
- //kdDebug( 6040 ) << "checkClear oldheight=" << m_height << endl;
- int bottom = 0;
- switch(child->style()->clear())
- {
- case CNONE:
- return false;
- case CLEFT:
- bottom = leftBottom();
- break;
- case CRIGHT:
- bottom = rightBottom();
- break;
- case CBOTH:
- bottom = floatBottom();
- break;
- }
-
- if (m_height < bottom) {
- m_height = bottom;
- return true;
- }
- return false;
-}
-
-void RenderFlow::insertSpecialObject(RenderObject *o)
-{
- // Create the list of special objects if we don't aleady have one
- if (!specialObjects) {
- specialObjects = new QSortedList<SpecialObject>;
- specialObjects->setAutoDelete(true);
- }
- else {
- // Don't insert the object again if it's already in the list
- QPtrListIterator<SpecialObject> it(*specialObjects);
- SpecialObject* f;
- while ( (f = it.current()) ) {
- if (f->node == o) return;
- ++it;
- }
- }
-
- // Create the special object entry & append it to the list
-
- SpecialObject *newObj;
- if (o->isPositioned()) {
- // positioned object
- newObj = new SpecialObject(SpecialObject::Positioned);
- setOverhangingContents();
- }
- else if (o->isFloating()) {
- // floating object
- if ( !o->layouted() )
- o->layout();
-
- if(o->style()->floating() == FLEFT)
- newObj = new SpecialObject(SpecialObject::FloatLeft);
- else
- newObj = new SpecialObject(SpecialObject::FloatRight);
-
- newObj->startY = -1;
- newObj->endY = -1;
- newObj->width = o->width() + o->marginLeft() + o->marginRight();
- }
- else {
- // We should never get here, as insertSpecialObject() should only ever be called with positioned or floating
- // objects.
- KHTMLAssert(false);
- newObj = 0; // keep gcc's uninitialized variable warnings happy
- }
-
- newObj->count = specialObjects->count();
- newObj->node = o;
-
- specialObjects->append(newObj);
-}
-
-void RenderFlow::removeSpecialObject(RenderObject *o)
-{
- if (specialObjects) {
- QPtrListIterator<SpecialObject> it(*specialObjects);
- while (it.current()) {
- if (it.current()->node == o)
- specialObjects->removeRef(it.current());
- ++it;
- }
- }
-}
-
-void RenderFlow::positionNewFloats()
-{
- if(!specialObjects) return;
- SpecialObject *f = specialObjects->getLast();
- if(!f || f->startY != -1) return;
- SpecialObject *lastFloat;
- while(1)
- {
- lastFloat = specialObjects->prev();
- if(!lastFloat || (lastFloat->startY != -1 && !(lastFloat->type==SpecialObject::Positioned) )) {
- specialObjects->next();
- break;
- }
- f = lastFloat;
- }
-
-
- int y = m_height;
-
-
- // the float can not start above the y position of the last positioned float.
- if(lastFloat && lastFloat->startY > y)
- y = lastFloat->startY;
-
- while(f)
- {
- //skip elements copied from elsewhere and positioned elements
- if (f->node->containingBlock()!=this || f->type==SpecialObject::Positioned)
- {
- f = specialObjects->next();
- continue;
- }
-
- RenderObject *o = f->node;
- int _height = o->height() + o->marginTop() + o->marginBottom();
-
- int ro = rightOffset(); // Constant part of right offset.
- int lo = leftOffset(); // Constat part of left offset.
- int fwidth = f->width; // The width we look for.
- //kdDebug( 6040 ) << " Object width: " << fwidth << " available width: " << ro - lo << endl;
- if (ro - lo < fwidth)
- fwidth = ro - lo; // Never look for more than what will be available.
- if (o->style()->floating() == FLEFT)
- {
- if ( o->style()->clear() & CLEFT )
- y = QMAX( leftBottom(), y );
- int heightRemainingLeft = 1;
- int heightRemainingRight = 1;
- int fx = leftRelOffset(y,lo, &heightRemainingLeft);
- while (rightRelOffset(y,ro, &heightRemainingRight)-fx < fwidth)
- {
- y += QMIN( heightRemainingLeft, heightRemainingRight );
- fx = leftRelOffset(y,lo, &heightRemainingLeft);
- }
- if (fx<0) fx=0;
- f->left = fx;
- //kdDebug( 6040 ) << "positioning left aligned float at (" << fx + o->marginLeft() << "/" << y + o->marginTop() << ") fx=" << fx << endl;
- o->setPos(fx + o->marginLeft(), y + o->marginTop());
- }
- else
- {
- if ( o->style()->clear() & CRIGHT )
- y = QMAX( rightBottom(), y );
- int heightRemainingLeft = 1;
- int heightRemainingRight = 1;
- int fx = rightRelOffset(y,ro, &heightRemainingRight);
- while (fx - leftRelOffset(y,lo, &heightRemainingLeft) < fwidth)
- {
- y += QMIN(heightRemainingLeft, heightRemainingRight);
- fx = rightRelOffset(y,ro, &heightRemainingRight);
- }
- if (fx<f->width) fx=f->width;
- f->left = fx - f->width;
- //kdDebug( 6040 ) << "positioning right aligned float at (" << fx - o->marginRight() - o->width() << "/" << y + o->marginTop() << ")" << endl;
- o->setPos(fx - o->marginRight() - o->width(), y + o->marginTop());
- }
- f->startY = y;
- f->endY = f->startY + _height;
-
-
- //kdDebug( 6040 ) << "specialObject x/y= (" << f->left << "/" << f->startY << "-" << f->width << "/" << f->endY - f->startY << ")" << endl;
-
- f = specialObjects->next();
- }
-}
-
-void RenderFlow::newLine()
-{
- positionNewFloats();
- // set y position
- int newY = 0;
- switch(m_clearStatus)
- {
- case CLEFT:
- newY = leftBottom();
- break;
- case CRIGHT:
- newY = rightBottom();
- break;
- case CBOTH:
- newY = floatBottom();
- default:
- break;
- }
- if(m_height < newY)
- {
-// kdDebug( 6040 ) << "adjusting y position" << endl;
- m_height = newY;
- }
- m_clearStatus = CNONE;
-}
-
-
-int
-RenderFlow::leftOffset() const
-{
- int left = 0;
-
- left += borderLeft() + paddingLeft();
-
- if ( firstLine && style()->direction() == LTR ) {
- int cw=0;
- if (style()->textIndent().isPercent())
- cw = containingBlock()->contentWidth();
- left += style()->textIndent().minWidth(cw);
- }
-
- return left;
-}
-
-int
-RenderFlow::leftRelOffset(int y, int fixedOffset, int *heightRemaining ) const
-{
- int left = fixedOffset;
- if(!specialObjects)
- return left;
-
- if ( heightRemaining ) *heightRemaining = 1;
- SpecialObject* r;
- QPtrListIterator<SpecialObject> it(*specialObjects);
- for ( ; (r = it.current()); ++it )
- {
- //kdDebug( 6040 ) <<(void *)this << " left: sy, ey, x, w " << r->startY << "," << r->endY << "," << r->left << "," << r->width << " " << endl;
- if (r->startY <= y && r->endY > y &&
- r->type == SpecialObject::FloatLeft &&
- r->left + r->width > left) {
- left = r->left + r->width;
- if ( heightRemaining ) *heightRemaining = r->endY - y;
- }
- }
- //kdDebug( 6040 ) << "leftOffset(" << y << ") = " << left << endl;
- return left;
-}
-
-int
-RenderFlow::rightOffset() const
-{
- int right = m_width;
-
- right -= borderRight() + paddingRight();
-
- if ( firstLine && style()->direction() == RTL ) {
- int cw=0;
- if (style()->textIndent().isPercent())
- cw = containingBlock()->contentWidth();
- right += style()->textIndent().minWidth(cw);
- }
-
- return right;
-}
-
-int
-RenderFlow::rightRelOffset(int y, int fixedOffset, int *heightRemaining ) const
-{
- int right = fixedOffset;
-
- if (!specialObjects) return right;
-
- if (heightRemaining) *heightRemaining = 1;
- SpecialObject* r;
- QPtrListIterator<SpecialObject> it(*specialObjects);
- for ( ; (r = it.current()); ++it )
- {
- //kdDebug( 6040 ) << "right: sy, ey, x, w " << r->startY << "," << r->endY << "," << r->left << "," << r->width << " " << endl;
- if (r->startY <= y && r->endY > y &&
- r->type == SpecialObject::FloatRight &&
- r->left < right) {
- right = r->left;
- if ( heightRemaining ) *heightRemaining = r->endY - y;
- }
- }
- //kdDebug( 6040 ) << "rightOffset(" << y << ") = " << right << endl;
- return right;
-}
-
-unsigned short
-RenderFlow::lineWidth(int y) const
-{
- //kdDebug( 6040 ) << "lineWidth(" << y << ")=" << rightOffset(y) - leftOffset(y) << endl;
- return rightOffset(y) - leftOffset(y);
-}
-
-int
-RenderFlow::nearestFloatBottom(int height) const
-{
- if (!specialObjects) return 0;
- int bottom=0;
- SpecialObject* r;
- QPtrListIterator<SpecialObject> it(*specialObjects);
- for ( ; (r = it.current()); ++it )
- if (r->endY>height && (r->endY<bottom || bottom==0) && (int)r->type <= (int)SpecialObject::FloatRight)
- bottom=r->endY;
- return bottom;
-}
-
-int
-RenderFlow::floatBottom() const
-{
- if (!specialObjects) return 0;
- int bottom=0;
- SpecialObject* r;
- QPtrListIterator<SpecialObject> it(*specialObjects);
- for ( ; (r = it.current()); ++it )
- if (r->endY>bottom && (int)r->type <= (int)SpecialObject::FloatRight)
- bottom=r->endY;
- return bottom;
-}
-
-int
-RenderFlow::lowestPosition() const
-{
- int bottom = RenderBox::lowestPosition();
- //kdDebug(0) << renderName() << "("<<this<<") lowest = " << bottom << endl;
- int lp = 0;
- RenderObject *last = 0;
- if ( !m_childrenInline ) {
- last = lastChild();
- while( last && (last->isPositioned() || last->isFloating()) )
- last = last->previousSibling();
- if( last )
- lp = last->yPos() + last->lowestPosition();
- }
-
- if( lp > bottom )
- bottom = lp;
-
- //kdDebug(0) << " bottom = " << bottom << endl;
-
- if (specialObjects) {
- SpecialObject* r;
- QPtrListIterator<SpecialObject> it(*specialObjects);
- for ( ; (r = it.current()); ++it ) {
- lp = 0;
- if ( r->type == SpecialObject::FloatLeft || r->type == SpecialObject::FloatRight ){
- lp = r->startY + r->node->lowestPosition();
- //kdDebug(0) << r->node->renderName() << " lp = " << lp << "startY=" << r->startY << endl;
- } else if ( r->type == SpecialObject::Positioned ) {
- lp = r->node->yPos() + r->node->lowestPosition();
- }
- if( lp > bottom)
- bottom = lp;
- }
- }
-
- if ( overhangingContents() ) {
- RenderObject *child = firstChild();
- while( child ) {
- if ( child != last && child->overhangingContents() ) {
- int lp = child->yPos() + child->lowestPosition();
- if ( lp > bottom ) bottom = lp;
- }
- child = child->nextSibling();
- }
- }
-
- //kdDebug(0) << renderName() << " bottom final = " << bottom << endl;
- return bottom;
-}
-
-int RenderFlow::rightmostPosition() const
-{
- int right = RenderBox::rightmostPosition();
-
- RenderObject *c;
- for (c = firstChild(); c; c = c->nextSibling()) {
- if (!c->isPositioned() && !c->isFloating()) {
- int childRight = c->xPos() + c->rightmostPosition();
- if (childRight > right)
- right = childRight;
- }
- }
-
- if (specialObjects) {
- SpecialObject* r;
- QPtrListIterator<SpecialObject> it(*specialObjects);
- for ( ; (r = it.current()); ++it ) {
- int specialRight=0;
- if ( r->type == SpecialObject::FloatLeft || r->type == SpecialObject::FloatRight ){
- specialRight = r->left + r->node->rightmostPosition();
- } else if ( r->type == SpecialObject::Positioned ) {
- specialRight = r->node->xPos() + r->node->rightmostPosition();
- }
- if (specialRight > right)
- right = specialRight;
- }
- }
-
- if ( overhangingContents() ) {
- RenderObject *child = firstChild();
- while( child ) {
- if ( (child->isPositioned() || child->isFloating()) && child->overhangingContents() ) {
- int r = child->xPos() + child->rightmostPosition();
- if ( r > right ) right = r;
- }
- child = child->nextSibling();
- }
- }
-
- return right;
-}
-
-
-int
-RenderFlow::leftBottom()
-{
- if (!specialObjects) return 0;
- int bottom=0;
- SpecialObject* r;
- QPtrListIterator<SpecialObject> it(*specialObjects);
- for ( ; (r = it.current()); ++it )
- if (r->endY>bottom && r->type == SpecialObject::FloatLeft)
- bottom=r->endY;
-
- return bottom;
-}
-
-int
-RenderFlow::rightBottom()
-{
- if (!specialObjects) return 0;
- int bottom=0;
- SpecialObject* r;
- QPtrListIterator<SpecialObject> it(*specialObjects);
- for ( ; (r = it.current()); ++it )
- if (r->endY>bottom && r->type == SpecialObject::FloatRight)
- bottom=r->endY;
-
- return bottom;
-}
-
-void
-RenderFlow::clearFloats()
-{
- //kdDebug( 6040 ) << this <<" clearFloats" << endl;
-
- if (specialObjects) {
- if( overhangingContents() ) {
- specialObjects->first();
- while ( specialObjects->current()) {
- if ( !(specialObjects->current()->type == SpecialObject::Positioned) )
- specialObjects->remove();
- else
- specialObjects->next();
- }
- } else
- specialObjects->clear();
- }
-
- if (isFloating() || isPositioned()) return;
-
- RenderObject *prev = previousSibling();
-
- // find the element to copy the floats from
- // pass non-flows
- // pass fAF's unless they contain overhanging stuff
- bool parentHasFloats = false;
- while (prev) {
- if (!prev->isFlow() || prev->isFloating() ||
- (prev->style()->flowAroundFloats() &&
- // A <table> or <ul> can have a height of 0, so its ypos may be the same
- // as m_y. That's why we have a <= and not a < here. -dwh
- (static_cast<RenderFlow *>(prev)->floatBottom()+prev->yPos() <= m_y ))) {
- if ( prev->isFloating() && parent()->isFlow() ) {
- parentHasFloats = true;
- }
- prev = prev->previousSibling();
- } else
- break;
- }
-
- int offset = m_y;
-
- if ( parentHasFloats ) {
- addOverHangingFloats( static_cast<RenderFlow *>( parent() ), parent()->borderLeft() + parent()->paddingLeft() , offset, false );
- }
-
- if(prev ) {
- if(prev->isTableCell()) return;
-
- offset -= prev->yPos();
- } else {
- prev = parent();
- if(!prev) return;
- }
- //kdDebug() << "RenderFlow::clearFloats found previous "<< (void *)this << " prev=" << (void *)prev<< endl;
-
- // add overhanging special objects from the previous RenderFlow
- if(!prev->isFlow()) return;
- RenderFlow * flow = static_cast<RenderFlow *>(prev);
- if(!flow->specialObjects) return;
- if( ( style()->htmlHacks() || isTable() ) && style()->flowAroundFloats())
- return; //html tables and lists flow as blocks
-
- if(flow->floatBottom() > offset)
- addOverHangingFloats( flow, 0, offset );
-}
-
-void RenderFlow::addOverHangingFloats( RenderFlow *flow, int xoff, int offset, bool child )
-{
-#ifdef DEBUG_LAYOUT
- kdDebug( 6040 ) << (void *)this << ": adding overhanging floats xoff=" << xoff << " offset=" << offset << " child=" << child << endl;
-#endif
- if ( !flow->specialObjects || (child && flow->layer()) )
- return;
-
- // we have overhanging floats
- if(!specialObjects) {
- specialObjects = new QSortedList<SpecialObject>;
- specialObjects->setAutoDelete(true);
- }
-
- QPtrListIterator<SpecialObject> it(*flow->specialObjects);
- SpecialObject *r;
- for ( ; (r = it.current()); ++it ) {
- if ( (int)r->type <= (int)SpecialObject::FloatRight &&
- ( ( !child && r->endY > offset ) ||
- ( child && flow->yPos() + r->endY > height() ) ) ) {
-
- if (child)
- r->noPaint = true;
-
- SpecialObject* f = 0;
- // don't insert it twice!
- QPtrListIterator<SpecialObject> it(*specialObjects);
- while ( (f = it.current()) ) {
- if (f->node == r->node) break;
- ++it;
- }
- if ( !f ) {
- SpecialObject *special = new SpecialObject(r->type);
- special->count = specialObjects->count();
- special->startY = r->startY - offset;
- special->endY = r->endY - offset;
- special->left = r->left - xoff;
- // Applying the child's margin makes no sense in the case where the child was passed in.
- // since his own margin was added already through the subtraction of the |xoff| variable
- // above. |xoff| will equal -flow->marginLeft() in this case, so it's already been taken
- // into account. Only apply this code if |child| is false, since otherwise the left margin
- // will get applied twice. -dwh
- if (!child && flow != parent())
- special->left += flow->marginLeft();
- if ( !child ) {
- special->left -= marginLeft();
- special->noPaint = true;
- }
- special->width = r->width;
- special->node = r->node;
- specialObjects->append(special);
-#ifdef DEBUG_LAYOUT
- kdDebug( 6040 ) << "addOverHangingFloats x/y= (" << special->left << "/" << special->startY << "-" << special->width << "/" << special->endY - special->startY << ")" << endl;
-#endif
- }
- }
- }
-}
-
-
-static inline RenderObject *next(RenderObject *par, RenderObject *current)
-{
- RenderObject *next = 0;
- while(current != 0)
- {
- //kdDebug( 6040 ) << "current = " << current << endl;
- if(!current->isFloating() && !current->isReplaced() && !current->isPositioned())
- next = current->firstChild();
- if(!next) {
- while(current && current != par) {
- next = current->nextSibling();
- if(next) break;
- current = current->parent();
- }
- }
-
- if(!next) break;
-
- if(next->isText() || next->isBR() || next->isFloating() || next->isReplaced() || next->isPositioned())
- break;
- current = next;
- }
- return next;
-}
-
-void RenderFlow::calcInlineMinMaxWidth()
-{
- int inlineMax=0;
- int inlineMin=0;
-
- int cw = containingBlock()->contentWidth();
-
- RenderObject *child = firstChild();
-
- // If we are at the start of a line, we want to ignore all white-space.
- // Also strip spaces if we previously had text that ended in a trailing space.
- bool stripFrontSpaces = true;
- RenderObject* trailingSpaceChild = 0;
-
- bool nowrap, oldnowrap;
- nowrap = oldnowrap = style()->whiteSpace() == NOWRAP;
-
- while(child != 0)
- {
- // positioned children don't affect the minmaxwidth
- if (child->isPositioned())
- {
- child = next(this, child);
- continue;
- }
-
- nowrap = child->style()->whiteSpace() == NOWRAP;
-
- if( !child->isBR() )
- {
- // Step One: determine whether or not we need to go ahead and
- // terminate our current line. Each discrete chunk can become
- // the new min-width, if it is the widest chunk seen so far, and
- // it can also become the max-width.
-
- // Children fall into three categories:
- // (1) An inline flow object. These objects always have a min/max of 0,
- // and are included in the iteration solely so that their margins can
- // be added in. XXXdwh Just adding in the margins is totally bogus, since
- // a <span> could wrap to multiple lines. Technically the left margin should
- // be considered part of the first descendant's start, and the right margin
- // should be considered part of the last descendant's end. Leave this alone
- // for now, but fix later.
- //
- // (2) An inline non-text non-flow object, e.g., an inline replaced element.
- // These objects can always be on a line by themselves, so in this situation
- // we need to go ahead and break the current line, and then add in our own
- // margins and min/max width on its own line, and then terminate the line.
- //
- // (3) A text object. Text runs can have breakable characters at the start,
- // the middle or the end. They may also lose whitespace off the front if
- // we're already ignoring whitespace. In order to compute accurate min-width
- // information, we need three pieces of information.
- // (a) the min-width of the first non-breakable run. Should be 0 if the text string
- // starts with whitespace.
- // (b) the min-width of the last non-breakable run. Should be 0 if the text string
- // ends with whitespace.
- // (c) the min/max width of the string (trimmed for whitespace).
- //
- // If the text string starts with whitespace, then we need to go ahead and
- // terminate our current line (unless we're already in a whitespace stripping
- // mode.
- //
- // If the text string has a breakable character in the middle, but didn't start
- // with whitespace, then we add the width of the first non-breakable run and
- // then end the current line. We then need to use the intermediate min/max width
- // values (if any of them are larger than our current min/max). We then look at
- // the width of the last non-breakable run and use that to start a new line
- // (unless we end in whitespace).
- RenderStyle* cstyle = child->style();
- short childMin = 0;
- short childMax = 0;
-
- if (!child->isText()) {
- // Case (1) and (2). Inline replaced and inline flow elements. Both
- // add in their margins to their min/max values.
- int margins = 0;
- LengthType type = cstyle->marginLeft().type;
- if ( type != Variable )
- margins += (type == Fixed ? cstyle->marginLeft().value : child->marginLeft());
- type = cstyle->marginRight().type;
- if ( type != Variable )
- margins += (type == Fixed ? cstyle->marginRight().value : child->marginRight());
- childMin += margins;
- childMax += margins;
-
- if (child->isInline() && child->isFlow()) {
- // Add in padding for inline flow elements. This is wrong in the
- // same way the margin addition is wrong. XXXdwh fixme.
- int padding = 0;
- type = cstyle->paddingLeft().type;
- if ( type != Variable )
- padding += (type == Fixed ? cstyle->paddingLeft().value : child->paddingLeft());
- type = cstyle->paddingRight().type;
- if ( type != Variable )
- padding += (type == Fixed ? cstyle->paddingRight().value : child->paddingRight());
- childMin += padding;
- childMax += padding;
-
- inlineMin += childMin;
- inlineMax += childMax;
- }
- }
-
- if (!(child->isInline() && child->isFlow()) && !child->isText()) {
- // Case (2). Inline replaced elements.
- // Go ahead and terminate the current line as far as
- // minwidth is concerned.
- childMin += child->minWidth();
- childMax += child->maxWidth();
-
- if (!nowrap || !oldnowrap) {
- if(m_minWidth < inlineMin) m_minWidth = inlineMin;
- inlineMin = 0;
- }
-
- // Add our width to the max.
- inlineMax += childMax;
-
- if (nowrap)
- inlineMin += childMin;
- else {
- // Now check our line.
- inlineMin = childMin;
- if(m_minWidth < inlineMin) m_minWidth = inlineMin;
-
- // Now start a new line.
- inlineMin = 0;
- }
-
- // We are no longer stripping whitespace at the start of
- // a line.
- if (!child->isFloating())
- stripFrontSpaces = false;
- trailingSpaceChild = 0;
- }
- else if (child->isText())
- {
- // Case (3). Text.
- RenderText* t = static_cast<RenderText *>(child);
-
- // Determine if we have a breakable character. Pass in
- // whether or not we should ignore any spaces at the front
- // of the string. If those are going to be stripped out,
- // then they shouldn't be considered in the breakable char
- // check.
- bool hasBreakableChar, hasBreak;
- short beginMin, endMin;
- bool beginWS, endWS;
- short beginMax, endMax;
- t->trimmedMinMaxWidth(beginMin, beginWS, endMin, endWS, hasBreakableChar,
- hasBreak, beginMax, endMax,
- childMin, childMax, stripFrontSpaces);
- if (stripFrontSpaces)
- trailingSpaceChild = child;
- else
- trailingSpaceChild = 0;
-
- // Add in text-indent.
- int ti = cstyle->textIndent().minWidth(cw);
- childMin+=ti; beginMin += ti;
- childMax+=ti; beginMax += ti;
-
- // If we have no breakable characters at all,
- // then this is the easy case. We add ourselves to the current
- // min and max and continue.
- if (!hasBreakableChar) {
- inlineMin += childMin;
- }
- else {
- // We have a breakable character. Now we need to know if
- // we start and end with whitespace.
- if (beginWS) {
- // Go ahead and end the current line.
- if(m_minWidth < inlineMin) m_minWidth = inlineMin;
- }
- else {
- inlineMin += beginMin;
- if(m_minWidth < inlineMin) m_minWidth = inlineMin;
- childMin -= ti;
- }
-
- inlineMin = childMin;
-
- if (endWS) {
- // We end in whitespace, which means we can go ahead
- // and end our current line.
- if(m_minWidth < inlineMin) m_minWidth = inlineMin;
- inlineMin = 0;
- }
- else {
- if(m_minWidth < inlineMin) m_minWidth = inlineMin;
- inlineMin = endMin;
- }
- }
-
- if (hasBreak) {
- inlineMax += beginMax;
- if (m_maxWidth < inlineMax) m_maxWidth = inlineMax;
- if (m_maxWidth < childMax) m_maxWidth = childMax;
- inlineMax = endMax;
- }
- else
- inlineMax += childMax;
- }
- }
- else
- {
- if(m_minWidth < inlineMin) m_minWidth = inlineMin;
- if(m_maxWidth < inlineMax) m_maxWidth = inlineMax;
- inlineMin = inlineMax = 0;
- stripFrontSpaces = true;
- trailingSpaceChild = 0;
- }
-
- oldnowrap = nowrap;
-
- child = next(this, child);
- }
-
- if (trailingSpaceChild && trailingSpaceChild->isText() && !m_pre) {
- // Collapse away the trailing space at the end of a block.
- RenderText* t = static_cast<RenderText *>(trailingSpaceChild);
- const Font *f = t->htmlFont( false );
- QChar space[1]; space[0] = ' ';
- int spaceWidth = f->width(space, 1, 0);
- inlineMax -= spaceWidth;
- if (inlineMin > inlineMax)
- inlineMin = inlineMax;
- }
-
- if(m_minWidth < inlineMin) m_minWidth = inlineMin;
- if(m_maxWidth < inlineMax) m_maxWidth = inlineMax;
-// kdDebug( 6040 ) << "m_minWidth=" << m_minWidth
-// << " m_maxWidth=" << m_maxWidth << endl;
-}
-
-void RenderFlow::calcBlockMinMaxWidth()
-{
- bool nowrap = style()->whiteSpace() == NOWRAP;
-
- RenderObject *child = firstChild();
- while(child != 0)
- {
- // positioned children don't affect the minmaxwidth
- if (child->isPositioned())
- {
- child = child->nextSibling();
- continue;
- }
-
- int margin=0;
- // auto margins don't affect minwidth
-
- Length ml = child->style()->marginLeft();
- Length mr = child->style()->marginRight();
-
- if (style()->textAlign() == KONQ_CENTER)
- {
- if (ml.type==Fixed) margin+=ml.value;
- if (mr.type==Fixed) margin+=mr.value;
- }
- else
- {
- // Call calcWidth on the child to ensure that our margins are
- // up to date. This method can be called before the child has actually
- // calculated its margins (which are computed inside calcWidth).
- child->calcWidth();
-
- if (!(ml.type==Variable) && !(mr.type==Variable))
- {
- if (!(child->style()->width().type==Variable))
- {
- if (child->style()->direction()==LTR)
- margin = child->marginLeft();
- else
- margin = child->marginRight();
- }
- else
- margin = child->marginLeft()+child->marginRight();
-
- }
- else if (!(ml.type == Variable))
- margin = child->marginLeft();
- else if (!(mr.type == Variable))
- margin = child->marginRight();
- }
-
- if (margin<0) margin=0;
-
- int w = child->minWidth() + margin;
- if(m_minWidth < w) m_minWidth = w;
- // IE ignores tables for calculation of nowrap. Makes some sense.
- if ( nowrap && !child->isTable() && m_maxWidth < w )
- m_maxWidth = w;
-
- w = child->maxWidth() + margin;
- if(m_maxWidth < w) m_maxWidth = w;
- child = child->nextSibling();
- }
-}
-
-void RenderFlow::calcMinMaxWidth()
-{
- KHTMLAssert( !minMaxKnown() );
-
-#ifdef DEBUG_LAYOUT
- kdDebug( 6040 ) << renderName() << "(RenderBox)::calcMinMaxWidth() this=" << this << endl;
-#endif
-
- m_minWidth = 0;
- m_maxWidth = 0;
-
- if (isInline()) {
- // Irrelevant, since some enclosing block will actually flow our children.
- setMinMaxKnown();
- return;
- }
-
- bool preOrNowrap = style()->whiteSpace() != NORMAL;
- if (childrenInline())
- calcInlineMinMaxWidth();
- else
- calcBlockMinMaxWidth();
-
- if(m_maxWidth < m_minWidth) m_maxWidth = m_minWidth;
-
- if (preOrNowrap && childrenInline())
- m_minWidth = m_maxWidth;
-
- if (style()->width().isFixed() && style()->width().value > 0)
- m_maxWidth = KMAX(m_minWidth,short(style()->width().value));
-
- int toAdd = 0;
- toAdd = borderLeft() + borderRight() + paddingLeft() + paddingRight();
-
- m_minWidth += toAdd;
- m_maxWidth += toAdd;
-
- // Scrolling marquees like to use this trick:
- // <td><div style="overflow:hidden; width:300px"><nobr>.....[lots of text].....</nobr></div></td>
- // We need to sanity-check our m_minWidth, and not let it exceed our clipped boundary. -dwh
- if (style()->overflow() == OHIDDEN && m_minWidth > m_width)
- m_minWidth = m_width;
-
- setMinMaxKnown();
-
- //kdDebug( 6040 ) << "Text::calcMinMaxWidth(" << this << "): min = " << m_minWidth << " max = " << m_maxWidth << endl;
- // ### compare with min/max width set in style sheet...
-}
-
-void RenderFlow::close()
-{
- if(lastChild() && lastChild()->isAnonymousBox()) {
- lastChild()->close();
- }
-
- RenderBox::close();
-}
-
-short RenderFlow::offsetWidth() const
-{
- if (isInline() && !isText()) {
- short w = 0;
- RenderObject* object = firstChild();
- while (object) {
- w += object->offsetWidth();
- object = object->nextSibling();
- }
- return w;
- }
- return width();
-}
-
-int RenderFlow::offsetHeight() const
-{
- if (isInline() && !isText() && firstChild())
- return firstChild()->offsetHeight();
- return height();
-}
-
-int RenderFlow::offsetLeft() const
-{
- int x = RenderBox::offsetLeft();
- RenderObject* textChild = (RenderObject*)this;
- while (textChild && textChild->isInline() && !textChild->isText())
- textChild = textChild->firstChild();
- if (textChild && textChild != this)
- x += textChild->xPos() - textChild->borderLeft() - textChild->paddingLeft();
- return x;
-}
-
-int RenderFlow::offsetTop() const
-{
- RenderObject* textChild = (RenderObject*)this;
- while (textChild && textChild->isInline() && !textChild->isText())
- textChild = textChild->firstChild();
- int y = RenderBox::offsetTop();
- if (textChild && textChild != this)
- y += textChild->yPos() - textChild->borderTop() - textChild->paddingTop();
- return y;
+ RenderObject* result =
+ (style->display() == INLINE) ?
+ (RenderObject*)(new (arena) RenderInline(node)) :
+ (RenderObject*)(new (arena) RenderBlock(node));
+ result->setStyle(style);
+ return result;
}
RenderFlow* RenderFlow::continuationBefore(RenderObject* beforeChild)
@@ -1811,155 +78,11 @@ RenderFlow* RenderFlow::continuationBefore(RenderObject* beforeChild)
return last;
}
-static RenderFlow* cloneInline(RenderFlow* src)
-{
- RenderFlow *o = new (src->renderArena()) RenderFlow(src->element());
- o->setStyle(src->style());
- return o;
-}
-
-void RenderFlow::splitInlines(RenderFlow* fromBlock, RenderFlow* toBlock,
- RenderFlow* middleBlock,
- RenderObject* beforeChild, RenderFlow* oldCont)
-{
- // Create a clone of this inline.
- RenderFlow* clone = cloneInline(this);
- clone->setContinuation(oldCont);
-
- // Now take all of the children from beforeChild to the end and remove
- // then from |this| and place them in the clone.
- RenderObject* o = beforeChild;
- while (o) {
- RenderObject* tmp = o;
- o = tmp->nextSibling();
- clone->appendChildNode(removeChildNode(tmp));
- tmp->setLayouted(false);
- tmp->setMinMaxKnown(false);
- }
-
- // Hook |clone| up as the continuation of the middle block.
- middleBlock->setContinuation(clone);
-
- // We have been reparented and are now under the fromBlock. We need
- // to walk up our inline parent chain until we hit the containing block.
- // Once we hit the containing block we're done.
- KHTMLAssert(parent()->isFlow());
- RenderFlow* curr = static_cast<RenderFlow*>(parent());
- RenderFlow* currChild = this;
- while (curr && curr != fromBlock) {
- // Create a new clone.
- RenderFlow* cloneChild = clone;
- clone = cloneInline(curr);
-
- // Insert our child clone as the first child.
- clone->appendChildNode(cloneChild);
-
- // Hook the clone up as a continuation of |curr|.
- RenderFlow* oldCont = curr->continuation();
- curr->setContinuation(clone);
- clone->setContinuation(oldCont);
-
- // Now we need to take all of the children starting from the first child
- // *after* currChild and append them all to the clone.
- o = currChild->nextSibling();
- while (o) {
- RenderObject* tmp = o;
- o = tmp->nextSibling();
- clone->appendChildNode(curr->removeChildNode(tmp));
- tmp->setLayouted(false);
- tmp->setMinMaxKnown(false);
- }
-
- // Keep walking up the chain.
- currChild = curr;
- KHTMLAssert(curr->parent()->isFlow());
- curr = static_cast<RenderFlow*>(curr->parent());
- }
-
- // Now we are at the block level. We need to put the clone into the toBlock.
- toBlock->appendChildNode(clone);
-
- // Now take all the children after currChild and remove them from the fromBlock
- // and put them in the toBlock.
- o = currChild->nextSibling();
- while (o) {
- RenderObject* tmp = o;
- o = tmp->nextSibling();
- toBlock->appendChildNode(fromBlock->removeChildNode(tmp));
- }
-}
-
-void RenderFlow::splitFlow(RenderObject* beforeChild, RenderFlow* newBlockBox,
- RenderObject* newChild, RenderFlow* oldCont)
-{
- RenderObject* block = containingBlock();
- RenderFlow* pre = 0;
- RenderFlow* post = 0;
-
- RenderStyle* newStyle = new RenderStyle();
- newStyle->inheritFrom(block->style());
- newStyle->setDisplay(BLOCK);
- pre = new (renderArena()) RenderFlow(0 /* anonymous box */);
- pre->setStyle(newStyle);
- pre->setIsAnonymousBox(true);
- pre->setChildrenInline(true);
-
- newStyle = new RenderStyle();
- newStyle->inheritFrom(block->style());
- newStyle->setDisplay(BLOCK);
- post = new (renderArena()) RenderFlow(0 /* anonymous box */);
- post->setStyle(newStyle);
- post->setIsAnonymousBox(true);
- post->setChildrenInline(true);
-
- RenderObject* boxFirst = block->firstChild();
- block->insertChildNode(pre, boxFirst);
- block->insertChildNode(newBlockBox, boxFirst);
- block->insertChildNode(post, boxFirst);
- block->setChildrenInline(false);
-
- RenderObject* o = boxFirst;
- while (o)
- {
- RenderObject* no = o;
- o = no->nextSibling();
- pre->appendChildNode(block->removeChildNode(no));
- no->setLayouted(false);
- no->setMinMaxKnown(false);
- }
-
- splitInlines(pre, post, newBlockBox, beforeChild, oldCont);
-
- // We already know the newBlockBox isn't going to contain inline kids, so avoid wasting
- // time in makeChildrenNonInline by just setting this explicitly up front.
- newBlockBox->setChildrenInline(false);
-
- // We don't just call addChild, since it would pass things off to the
- // continuation, so we call addChildToFlow explicitly instead. We delayed
- // adding the newChild until now so that the |newBlockBox| would be fully
- // connected, thus allowing newChild access to a renderArena should it need
- // to wrap itself in additional boxes (e.g., table construction).
- newBlockBox->addChildToFlow(newChild, 0);
-
- // XXXdwh is any of this even necessary? I don't think it is.
- pre->close();
- pre->setPos(0, -500000);
- pre->setLayouted(false);
- newBlockBox->close();
- newBlockBox->setPos(0, -500000);
- newBlockBox->setLayouted(false);
- post->close();
- post->setPos(0, -500000);
- post->setLayouted(false);
-
- block->setLayouted(false);
- block->setMinMaxKnown(false);
-}
-
void RenderFlow::addChildWithContinuation(RenderObject* newChild, RenderObject* beforeChild)
{
RenderFlow* flow = continuationBefore(beforeChild);
- KHTMLAssert(!beforeChild || beforeChild->parent()->isFlow());
+ KHTMLAssert(!beforeChild || beforeChild->parent()->isRenderBlock() ||
+ beforeChild->parent()->isRenderInline());
RenderFlow* beforeChildParent = beforeChild ? static_cast<RenderFlow*>(beforeChild->parent()) :
(flow->continuation() ? flow->continuation() : flow);
@@ -1999,382 +122,3 @@ void RenderFlow::addChild(RenderObject *newChild, RenderObject *beforeChild)
return addChildToFlow(newChild, beforeChild);
}
-void RenderFlow::addChildToFlow(RenderObject* newChild, RenderObject* beforeChild)
-{
- setLayouted( false );
-
- bool madeBoxesNonInline = FALSE;
-
- RenderStyle* pseudoStyle=0;
- if (!isInline() && (!firstChild() || firstChild() == beforeChild) && newChild->isText())
- {
- RenderText* newTextChild = static_cast<RenderText*>(newChild);
- //kdDebug( 6040 ) << "first letter" << endl;
-
- if ( (pseudoStyle=style()->getPseudoStyle(RenderStyle::FIRST_LETTER)) ) {
- RenderFlow* firstLetter = new (renderArena()) RenderFlow(0 /* anonymous box */);
- pseudoStyle->setDisplay( INLINE );
- pseudoStyle->setPosition( STATIC ); // CSS2 says first-letter can't be positioned.
- firstLetter->setStyle(pseudoStyle);
- addChild(firstLetter);
-
- DOMStringImpl* oldText = newTextChild->string();
-
- if(oldText->l >= 1) {
- unsigned int length = 0;
- while ( length < oldText->l &&
- ( (oldText->s+length)->isSpace() || (oldText->s+length)->isPunct() ) )
- length++;
- length++;
- //kdDebug( 6040 ) << "letter= '" << DOMString(oldText->substring(0,length)).string() << "'" << endl;
- newTextChild->setText(oldText->substring(length,oldText->l-length));
-
- RenderText* letter = new (renderArena()) RenderText(newTextChild->element(), oldText->substring(0,length));
- RenderStyle* newStyle = new RenderStyle();
- newStyle->inheritFrom(pseudoStyle);
- letter->setStyle(newStyle);
- firstLetter->addChild(letter);
- }
- firstLetter->close();
- }
- }
-
- insertPseudoChild(RenderStyle::BEFORE, newChild, beforeChild);
-
- // If the requested beforeChild is not one of our children, then this is most likely because
- // there is an anonymous block box within this object that contains the beforeChild. So
- // just insert the child into the anonymous block box instead of here.
- if (beforeChild && beforeChild->parent() != this) {
-
- KHTMLAssert(beforeChild->parent());
- KHTMLAssert(beforeChild->parent()->isAnonymousBox());
-
- if (newChild->isInline()) {
- beforeChild->parent()->addChild(newChild,beforeChild);
- newChild->setLayouted( false );
- newChild->setMinMaxKnown( false );
- return;
- }
- else if (beforeChild->parent()->firstChild() != beforeChild)
- return beforeChild->parent()->addChild(newChild, beforeChild);
- else
- return addChildToFlow(newChild, beforeChild->parent());
- }
-
- // prevent non-layouted elements from getting painted by pushing them far above the top of the
- // page
- if (!newChild->isInline())
- newChild->setPos(newChild->xPos(), -500000);
-
- if (!newChild->isText())
- {
- if (newChild->style()->position() != STATIC)
- setOverhangingContents();
- }
-
- // RenderFlow has to either have all of its children inline, or all of its children as blocks.
- // So, if our children are currently inline and a block child has to be inserted, we move all our
- // inline children into anonymous block boxes
- if ( m_childrenInline && !newChild->isInline() && !newChild->isSpecial() )
- {
- if (isInline()) {
- // We are placing a block inside an inline. We have to perform a split of this
- // inline into continuations. This involves creating an anonymous block box to hold
- // |newChild|. We then make that block box a continuation of this inline. We take all of
- // the children after |beforeChild| and put them in a clone of this object.
- RenderStyle *newStyle = new RenderStyle();
- newStyle->inheritFrom(style());
- newStyle->setDisplay(BLOCK);
-
- RenderFlow *newBox = new (renderArena()) RenderFlow(0 /* anonymous box */);
- newBox->setStyle(newStyle);
- newBox->setIsAnonymousBox(true);
- RenderFlow* oldContinuation = continuation();
- setContinuation(newBox);
- splitFlow(beforeChild, newBox, newChild, oldContinuation);
- return;
- }
- else {
- // This is a block with inline content. Wrap the inline content in anonymous blocks.
- makeChildrenNonInline(beforeChild);
- madeBoxesNonInline = true;
- }
-
- if (beforeChild) {
- if ( beforeChild->parent() != this ) {
- beforeChild = beforeChild->parent();
- KHTMLAssert(beforeChild->isAnonymousBox());
- KHTMLAssert(beforeChild->parent() == this);
- }
- }
- }
- else if (!m_childrenInline && !newChild->isSpecial())
- {
- // If we're inserting an inline child but all of our children are blocks, then we have to make sure
- // it is put into an anomyous block box. We try to use an existing anonymous box if possible, otherwise
- // a new one is created and inserted into our list of children in the appropriate position.
- if(newChild->isInline()) {
- if (beforeChild) {
- if (beforeChild->previousSibling() && beforeChild->previousSibling()->isAnonymousBox()) {
- beforeChild->previousSibling()->addChild(newChild);
- newChild->setLayouted( false );
- newChild->setMinMaxKnown( false );
- return;
- }
- }
- else{
- if (m_last && m_last->isAnonymousBox()) {
- m_last->addChild(newChild);
- newChild->setLayouted( false );
- newChild->setMinMaxKnown( false );
- return;
- }
- }
-
- // no suitable existing anonymous box - create a new one
- RenderStyle *newStyle = new RenderStyle();
- newStyle->inheritFrom(style());
- newStyle->setDisplay(BLOCK);
-
- RenderFlow *newBox = new (renderArena()) RenderFlow(0 /* anonymous box */);
- newBox->setStyle(newStyle);
- newBox->setIsAnonymousBox(true);
-
- RenderBox::addChild(newBox,beforeChild);
- newBox->addChild(newChild);
- newBox->setPos(newBox->xPos(), -500000);
-
- newChild->setLayouted( false );
- newChild->setMinMaxKnown( false );
- return;
- }
- else {
- // We are adding another block child... if the current last child is an anonymous box
- // then it needs to be closed.
- // ### get rid of the closing thing altogether this will only work during initial parsing
- if (lastChild() && lastChild()->isAnonymousBox()) {
- lastChild()->close();
- }
- }
- }
-
- RenderBox::addChild(newChild,beforeChild);
- // ### care about aligned stuff
-
- newChild->setLayouted( false );
- newChild->setMinMaxKnown( false );
- insertPseudoChild(RenderStyle::AFTER, newChild, beforeChild);
-
- if ( madeBoxesNonInline )
- removeLeftoverAnonymousBoxes();
-}
-
-static void getInlineRun(RenderObject* start, RenderObject* stop,
- RenderObject*& inlineRunStart,
- RenderObject*& inlineRunEnd)
-{
- // Beginning at |start| we find the largest contiguous run of inlines that
- // we can. We denote the run with start and end points, |inlineRunStart|
- // and |inlineRunEnd|. Note that these two values may be the same if
- // we encounter only one inline.
- //
- // We skip any non-inlines we encounter as long as we haven't found any
- // inlines yet.
- //
- // |stop| indicates a non-inclusive stop point. Regardless of whether |stop|
- // is inline or not, we will not include it. It's as though we encountered
- // a non-inline.
- inlineRunStart = inlineRunEnd = 0;
-
- // Start by skipping as many non-inlines as we can.
- RenderObject * curr = start;
- while (curr && !curr->isInline())
- curr = curr->nextSibling();
-
- if (!curr)
- return; // No more inline children to be found.
-
- inlineRunStart = inlineRunEnd = curr;
- curr = curr->nextSibling();
- while (curr && curr->isInline() && (curr != stop)) {
- inlineRunEnd = curr;
- curr = curr->nextSibling();
- }
-}
-
-void RenderFlow::makeChildrenNonInline(RenderObject *insertionPoint)
-{
- // makeChildrenNonInline takes a block whose children are *all* inline and it
- // makes sure that inline children are coalesced under anonymous
- // blocks. If |insertionPoint| is defined, then it represents the insertion point for
- // the new block child that is causing us to have to wrap all the inlines. This
- // means that we cannot coalesce inlines before |insertionPoint| with inlines following
- // |insertionPoint|, because the new child is going to be inserted in between the inlines,
- // splitting them.
- KHTMLAssert(!isInline());
- KHTMLAssert(!insertionPoint || insertionPoint->parent() == this);
-
- m_childrenInline = false;
-
- RenderObject *child = firstChild();
-
- while (child) {
- RenderObject *inlineRunStart, *inlineRunEnd;
- getInlineRun(child, insertionPoint, inlineRunStart, inlineRunEnd);
-
- if (!inlineRunStart)
- break;
-
- child = inlineRunEnd->nextSibling();
-
- RenderStyle *newStyle = new RenderStyle();
- newStyle->inheritFrom(style());
- newStyle->setDisplay(BLOCK);
-
- RenderFlow *box = new (renderArena()) RenderFlow(0 /* anonymous box */);
- box->setStyle(newStyle);
- box->setIsAnonymousBox(true);
-
- insertChildNode(box, inlineRunStart);
- RenderObject* o = inlineRunStart;
- while(o != inlineRunEnd)
- {
- RenderObject* no = o;
- o = no->nextSibling();
- box->appendChildNode(removeChildNode(no));
- }
- box->appendChildNode(removeChildNode(inlineRunEnd));
- box->close();
- box->setPos(box->xPos(), -500000);
- box->setLayouted(false);
- }
-
- setLayouted(false);
-}
-
-void RenderFlow::removeChild(RenderObject *oldChild)
-{
- // If this child is a block, and if our previous and next siblings are
- // both anonymous blocks with inline content, then we can go ahead and
- // fold the inline content back together.
- RenderObject* prev = oldChild->previousSibling();
- RenderObject* next = oldChild->nextSibling();
- bool mergedBlocks = false;
- if (!isInline() && !oldChild->isInline() && !oldChild->continuation() &&
- prev && prev->isAnonymousBox() && prev->childrenInline() &&
- next && next->isAnonymousBox() && next->childrenInline()) {
- // Take all the children out of the |next| block and put them in
- // the |prev| block.
- RenderObject* o = next->firstChild();
- while (o) {
- RenderObject* no = o;
- o = no->nextSibling();
- prev->appendChildNode(next->removeChildNode(no));
- no->setLayouted(false);
- no->setMinMaxKnown(false);
- }
- prev->setLayouted(false);
- prev->setMinMaxKnown(false);
-
- // Nuke the now-empty block.
- next->detach(renderArena());
-
- mergedBlocks = true;
- }
-
- RenderBox::removeChild(oldChild);
-
- if (mergedBlocks && prev && !prev->previousSibling() && !prev->nextSibling()) {
- // The remerge has knocked us down to containing only a single anonymous
- // box. We can go ahead and pull the content right back up into our
- // box.
- RenderObject* anonBlock = removeChildNode(prev);
- m_childrenInline = true;
- RenderObject* o = anonBlock->firstChild();
- while (o) {
- RenderObject* no = o;
- o = no->nextSibling();
- appendChildNode(anonBlock->removeChildNode(no));
- no->setLayouted(false);
- no->setMinMaxKnown(false);
- }
- setLayouted(false);
- setMinMaxKnown(false);
- }
-}
-
-bool RenderFlow::nodeAtPoint(NodeInfo& info, int _x, int _y, int _tx, int _ty, bool inBox)
-{
- if (specialObjects) {
- int stx = _tx + xPos();
- int sty = _ty + yPos();
- if (isRoot()) {
- stx += static_cast<RenderRoot*>(this)->view()->contentsX();
- sty += static_cast<RenderRoot*>(this)->view()->contentsY();
- }
- SpecialObject* o;
- QPtrListIterator<SpecialObject> it(*specialObjects);
- for (it.toLast(); (o = it.current()); --it)
- if (o->node->isFloating() && !o->noPaint)
- inBox |= o->node->nodeAtPoint(info, _x, _y,
- stx+o->left + o->node->marginLeft() - o->node->xPos(),
- sty+o->startY + o->node->marginTop() - o->node->yPos());
- }
-
- inBox |= RenderBox::nodeAtPoint(info, _x, _y, _tx, _ty, inBox);
- return inBox;
-}
-
-
-#ifndef NDEBUG
-void RenderFlow::printTree(int indent) const
-{
- RenderBox::printTree(indent);
-
- if(specialObjects)
- {
- QPtrListIterator<SpecialObject> it(*specialObjects);
- SpecialObject *r;
- for ( ; (r = it.current()); ++it )
- {
- QString s;
- s.fill(' ', indent);
- kdDebug() << s << renderName() << ": " <<
- (r->type == SpecialObject::FloatLeft ? "FloatLeft" : (r->type == SpecialObject::FloatRight ? "FloatRight" : "Positioned")) <<
- "[" << r->node->renderName() << ": " << (void*)r->node << "] (" << r->startY << " - " << r->endY << ")" << "width: " << r->width <<
- endl;
- }
- }
-}
-
-void RenderFlow::dump(QTextStream *stream, QString ind) const
-{
- if (m_childrenInline) { *stream << " childrenInline"; }
- if (m_pre) { *stream << " pre"; }
- if (firstLine) { *stream << " firstLine"; }
-
- if(specialObjects && !specialObjects->isEmpty())
- {
- *stream << " special(";
- QPtrListIterator<SpecialObject> it(*specialObjects);
- SpecialObject *r;
- bool first = true;
- for ( ; (r = it.current()); ++it )
- {
- if (!first)
- *stream << ",";
- *stream << r->node->renderName();
- first = false;
- }
- *stream << ")";
- }
-
- // ### EClear m_clearStatus
-
- RenderBox::dump(stream,ind);
-}
-#endif
-
-#undef DEBUG
-#undef DEBUG_LAYOUT
-#undef BOX_DEBUG
diff --git a/WebCore/khtml/rendering/render_flow.h b/WebCore/khtml/rendering/render_flow.h
index 18112b3..1dfb876 100644
--- a/WebCore/khtml/rendering/render_flow.h
+++ b/WebCore/khtml/rendering/render_flow.h
@@ -42,232 +42,22 @@ namespace khtml {
*/
class RenderFlow : public RenderBox
{
-
public:
- RenderFlow(DOM::NodeImpl* node);
-
- virtual ~RenderFlow();
-
- virtual const char *renderName() const
- {
- if (isFloating())
- return "Block (Floating)";
- if (isPositioned())
- return "Block (Positioned)";
- if (isAnonymousBox())
- return "Block (Anonymous)";
- if (isInline()) {
- if (isRelPositioned())
- return "Inline (Rel Positioned)";
- return "Inline";
- }
- if (isRelPositioned())
- return "Block (Rel Positioned)";
- return "Block";
- };
+ RenderFlow(DOM::NodeImpl* node)
+ : RenderBox(node)
+ { m_continuation = 0; }
- virtual void setStyle(RenderStyle *style);
-
- virtual bool isFlow() const { return true; }
- virtual bool childrenInline() const { return m_childrenInline; }
- virtual void setChildrenInline(bool b) { m_childrenInline = b; }
-
- virtual bool isRendered() const { return true; }
-
virtual RenderFlow* continuation() const { return m_continuation; }
void setContinuation(RenderFlow* c) { m_continuation = c; }
RenderFlow* continuationBefore(RenderObject* beforeChild);
- void splitInlines(RenderFlow* fromBlock, RenderFlow* toBlock, RenderFlow* middleBlock,
- RenderObject* beforeChild, RenderFlow* oldCont);
- void splitFlow(RenderObject* beforeChild, RenderFlow* newBlockBox,
- RenderObject* newChild, RenderFlow* oldCont);
void addChildWithContinuation(RenderObject* newChild, RenderObject* beforeChild);
- void addChildToFlow(RenderObject* newChild, RenderObject* beforeChild);
- void removeChild(RenderObject *oldChild);
-
- void makeChildrenNonInline(RenderObject *box2Start = 0);
-
- // overrides RenderObject
-
- virtual void paint(QPainter *, int x, int y, int w, int h,
- int tx, int ty, PaintAction paintAction);
- virtual void paintObject(QPainter *, int x, int y, int w, int h,
- int tx, int ty, PaintAction paintAction);
- void paintFloats(QPainter *p, int _x, int _y,
- int _w, int _h, int _tx, int _ty, bool paintSelection = false);
-
- virtual bool requiresLayer() { return !isTableCell() &&
- (isPositioned() || isRelPositioned() || style()->overflow()==OHIDDEN); }
-
- virtual void layout( );
-
- virtual void close();
-
+ virtual void addChildToFlow(RenderObject* newChild, RenderObject* beforeChild) = 0;
virtual void addChild(RenderObject *newChild, RenderObject *beforeChild = 0);
- virtual unsigned short lineWidth(int y) const;
-
- virtual int lowestPosition() const;
- virtual int rightmostPosition() const;
-
- int rightOffset() const;
- int rightRelOffset(int y, int fixedOffset, int *heightRemaining = 0) const;
- int rightOffset(int y) const { return rightRelOffset(y, rightOffset()); }
-
- int leftOffset() const;
- int leftRelOffset(int y, int fixedOffset, int *heightRemaining = 0) const;
- int leftOffset(int y) const { return leftRelOffset(y, leftOffset()); }
-
-#ifndef NDEBUG
- virtual void printTree(int indent=0) const;
- virtual void dump(QTextStream *stream, QString ind = "") const;
-#endif
-
- virtual bool nodeAtPoint(NodeInfo& info, int x, int y, int tx, int ty, bool inside=false);
+ static RenderObject* createFlow(DOM::NodeImpl* node, RenderStyle* style, RenderArena* arena);
protected:
-
- virtual void newLine();
-
- void layoutBlockChildren( bool relayoutChildren );
- void layoutInlineChildren( bool relayoutChildren );
- void layoutSpecialObjects( bool relayoutChildren );
-
-public:
- int nearestFloatBottom(int height) const;
- int floatBottom() const;
- inline int leftBottom();
- inline int rightBottom();
- bool checkClear(RenderObject *child);
-
- // used to calculate offsetWidth/Height. Overridden by inlines (render_flow) to return
- // the remaining width on a given line (and the height of a single line).
- virtual short offsetWidth() const;
- virtual int offsetHeight() const;
- virtual int offsetLeft() const;
- virtual int offsetTop() const;
-
- void insertSpecialObject(RenderObject *o);
-
- // from BiDiParagraph
- virtual void closeParagraph() { positionNewFloats(); }
-
- void removeSpecialObject(RenderObject *o);
- // called from lineWidth, to position the floats added in the last line.
- void positionNewFloats();
- void clearFloats();
- virtual void calcMinMaxWidth();
- void calcInlineMinMaxWidth();
- void calcBlockMinMaxWidth();
-
- virtual bool containsSpecial() { return specialObjects!=0; }
- virtual bool hasOverhangingFloats() { return floatBottom() > m_height; }
-
- void addOverHangingFloats( RenderFlow *flow, int xoffset, int yoffset, bool child = false );
-
- // implementation of the following functions is in bidi.cpp
- void bidiReorderLine(const BidiIterator &start, const BidiIterator &end);
- BidiIterator findNextLineBreak(BidiIterator &start, QPtrList<BidiIterator>& midpoints);
-
- // The height (and width) of a block when you include overflow spillage out of the bottom
- // of the block (e.g., a <div style="height:25px"> that has a 100px tall image inside
- // it would have an overflow height of borderTop() + paddingTop() + 100px.
- virtual int overflowHeight() const { return m_overflowHeight; }
- virtual int overflowWidth() const { return m_overflowWidth; }
- virtual void setOverflowHeight(int h) { m_overflowHeight = h; }
- virtual void setOverflowWidth(int w) { m_overflowWidth = w; }
-
- virtual bool isSelfCollapsingBlock() const { return m_height == 0; }
- virtual bool isTopMarginQuirk() const { return m_topMarginQuirk; }
- virtual bool isBottomMarginQuirk() const { return m_bottomMarginQuirk; }
-
- virtual short maxTopMargin(bool positive) const {
- if (positive)
- return m_maxTopPosMargin;
- else
- return m_maxTopNegMargin;
- }
- virtual short maxBottomMargin(bool positive) const {
- if (positive)
- return m_maxBottomPosMargin;
- else
- return m_maxBottomNegMargin;
- }
-
- void initMaxMarginValues() {
- if (m_marginTop >= 0)
- m_maxTopPosMargin = m_marginTop;
- else
- m_maxTopNegMargin = -m_marginTop;
- if (m_marginBottom >= 0)
- m_maxBottomPosMargin = m_marginBottom;
- else
- m_maxBottomNegMargin = -m_marginBottom;
- }
-
-protected:
-
- struct SpecialObject {
- enum Type {
- FloatLeft,
- FloatRight,
- Positioned
- };
-
- SpecialObject(Type _type) {
- node = 0;
- startY = 0;
- endY = 0;
- type = _type;
- left = 0;
- width = 0;
- count = 0;
- noPaint = false;
- }
-
- RenderObject* node;
- int startY;
- int endY;
- short left;
- short width;
- short count;
- Type type : 2; // left or right aligned
- bool noPaint: 1;
-
- bool operator==(const SpecialObject& ) const
- {
- return false;
- }
- bool operator<(const SpecialObject& o) const
- {
- if(node->style()->zIndex() == o.node->style()->zIndex())
- return count < o.count;
- return node->style()->zIndex() < o.node->style()->zIndex();
- }
- };
-
- QSortedList<SpecialObject>* specialObjects;
-
-private:
- bool m_childrenInline : 1;
- bool m_pre : 1;
- bool firstLine : 1; // used in inline layouting
- EClear m_clearStatus : 2; // used during layuting of paragraphs
- bool m_topMarginQuirk : 1;
- bool m_bottomMarginQuirk : 1;
-
- short m_maxTopPosMargin;
- short m_maxTopNegMargin;
- short m_maxBottomPosMargin;
- short m_maxBottomNegMargin;
-
- // How much content overflows out of our block vertically or horizontally (all we support
- // for now is spillage out of the bottom and the right, which are the common cases).
- // XXX Generalize to work with top and left as well.
- int m_overflowHeight;
- int m_overflowWidth;
-
// An inline can be split with blocks occurring in between the inline content.
// When this occurs we need a pointer to our next object. We can basically be
// split into a sequence of inlines and blocks. The continuation will either be
diff --git a/WebCore/khtml/rendering/render_form.h b/WebCore/khtml/rendering/render_form.h
index 944d10b..d4d55ac 100644
--- a/WebCore/khtml/rendering/render_form.h
+++ b/WebCore/khtml/rendering/render_form.h
@@ -70,7 +70,6 @@ public:
virtual const char *renderName() const { return "RenderForm"; }
- virtual bool isRendered() const { return true; }
virtual bool isFormElement() const { return true; }
#if APPLE_CHANGES
diff --git a/WebCore/khtml/rendering/render_html.cpp b/WebCore/khtml/rendering/render_html.cpp
index 7a01687..353a21f 100644
--- a/WebCore/khtml/rendering/render_html.cpp
+++ b/WebCore/khtml/rendering/render_html.cpp
@@ -32,7 +32,7 @@
using namespace khtml;
RenderHtml::RenderHtml(DOM::HTMLElementImpl* node)
- : RenderFlow(node)
+ : RenderBlock(node)
{
m_layer = new (node->getDocument()->renderArena()) RenderLayer(this);
}
@@ -43,7 +43,8 @@ RenderHtml::~RenderHtml()
void RenderHtml::setStyle(RenderStyle *style)
{
- RenderFlow::setStyle(style);
+ style->setDisplay(BLOCK); // Don't allow RenderHTML to be inline.
+ RenderBlock::setStyle(style);
setShouldPaintBackgroundOrBorder(true);
}
@@ -115,7 +116,7 @@ void RenderHtml::repaint(bool immediate)
void RenderHtml::layout()
{
- RenderFlow::layout();
+ RenderBlock::layout();
//kdDebug(0) << renderName() << " height = " << m_height << endl;
int lp = lowestPosition();
diff --git a/WebCore/khtml/rendering/render_html.h b/WebCore/khtml/rendering/render_html.h
index bd938f2..29be999 100644
--- a/WebCore/khtml/rendering/render_html.h
+++ b/WebCore/khtml/rendering/render_html.h
@@ -22,7 +22,7 @@
#ifndef RENDER_HTML
#define RENDER_HTML
-#include "render_flow.h"
+#include "render_block.h"
namespace DOM {
@@ -33,7 +33,7 @@ class QScrollView;
namespace khtml {
- class RenderHtml : public RenderFlow
+ class RenderHtml : public RenderBlock
{
public:
RenderHtml(DOM::HTMLElementImpl* node);
diff --git a/WebCore/khtml/rendering/render_image.h b/WebCore/khtml/rendering/render_image.h
index 1beb79f..58f970f 100644
--- a/WebCore/khtml/rendering/render_image.h
+++ b/WebCore/khtml/rendering/render_image.h
@@ -43,7 +43,6 @@ public:
virtual const char *renderName() const { return "RenderImage"; }
- virtual bool isRendered() const { return true; }
virtual bool isImage() const { return true; }
virtual void paintObject( QPainter *p, int /*x*/, int /*y*/, int /*w*/, int /*h*/, int tx, int ty, PaintAction paintAction);
diff --git a/WebCore/khtml/rendering/render_inline.cpp b/WebCore/khtml/rendering/render_inline.cpp
new file mode 100644
index 0000000..d12e1d9
--- /dev/null
+++ b/WebCore/khtml/rendering/render_inline.cpp
@@ -0,0 +1,315 @@
+/*
+ * This file is part of the render object implementation for KHTML.
+ *
+ * Copyright (C) 2003 Apple Computer, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include <kglobal.h>
+#include "render_inline.h"
+#include "render_block.h"
+
+using namespace khtml;
+
+RenderInline::RenderInline(DOM::NodeImpl* node)
+:RenderFlow(node)
+{}
+
+RenderInline::~RenderInline()
+{}
+
+void RenderInline::setStyle(RenderStyle* _style)
+{
+ setInline(true);
+ RenderFlow::setStyle(_style);
+ // Ensure that all of the split inlines pick up the new style. We
+ // only do this if we're an inline, since we don't want to propagate
+ // a block's style to the other inlines.
+ // e.g., <font>foo <h4>goo</h4> moo</font>. The <font> inlines before
+ // and after the block share the same style, but the block doesn't
+ // need to pass its style on to anyone else.
+ RenderFlow* currCont = continuation();
+ while (currCont) {
+ if (currCont->isInline()) {
+ RenderFlow* nextCont = currCont->continuation();
+ currCont->setContinuation(0);
+ currCont->setStyle(style());
+ currCont->setContinuation(nextCont);
+ }
+ currCont = currCont->continuation();
+ }
+}
+
+void RenderInline::addChildToFlow(RenderObject* newChild, RenderObject* beforeChild)
+{
+ setLayouted( false );
+
+ insertPseudoChild(RenderStyle::BEFORE, newChild, beforeChild);
+
+ if (!newChild->isText() && newChild->style()->position() != STATIC)
+ setOverhangingContents();
+
+ if (!newChild->isInline() && !newChild->isSpecial() )
+ {
+ // We are placing a block inside an inline. We have to perform a split of this
+ // inline into continuations. This involves creating an anonymous block box to hold
+ // |newChild|. We then make that block box a continuation of this inline. We take all of
+ // the children after |beforeChild| and put them in a clone of this object.
+ RenderStyle *newStyle = new RenderStyle();
+ newStyle->inheritFrom(style());
+ newStyle->setDisplay(BLOCK);
+
+ RenderBlock *newBox = new (renderArena()) RenderBlock(0 /* anonymous box */);
+ newBox->setStyle(newStyle);
+ newBox->setIsAnonymousBox(true);
+ RenderFlow* oldContinuation = continuation();
+ setContinuation(newBox);
+ splitFlow(beforeChild, newBox, newChild, oldContinuation);
+ return;
+ }
+
+ RenderBox::addChild(newChild,beforeChild);
+
+ newChild->setLayouted( false );
+ newChild->setMinMaxKnown( false );
+ insertPseudoChild(RenderStyle::AFTER, newChild, beforeChild);
+}
+
+static RenderFlow* cloneInline(RenderFlow* src)
+{
+ RenderInline *o = new (src->renderArena()) RenderInline(src->element());
+ o->setStyle(src->style());
+ return o;
+}
+
+void RenderInline::splitInlines(RenderFlow* fromBlock, RenderFlow* toBlock,
+ RenderFlow* middleBlock,
+ RenderObject* beforeChild, RenderFlow* oldCont)
+{
+ // Create a clone of this inline.
+ RenderFlow* clone = cloneInline(this);
+ clone->setContinuation(oldCont);
+
+ // Now take all of the children from beforeChild to the end and remove
+ // then from |this| and place them in the clone.
+ RenderObject* o = beforeChild;
+ while (o) {
+ RenderObject* tmp = o;
+ o = tmp->nextSibling();
+ clone->appendChildNode(removeChildNode(tmp));
+ tmp->setLayouted(false);
+ tmp->setMinMaxKnown(false);
+ }
+
+ // Hook |clone| up as the continuation of the middle block.
+ middleBlock->setContinuation(clone);
+
+ // We have been reparented and are now under the fromBlock. We need
+ // to walk up our inline parent chain until we hit the containing block.
+ // Once we hit the containing block we're done.
+ RenderFlow* curr = static_cast<RenderFlow*>(parent());
+ RenderFlow* currChild = this;
+ while (curr && curr != fromBlock) {
+ // Create a new clone.
+ RenderFlow* cloneChild = clone;
+ clone = cloneInline(curr);
+
+ // Insert our child clone as the first child.
+ clone->appendChildNode(cloneChild);
+
+ // Hook the clone up as a continuation of |curr|.
+ RenderFlow* oldCont = curr->continuation();
+ curr->setContinuation(clone);
+ clone->setContinuation(oldCont);
+
+ // Now we need to take all of the children starting from the first child
+ // *after* currChild and append them all to the clone.
+ o = currChild->nextSibling();
+ while (o) {
+ RenderObject* tmp = o;
+ o = tmp->nextSibling();
+ clone->appendChildNode(curr->removeChildNode(tmp));
+ tmp->setLayouted(false);
+ tmp->setMinMaxKnown(false);
+ }
+
+ // Keep walking up the chain.
+ currChild = curr;
+ curr = static_cast<RenderFlow*>(curr->parent());
+ }
+
+ // Now we are at the block level. We need to put the clone into the toBlock.
+ toBlock->appendChildNode(clone);
+
+ // Now take all the children after currChild and remove them from the fromBlock
+ // and put them in the toBlock.
+ o = currChild->nextSibling();
+ while (o) {
+ RenderObject* tmp = o;
+ o = tmp->nextSibling();
+ toBlock->appendChildNode(fromBlock->removeChildNode(tmp));
+ }
+}
+
+void RenderInline::splitFlow(RenderObject* beforeChild, RenderFlow* newBlockBox,
+ RenderObject* newChild, RenderFlow* oldCont)
+{
+ RenderBlock* block = containingBlock();
+ RenderFlow* pre = 0;
+ RenderFlow* post = 0;
+
+ RenderStyle* newStyle = new RenderStyle();
+ newStyle->inheritFrom(block->style());
+ newStyle->setDisplay(BLOCK);
+ pre = new (renderArena()) RenderBlock(0 /* anonymous box */);
+ pre->setStyle(newStyle);
+ pre->setIsAnonymousBox(true);
+ pre->setChildrenInline(true);
+
+ newStyle = new RenderStyle();
+ newStyle->inheritFrom(block->style());
+ newStyle->setDisplay(BLOCK);
+ post = new (renderArena()) RenderBlock(0 /* anonymous box */);
+ post->setStyle(newStyle);
+ post->setIsAnonymousBox(true);
+ post->setChildrenInline(true);
+
+ RenderObject* boxFirst = block->firstChild();
+ block->insertChildNode(pre, boxFirst);
+ block->insertChildNode(newBlockBox, boxFirst);
+ block->insertChildNode(post, boxFirst);
+ block->setChildrenInline(false);
+
+ RenderObject* o = boxFirst;
+ while (o)
+ {
+ RenderObject* no = o;
+ o = no->nextSibling();
+ pre->appendChildNode(block->removeChildNode(no));
+ no->setLayouted(false);
+ no->setMinMaxKnown(false);
+ }
+
+ splitInlines(pre, post, newBlockBox, beforeChild, oldCont);
+
+ // We already know the newBlockBox isn't going to contain inline kids, so avoid wasting
+ // time in makeChildrenNonInline by just setting this explicitly up front.
+ newBlockBox->setChildrenInline(false);
+
+ // We don't just call addChild, since it would pass things off to the
+ // continuation, so we call addChildToFlow explicitly instead. We delayed
+ // adding the newChild until now so that the |newBlockBox| would be fully
+ // connected, thus allowing newChild access to a renderArena should it need
+ // to wrap itself in additional boxes (e.g., table construction).
+ newBlockBox->addChildToFlow(newChild, 0);
+
+ // XXXdwh is any of this even necessary? I don't think it is.
+ pre->close();
+ pre->setPos(0, -500000);
+ pre->setLayouted(false);
+ newBlockBox->close();
+ newBlockBox->setPos(0, -500000);
+ newBlockBox->setLayouted(false);
+ post->close();
+ post->setPos(0, -500000);
+ post->setLayouted(false);
+
+ block->setLayouted(false);
+ block->setMinMaxKnown(false);
+}
+
+void RenderInline::paint(QPainter *p, int _x, int _y, int _w, int _h,
+ int _tx, int _ty, PaintAction paintAction)
+{
+ paintObject(p, _x, _y, _w, _h, _tx, _ty, paintAction);
+}
+
+void RenderInline::paintObject(QPainter *p, int _x, int _y,
+ int _w, int _h, int _tx, int _ty, PaintAction paintAction)
+{
+
+#ifdef DEBUG_LAYOUT
+ // kdDebug( 6040 ) << renderName() << "(RenderInline) " << this << " ::paintObject() w/h = (" << width() << "/" << height() << ")" << endl;
+#endif
+
+ // FIXME: This function will eventually get much more complicated. :) - dwh
+ // paint contents
+ RenderObject *child = firstChild();
+ while(child != 0)
+ {
+ if(!child->layer() && !child->isFloating())
+ child->paint(p, _x, _y, _w, _h, _tx, _ty, paintAction);
+ child = child->nextSibling();
+ }
+}
+
+void RenderInline::calcMinMaxWidth()
+{
+ KHTMLAssert( !minMaxKnown() );
+
+#ifdef DEBUG_LAYOUT
+ kdDebug( 6040 ) << renderName() << "(RenderInline)::calcMinMaxWidth() this=" << this << endl;
+#endif
+
+ // Irrelevant, since some enclosing block will actually measure us and our children.
+ m_minWidth = 0;
+ m_maxWidth = 0;
+
+ setMinMaxKnown();
+}
+
+short RenderInline::offsetWidth() const
+{
+ short w = 0;
+ RenderObject* object = firstChild();
+ while (object) {
+ w += object->offsetWidth();
+ object = object->nextSibling();
+ }
+ return w;
+}
+
+int RenderInline::offsetHeight() const
+{
+ if (firstChild())
+ return firstChild()->offsetHeight();
+ return height();
+}
+
+int RenderInline::offsetLeft() const
+{
+ int x = RenderFlow::offsetLeft();
+ RenderObject* textChild = (RenderObject*)this;
+ while (textChild && textChild->isInline() && !textChild->isText())
+ textChild = textChild->firstChild();
+ if (textChild && textChild != this)
+ x += textChild->xPos() - textChild->borderLeft() - textChild->paddingLeft();
+ return x;
+}
+
+int RenderInline::offsetTop() const
+{
+ RenderObject* textChild = (RenderObject*)this;
+ while (textChild && textChild->isInline() && !textChild->isText())
+ textChild = textChild->firstChild();
+ int y = RenderFlow::offsetTop();
+ if (textChild && textChild != this)
+ y += textChild->yPos() - textChild->borderTop() - textChild->paddingTop();
+ return y;
+}
+
diff --git a/WebCore/khtml/rendering/render_inline.h b/WebCore/khtml/rendering/render_inline.h
new file mode 100644
index 0000000..0bb1f98
--- /dev/null
+++ b/WebCore/khtml/rendering/render_inline.h
@@ -0,0 +1,78 @@
+/*
+ * This file is part of the render object implementation for KHTML.
+ *
+ * Copyright (C) 2003 Apple Computer, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+#ifndef RENDER_INLINE_H
+#define RENDER_INLINE_H
+
+#include "render_flow.h"
+
+namespace khtml {
+
+class RenderInline : public RenderFlow
+{
+public:
+ RenderInline(DOM::NodeImpl* node);
+ virtual ~RenderInline();
+
+ virtual const char *renderName() const
+ {
+ if (isRelPositioned())
+ return "Inline (Rel Positioned)";
+ else if (isAnonymousBox())
+ return "Inline (Anonymous)";
+ return "Inline";
+ };
+
+ virtual bool isRenderInline() const { return true; }
+
+ virtual void addChildToFlow(RenderObject* newChild, RenderObject* beforeChild);
+ void splitInlines(RenderFlow* fromBlock, RenderFlow* toBlock, RenderFlow* middleBlock,
+ RenderObject* beforeChild, RenderFlow* oldCont);
+ void splitFlow(RenderObject* beforeChild, RenderFlow* newBlockBox,
+ RenderObject* newChild, RenderFlow* oldCont);
+
+ virtual void setStyle(RenderStyle* _style);
+
+ virtual void layout() {} // Do nothing for layout()
+
+ virtual void paint(QPainter *, int x, int y, int w, int h,
+ int tx, int ty, PaintAction paintAction);
+ virtual void paintObject(QPainter *, int x, int y, int w, int h,
+ int tx, int ty, PaintAction paintAction);
+
+ virtual void calcMinMaxWidth();
+
+ // overrides RenderObject
+ virtual bool requiresLayer() { return isRelPositioned(); }
+
+ // used to calculate offsetWidth/Height. Overridden by inlines (render_flow) to return
+ // the remaining width on a given line (and the height of a single line).
+ virtual short offsetWidth() const;
+ virtual int offsetHeight() const;
+ virtual int offsetLeft() const;
+ virtual int offsetTop() const;
+};
+
+}; // namespace
+
+#endif // RENDER_BLOCK_H
+
diff --git a/WebCore/khtml/rendering/render_list.cpp b/WebCore/khtml/rendering/render_list.cpp
index 001dbc7..62e781c 100644
--- a/WebCore/khtml/rendering/render_list.cpp
+++ b/WebCore/khtml/rendering/render_list.cpp
@@ -121,7 +121,7 @@ static QString toHebrew( int number ) {
// -------------------------------------------------------------------------
RenderListItem::RenderListItem(DOM::NodeImpl* node)
- : RenderFlow(node), _notInList(false)
+ : RenderBlock(node), _notInList(false)
{
// init RenderObject attributes
setInline(false); // our object is not Inline
@@ -132,7 +132,7 @@ RenderListItem::RenderListItem(DOM::NodeImpl* node)
void RenderListItem::setStyle(RenderStyle *_style)
{
- RenderFlow::setStyle(_style);
+ RenderBlock::setStyle(_style);
RenderStyle *newStyle = new RenderStyle();
newStyle->ref();
@@ -197,7 +197,7 @@ static RenderObject* getParentOfFirstLineBox(RenderObject* curr, RenderObject* m
if (currChild->isFloating() || currChild->isPositioned())
continue;
- if (currChild->isTable() || !currChild->isFlow())
+ if (currChild->isTable() || !currChild->isRenderBlock())
break;
if (currChild->element() &&
@@ -248,7 +248,7 @@ void RenderListItem::calcMinMaxWidth()
// Make sure our marker is in the correct location.
updateMarkerLocation();
if (!minMaxKnown())
- RenderFlow::calcMinMaxWidth();
+ RenderBlock::calcMinMaxWidth();
}
void RenderListItem::layout( )
@@ -257,7 +257,7 @@ void RenderListItem::layout( )
KHTMLAssert( minMaxKnown() );
updateMarkerLocation();
- RenderFlow::layout();
+ RenderBlock::layout();
}
void RenderListItem::paint(QPainter *p, int _x, int _y, int _w, int _h,
@@ -269,7 +269,7 @@ void RenderListItem::paint(QPainter *p, int _x, int _y, int _w, int _h,
#ifdef DEBUG_LAYOUT
kdDebug( 6040 ) << nodeName().string() << "(LI)::paint()" << endl;
#endif
- RenderFlow::paint(p, _x, _y, _w, _h, _tx, _ty, paintAction);
+ RenderBlock::paint(p, _x, _y, _w, _h, _tx, _ty, paintAction);
}
void RenderListItem::paintObject(QPainter *p, int _x, int _y,
@@ -277,7 +277,7 @@ void RenderListItem::paintObject(QPainter *p, int _x, int _y,
{
// ### this should scale with the font size in the body... possible?
//m_marker->printIcon(p, _tx, _ty);
- RenderFlow::paintObject(p, _x, _y, _w, _h, _tx, _ty, paintAction);
+ RenderBlock::paintObject(p, _x, _y, _w, _h, _tx, _ty, paintAction);
}
// -----------------------------------------------------------
diff --git a/WebCore/khtml/rendering/render_list.h b/WebCore/khtml/rendering/render_list.h
index 823ce1e..2a45352 100644
--- a/WebCore/khtml/rendering/render_list.h
+++ b/WebCore/khtml/rendering/render_list.h
@@ -24,7 +24,7 @@
#ifndef RENDER_LIST_H
#define RENDER_LIST_H
-#include "render_flow.h"
+#include "render_block.h"
// ### list-style-position, list-style-image is still missing
@@ -78,7 +78,7 @@ protected:
RenderListItem* m_listItem;
};
-class RenderListItem : public RenderFlow
+class RenderListItem : public RenderBlock
{
public:
RenderListItem(DOM::NodeImpl*);
diff --git a/WebCore/khtml/rendering/render_object.cpp b/WebCore/khtml/rendering/render_object.cpp
index 2236add..3f43e7f 100644
--- a/WebCore/khtml/rendering/render_object.cpp
+++ b/WebCore/khtml/rendering/render_object.cpp
@@ -34,6 +34,8 @@
#include <qpainter.h>
#include "khtmlview.h"
#include "render_arena.h"
+#include "render_inline.h"
+#include "render_block.h"
#include <assert.h>
using namespace DOM;
@@ -77,8 +79,10 @@ RenderObject *RenderObject::createObject(DOM::NodeImpl* node, RenderStyle* styl
// a display of inline, make an inline-table.
else if (node->id() == ID_TABLE && node->getDocument()->inQuirksMode())
o = new (arena) RenderTable(node);
+ else if (style->display() == INLINE)
+ o = new (arena) RenderInline(node);
else
- o = new (arena) RenderFlow(node);
+ o = new (arena) RenderBlock(node);
break;
case LIST_ITEM:
o = new (arena) RenderListItem(node);
@@ -108,7 +112,7 @@ RenderObject *RenderObject::createObject(DOM::NodeImpl* node, RenderStyle* styl
o = new (arena) RenderTableCell(node);
break;
case TABLE_CAPTION:
- o = new (arena) RenderFlow(node);
+ o = new (arena) RenderBlock(node);
break;
}
if(o) o->setStyle(style);
@@ -366,38 +370,28 @@ void RenderObject::setLayouted(bool b)
}
}
-RenderObject *RenderObject::containingBlock() const
+RenderBlock* RenderObject::containingBlock() const
{
- if(isTableCell()) {
+ if(isTableCell())
return static_cast<const RenderTableCell *>(this)->table();
- }
-
+ else if (isRoot())
+ return 0; // Ensures termination so you can walk up a containingBlock() chain.
+
RenderObject *o = parent();
- if(m_style->position() == FIXED) {
+ if (m_style->position() == FIXED) {
while ( o && !o->isRoot() )
o = o->parent();
}
- else if(m_style->position() == ABSOLUTE) {
+ else if (m_style->position() == ABSOLUTE) {
while (o && o->style()->position() == STATIC && !o->isHtml() && !o->isRoot())
o = o->parent();
} else {
- while(o && o->isInline())
+ while(o && (o->isInline() || o->isTableRow() || o->isTableSection() || o->isTableCol()))
o = o->parent();
}
- // this is just to make sure we return a valid element.
- // the case below should never happen...
- if(!o) {
- if(!isRoot()) {
-#ifndef NDEBUG
- kdDebug( 6040 ) << this << ": " << renderName() << "(RenderObject): No containingBlock!" << endl;
- const RenderObject* p = this;
- while (p->parent()) p = p->parent();
- p->printTree();
-#endif
- }
- return const_cast<RenderObject *>(this);
- } else
- return o;
+
+ KHTMLAssert(o && o->isRenderBlock());
+ return static_cast<RenderBlock*>(o);
}
short RenderObject::containingBlockWidth() const
@@ -894,7 +888,7 @@ void RenderObject::setOverhangingContents(bool p)
if (p)
{
m_overhangingContents = true;
- if (cb!=this)
+ if (cb)
cb->setOverhangingContents();
}
else
@@ -913,7 +907,7 @@ void RenderObject::setOverhangingContents(bool p)
else
{
m_overhangingContents = false;
- if (cb!=this)
+ if (cb)
cb->setOverhangingContents(false);
}
}
@@ -1025,8 +1019,8 @@ void RenderObject::removeFromSpecialObjects()
if (isPositioned() || isFloating()) {
RenderObject *p;
for (p = parent(); p; p = p->parent()) {
- if (p->isFlow())
- static_cast<RenderFlow*>(p)->removeSpecialObject(this);
+ if (p->isRenderBlock())
+ static_cast<RenderBlock*>(p)->removeSpecialObject(this);
}
}
}
diff --git a/WebCore/khtml/rendering/render_object.h b/WebCore/khtml/rendering/render_object.h
index b3a1aab..fe2c36c 100644
--- a/WebCore/khtml/rendering/render_object.h
+++ b/WebCore/khtml/rendering/render_object.h
@@ -78,6 +78,7 @@ namespace DOM {
namespace khtml {
class RenderFlow;
+ class RenderBlock;
class RenderStyle;
class RenderTable;
class CachedObject;
@@ -164,10 +165,10 @@ public:
RenderArena* renderArena() const;
// some helper functions...
+ virtual bool isRenderBlock() const { return false; }
+ virtual bool isRenderInline() const { return false; }
virtual bool childrenInline() const { return false; }
virtual void setChildrenInline(bool b) { };
- virtual bool isRendered() const { return false; }
- virtual bool isFlow() const { return false; }
virtual RenderFlow* continuation() const { return 0; }
virtual bool isListItem() const { return false; }
@@ -359,7 +360,7 @@ public:
virtual void setStyle(RenderStyle *style);
// returns the containing block level element for this element.
- RenderObject *containingBlock() const;
+ RenderBlock *containingBlock() const;
// return just the width of the containing block
virtual short containingBlockWidth() const;
diff --git a/WebCore/khtml/rendering/render_replaced.h b/WebCore/khtml/rendering/render_replaced.h
index 9bdabdf..0634bc2 100644
--- a/WebCore/khtml/rendering/render_replaced.h
+++ b/WebCore/khtml/rendering/render_replaced.h
@@ -36,8 +36,6 @@ public:
virtual const char *renderName() const { return "RenderReplaced"; }
- virtual bool isRendered() const { return true; }
-
virtual short lineHeight( bool firstLine) const;
virtual short baselinePosition( bool firstLine ) const;
diff --git a/WebCore/khtml/rendering/render_root.cpp b/WebCore/khtml/rendering/render_root.cpp
index 1d64d68..a9343e6 100644
--- a/WebCore/khtml/rendering/render_root.cpp
+++ b/WebCore/khtml/rendering/render_root.cpp
@@ -36,7 +36,7 @@ using namespace khtml;
//#define SPEED_DEBUG
RenderRoot::RenderRoot(DOM::NodeImpl* node, KHTMLView *view)
- : RenderFlow(node)
+ : RenderBlock(node)
{
// init RenderObject attributes
setInline(false);
@@ -111,7 +111,7 @@ void RenderRoot::calcMinMaxWidth()
{
KHTMLAssert( !minMaxKnown() );
- RenderFlow::calcMinMaxWidth();
+ RenderBlock::calcMinMaxWidth();
m_maxWidth = m_minWidth;
@@ -152,7 +152,7 @@ void RenderRoot::layout()
m_height = m_rootHeight;
}
- RenderFlow::layout();
+ RenderBlock::layout();
if (!m_printingMode) {
m_view->resizeContents(docWidth(), docHeight());
@@ -196,7 +196,7 @@ void RenderRoot::paintObject(QPainter *p, int _x, int _y,
int _w, int _h, int _tx, int _ty, PaintAction paintAction)
{
#ifdef DEBUG_LAYOUT
- kdDebug( 6040 ) << renderName() << "(RenderFlow) " << this << " ::paintObject() w/h = (" << width() << "/" << height() << ")" << endl;
+ kdDebug( 6040 ) << renderName() << "(RenderRoot) " << this << " ::paintObject() w/h = (" << width() << "/" << height() << ")" << endl;
#endif
// 1. paint background, borders etc
if (paintAction == PaintActionBackground)
diff --git a/WebCore/khtml/rendering/render_root.h b/WebCore/khtml/rendering/render_root.h
index b57ab69..0d0ff01 100644
--- a/WebCore/khtml/rendering/render_root.h
+++ b/WebCore/khtml/rendering/render_root.h
@@ -22,14 +22,14 @@
#ifndef render_root_h
#define render_root_h
-#include "render_flow.h"
+#include "render_block.h"
class KHTMLView;
class QScrollView;
namespace khtml {
-class RenderRoot : public RenderFlow
+class RenderRoot : public RenderBlock
{
public:
RenderRoot(DOM::NodeImpl* node, KHTMLView *view);
@@ -37,7 +37,6 @@ public:
virtual const char *renderName() const { return "RenderRoot"; }
- virtual bool isRendered() const { return true; }
virtual bool isRoot() const { return true; }
virtual void layout();
diff --git a/WebCore/khtml/rendering/render_table.cpp b/WebCore/khtml/rendering/render_table.cpp
index b2f161e..a467741 100644
--- a/WebCore/khtml/rendering/render_table.cpp
+++ b/WebCore/khtml/rendering/render_table.cpp
@@ -43,7 +43,7 @@
using namespace khtml;
RenderTable::RenderTable(DOM::NodeImpl* node)
- : RenderFlow(node)
+ : RenderBlock(node)
{
tCaption = 0;
@@ -76,7 +76,7 @@ void RenderTable::setStyle(RenderStyle *_style)
ETableLayout oldTableLayout = style() ? style()->tableLayout() : TAUTO;
if ( _style->display() == INLINE ) _style->setDisplay(INLINE_TABLE);
if ( _style->display() != INLINE_TABLE ) _style->setDisplay(TABLE);
- RenderFlow::setStyle(_style);
+ RenderBlock::setStyle(_style);
// init RenderObject attributes
setInline(style()->display()==INLINE_TABLE && !isPositioned());
@@ -111,7 +111,7 @@ short RenderTable::lineHeight(bool b) const
// the base class.
if (isReplaced())
return height()+marginTop()+marginBottom();
- return RenderFlow::lineHeight(b);
+ return RenderBlock::lineHeight(b);
}
short RenderTable::baselinePosition(bool b) const
@@ -120,7 +120,7 @@ short RenderTable::baselinePosition(bool b) const
// the base class.
if (isReplaced())
return height()+marginTop()+marginBottom();
- return RenderFlow::baselinePosition(b);
+ return RenderBlock::baselinePosition(b);
}
void RenderTable::addChild(RenderObject *child, RenderObject *beforeChild)
@@ -139,7 +139,7 @@ void RenderTable::addChild(RenderObject *child, RenderObject *beforeChild)
switch(child->style()->display())
{
case TABLE_CAPTION:
- tCaption = static_cast<RenderFlow *>(child);
+ tCaption = static_cast<RenderBlock *>(child);
break;
case TABLE_COLUMN:
case TABLE_COLUMN_GROUP:
@@ -203,7 +203,7 @@ void RenderTable::calcWidth()
calcAbsoluteHorizontal();
}
- RenderObject *cb = containingBlock();
+ RenderBlock *cb = containingBlock();
int availableWidth = cb->contentWidth();
LengthType widthType = style()->width().type;
@@ -217,8 +217,8 @@ void RenderTable::calcWidth()
}
// restrict width to what we really have in case we flow around floats
- if ( style()->flowAroundFloats() && cb->isFlow() ) {
- availableWidth = static_cast<RenderFlow *>(cb)->lineWidth( m_y );
+ if (style()->flowAroundFloats()) {
+ availableWidth = cb->lineWidth( m_y );
m_width = QMIN( availableWidth, m_width );
}
@@ -569,7 +569,7 @@ void RenderTable::recalcSections()
switch(child->style()->display()) {
case TABLE_CAPTION:
if ( !tCaption) {
- tCaption = static_cast<RenderFlow*>(child);
+ tCaption = static_cast<RenderBlock*>(child);
tCaption->setLayouted(false);
}
break;
@@ -635,7 +635,7 @@ void RenderTable::dump(QTextStream *stream, QString ind) const
*stream << " " << columns[i].span;
*stream << endl << ind;
- RenderFlow::dump(stream,ind);
+ RenderBlock::dump(stream,ind);
}
#endif
@@ -1357,7 +1357,7 @@ void RenderTableRow::layout()
// -------------------------------------------------------------------------
RenderTableCell::RenderTableCell(DOM::NodeImpl* _node)
- : RenderFlow(_node)
+ : RenderBlock(_node)
{
_col = -1;
_row = -1;
@@ -1373,7 +1373,7 @@ void RenderTableCell::detach(RenderArena* arena)
if (parent() && section())
section()->setNeedCellRecalc();
- RenderFlow::detach(arena);
+ RenderBlock::detach(arena);
}
void RenderTableCell::updateFromElement()
@@ -1405,7 +1405,7 @@ void RenderTableCell::calcMinMaxWidth()
kdDebug( 6040 ) << renderName() << "(TableCell)::calcMinMaxWidth() known=" << minMaxKnown() << endl;
#endif
- RenderFlow::calcMinMaxWidth();
+ RenderBlock::calcMinMaxWidth();
setMinMaxKnown();
}
@@ -1424,7 +1424,7 @@ void RenderTableCell::setWidth( int width )
void RenderTableCell::close()
{
- RenderFlow::close();
+ RenderBlock::close();
#ifdef DEBUG_LAYOUT
kdDebug( 6040 ) << renderName() << "(RenderTableCell)::close() total height =" << m_height << endl;
@@ -1435,12 +1435,12 @@ void RenderTableCell::close()
void RenderTableCell::repaintRectangle(int x, int y, int w, int h, bool immediate, bool f)
{
y += _topExtra;
- RenderFlow::repaintRectangle(x, y, w, h, immediate, f);
+ RenderBlock::repaintRectangle(x, y, w, h, immediate, f);
}
bool RenderTableCell::absolutePosition(int &xPos, int &yPos, bool f)
{
- bool ret = RenderFlow::absolutePosition(xPos, yPos, f);
+ bool ret = RenderBlock::absolutePosition(xPos, yPos, f);
if (ret)
yPos += _topExtra;
return ret;
@@ -1464,7 +1464,7 @@ short RenderTableCell::baselinePosition( bool ) const
void RenderTableCell::setStyle( RenderStyle *style )
{
style->setDisplay(TABLE_CELL);
- RenderFlow::setStyle( style );
+ RenderBlock::setStyle( style );
setShouldPaintBackgroundOrBorder(true);
if (style->whiteSpace() == KONQ_NOWRAP) {
@@ -1581,7 +1581,7 @@ void RenderTableCell::dump(QTextStream *stream, QString ind) const
*stream << " cSpan=" << cSpan;
// *stream << " nWrap=" << nWrap;
- RenderFlow::dump(stream,ind);
+ RenderBlock::dump(stream,ind);
}
#endif
diff --git a/WebCore/khtml/rendering/render_table.h b/WebCore/khtml/rendering/render_table.h
index bc707d8..70e9321 100644
--- a/WebCore/khtml/rendering/render_table.h
+++ b/WebCore/khtml/rendering/render_table.h
@@ -31,7 +31,7 @@
#include <qptrvector.h>
#include "render_box.h"
-#include "render_flow.h"
+#include "render_block.h"
#include "render_style.h"
#include "misc/khtmllayout.h"
@@ -48,7 +48,7 @@ class RenderTableCell;
class RenderTableCol;
class TableLayout;
-class RenderTable : public RenderFlow
+class RenderTable : public RenderBlock
{
public:
enum Rules {
@@ -78,7 +78,6 @@ public:
virtual void setStyle(RenderStyle *style);
- virtual bool isRendered() const { return true; }
virtual bool isTable() const { return true; }
int getColumnPos(int col) const
@@ -170,7 +169,7 @@ protected:
friend class AutoTableLayout;
friend class FixedTableLayout;
- RenderFlow *tCaption;
+ RenderBlock *tCaption;
RenderTableSection *head;
RenderTableSection *foot;
RenderTableSection *firstBody;
@@ -293,7 +292,7 @@ public:
// -------------------------------------------------------------------------
-class RenderTableCell : public RenderFlow
+class RenderTableCell : public RenderBlock
{
public:
RenderTableCell(DOM::NodeImpl* node);
diff --git a/WebCore/khtml/rendering/render_text.h b/WebCore/khtml/rendering/render_text.h
index 5c197fb..2fbf5f7 100644
--- a/WebCore/khtml/rendering/render_text.h
+++ b/WebCore/khtml/rendering/render_text.h
@@ -137,8 +137,6 @@ public:
virtual void setStyle(RenderStyle *style);
- virtual bool isRendered() const { return true; }
-
virtual void paint(QPainter *, int x, int y, int w, int h,
int tx, int ty, PaintAction paintAction);
virtual void paintObject(QPainter *, int x, int y, int w, int h,
diff --git a/WebCore/khtml/xml/dom_textimpl.cpp b/WebCore/khtml/xml/dom_textimpl.cpp
index c4985fb..9fdd580 100644
--- a/WebCore/khtml/xml/dom_textimpl.cpp
+++ b/WebCore/khtml/xml/dom_textimpl.cpp
@@ -380,12 +380,12 @@ bool TextImpl::rendererIsNeeded(RenderStyle *style)
if (par->isInline()) {
// <span><div/> <div/></span>
RenderObject *prev = previousRenderer();
- if (prev && prev->isFlow() && !prev->isInline()) {
+ if (prev && prev->isRenderBlock()) {
return false;
}
} else {
RenderObject *prev = previousRenderer();
- if (par->isFlow() && !par->childrenInline() && (!prev || !prev->isInline())) {
+ if (par->isRenderBlock() && !par->childrenInline() && (!prev || !prev->isInline())) {
return false;
}
--
WebKit Debian packaging
More information about the Pkg-webkit-commits
mailing list