Commit 019f2358 authored by hyatt's avatar hyatt

Fix for 3128728. Ensure that list markers get placed into an

	existing line box if possible.  This patch also fixes RTL bullets
	and line height calculations involving image bullets that are the
	biggest thing on the line.  List markers also correctly move
	to avoid floats.

        Reviewed by mjs

        * khtml/rendering/render_list.cpp:
        (RenderListItem::setStyle):
        (getLineBoxParent):
        (RenderListItem::layout):
        (RenderListMarker::calcMinMaxWidth):


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@3082 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 23ba4fe3
2002-12-15 David Hyatt <hyatt@apple.com>
Fix for 3128728. Ensure that list markers get placed into an
existing line box if possible. This patch also fixes RTL bullets
and line height calculations involving image bullets that are the
biggest thing on the line. List markers also correctly move
to avoid floats.
Reviewed by mjs
* khtml/rendering/render_list.cpp:
(RenderListItem::setStyle):
(getLineBoxParent):
(RenderListItem::layout):
(RenderListMarker::calcMinMaxWidth):
2002-12-16 Darin Adler <darin@apple.com>
Reviewed by Maciej.
......@@ -18,6 +34,7 @@
* WebCore.pbproj/project.pbxproj: Updated source version to 37u2.
>>>>>>> 1.1131
2002-12-15 Darin Adler <darin@apple.com>
Reviewed by Trey.
......
2002-12-15 David Hyatt <hyatt@apple.com>
Fix for 3128728. Ensure that list markers get placed into an
existing line box if possible. This patch also fixes RTL bullets
and line height calculations involving image bullets that are the
biggest thing on the line. List markers also correctly move
to avoid floats.
Reviewed by mjs
* khtml/rendering/render_list.cpp:
(RenderListItem::setStyle):
(getLineBoxParent):
(RenderListItem::layout):
(RenderListMarker::calcMinMaxWidth):
2002-12-16 Darin Adler <darin@apple.com>
Reviewed by Maciej.
......@@ -18,6 +34,7 @@
* WebCore.pbproj/project.pbxproj: Updated source version to 37u2.
>>>>>>> 1.1131
2002-12-15 Darin Adler <darin@apple.com>
Reviewed by Trey.
......
......@@ -25,6 +25,7 @@
#include "rendering/render_root.h"
#include "xml/dom_docimpl.h"
#include "misc/htmltags.h"
#include <qpainter.h>
......@@ -34,6 +35,7 @@
//#define BOX_DEBUG
using DOM::DocumentImpl;
using namespace khtml;
static QString toRoman( int number, bool upper )
......@@ -139,11 +141,10 @@ void RenderListItem::setStyle(RenderStyle *_style)
newStyle->inheritFrom(style());
if(!m_marker && style()->listStyleType() != LNONE) {
if (!m_marker && style()->listStyleType() != LNONE) {
m_marker = new (renderArena()) RenderListMarker();
m_marker->setStyle(newStyle);
insertChildNode( m_marker, firstChild() );
m_marker->setListItem(this);
} else if ( m_marker && style()->listStyleType() == LNONE) {
m_marker->detach(renderArena());
m_marker = 0;
......@@ -183,6 +184,38 @@ void RenderListItem::calcListValue()
}
}
static RenderObject* getParentOfFirstLineBox(RenderObject* curr, RenderObject* marker)
{
RenderObject* firstChild = curr->firstChild();
if (!firstChild)
return 0;
for (RenderObject* currChild = firstChild;
currChild; currChild = currChild->nextSibling()) {
if (currChild == marker)
continue;
if (currChild->isInline())
return curr;
if (currChild->isFloating() || currChild->isPositioned())
continue;
if (currChild->isTable() || !currChild->isFlow())
break;
if (currChild->element() &&
(currChild->element()->getDocument()->parseMode() != DocumentImpl::Strict) &&
(currChild->element()->id() == ID_UL || currChild->element()->id() == ID_OL))
break;
RenderObject* lineBox = getParentOfFirstLineBox(currChild, marker);
if (lineBox)
return lineBox;
}
return 0;
}
void RenderListItem::layout( )
{
......@@ -194,8 +227,23 @@ void RenderListItem::layout( )
//kdDebug(0) << "empty item" << endl;
return;
}
if (m_marker && !m_marker->layouted())
m_marker->layout();
// Sanity check the location of our marker.
if (m_marker) {
RenderObject* markerPar = m_marker->parent();
RenderObject* lineBoxParent = getParentOfFirstLineBox(this, m_marker);
if (!lineBoxParent)
lineBoxParent = this;
if (markerPar != lineBoxParent)
{
if (markerPar)
markerPar->removeChild(m_marker);
if (!lineBoxParent)
lineBoxParent = this;
lineBoxParent->addChild(m_marker, lineBoxParent->firstChild());
}
}
RenderFlow::layout();
}
......@@ -290,6 +338,20 @@ void RenderListMarker::setStyle(RenderStyle *s)
void RenderListMarker::paint(QPainter *p, int _x, int _y, int _w, int _h,
int _tx, int _ty, int paintPhase)
{
if (paintPhase != FOREGROUND_PHASE)
return;
if (style()->visibility() != VISIBLE) return;
_tx += m_x;
_ty += m_y;
if((_ty > _y + _h) || (_ty + m_height < _y))
return;
if(shouldPaintBackgroundOrBorder())
paintBoxDecorations(p, _x, _y, _w, _h, _tx, _ty);
paintObject(p, _x, _y, _w, _h, _tx, _ty, paintPhase);
}
......@@ -305,6 +367,32 @@ void RenderListMarker::paintObject(QPainter *p, int, int _y,
const QFontMetrics fm = p->fontMetrics();
int offset = fm.ascent()*2/3;
// The marker needs to adjust its tx, for the case where it's an outside marker.
RenderObject* listItem = 0;
int leftLineOffset = 0;
int rightLineOffset = 0;
if (style()->listStylePosition() == OUTSIDE) {
listItem = this;
int yOffset = 0;
int xOffset = 0;
while (listItem && listItem != m_listItem) {
yOffset += listItem->yPos();
xOffset += listItem->xPos();
listItem = listItem->parent();
}
// Now that we have our xoffset within the listbox, we need to adjust ourselves by the delta
// between our current xoffset and our desired position.
if (style()->direction() == LTR) {
leftLineOffset = m_listItem->leftRelOffset(yOffset, m_listItem->leftOffset(yOffset));
_tx -= (xOffset - leftLineOffset);
}
else {
rightLineOffset = m_listItem->rightRelOffset(yOffset, m_listItem->rightOffset(yOffset));
_tx += (rightLineOffset-xOffset);
}
}
bool isPrinting = (p->device()->devType() == QInternal::Printer);
if (isPrinting)
{
......@@ -327,12 +415,13 @@ void RenderListMarker::paintObject(QPainter *p, int, int _y,
int xoff = 0;
int yoff = fm.ascent() - offset;
if(style()->listStylePosition() == OUTSIDE) {
xoff = -7 - offset;
if(style()->direction() == RTL)
xoff = -xoff + parent()->width();
}
if(style()->listStylePosition() == OUTSIDE)
if (listItem->style()->direction() == LTR)
xoff = -7 - offset;
else
xoff = offset;
if ( m_listImage && !m_listImage->isErrorImage()) {
// For OUTSIDE bullets shrink back to only a 0.3em margin. 0.67 em is too
// much. This brings the margin back to MacIE/Gecko/WinIE levels.
......@@ -383,17 +472,17 @@ void RenderListMarker::paintObject(QPainter *p, int, int _y,
#else
//_ty += fm.ascent() - fm.height()/2 + 1;
#endif
if(style()->listStylePosition() == INSIDE) {
if(style()->direction() == LTR)
p->drawText(_tx, _ty, 0, 0, Qt::AlignLeft|Qt::DontClip, m_item);
if (style()->listStylePosition() == INSIDE) {
if( style()->direction() == LTR)
p->drawText(_tx, _ty, 0, 0, Qt::AlignLeft|Qt::DontClip, m_item);
else
p->drawText(_tx, _ty, 0, 0, Qt::AlignRight|Qt::DontClip, m_item);
} else {
if(style()->direction() == LTR)
p->drawText(_tx-offset/2, _ty, 0, 0, Qt::AlignRight|Qt::DontClip, m_item);
else
p->drawText(_tx+offset/2 + parent()->width(), _ty, 0, 0, Qt::AlignLeft|Qt::DontClip, m_item);
}
p->drawText(_tx+offset/2, _ty, 0, 0, Qt::AlignLeft|Qt::DontClip, m_item);
}
}
}
}
......@@ -438,12 +527,8 @@ void RenderListMarker::calcMinMaxWidth()
return;
}
if (m_value < 0) { // not yet calculated
RenderObject* p = parent();
while (p->isAnonymousBox())
p = p->parent();
static_cast<RenderListItem*>(p)->calcListValue();
}
if (m_value < 0) // not yet calculated
m_listItem->calcListValue();
const QFontMetrics &fm = style()->fontMetrics();
m_height = fm.ascent();
......@@ -505,7 +590,7 @@ void RenderListMarker::calcMinMaxWidth()
m_item += QString::fromLatin1(". ");
if(style()->listStylePosition() == INSIDE)
m_width = fm.width(m_item);
m_width = fm.width(m_item);
end:
......@@ -515,14 +600,17 @@ end:
setMinMaxKnown();
}
short RenderListMarker::verticalPositionHint( bool ) const
void RenderListMarker::calcWidth()
{
return 0;
RenderBox::calcWidth();
}
void RenderListMarker::calcWidth()
short RenderListMarker::baselinePosition(bool b) const
{
RenderBox::calcWidth();
if (m_listImage)
return height()+marginTop()+marginBottom();
// FIXME: This should one day really align.
return RenderBox::baselinePosition(b);
}
#undef BOX_DEBUG
......@@ -54,20 +54,24 @@ public:
virtual void layout( );
virtual void calcMinMaxWidth();
virtual short verticalPositionHint( bool firstLine ) const;
virtual void setPixmap( const QPixmap &, const QRect&, CachedImage *);
virtual void calcWidth();
virtual short baselinePosition(bool b) const;
virtual bool isListMarker() const { return true; }
RenderListItem* listItem() { return m_listItem; }
void setListItem(RenderListItem* listItem) { m_listItem = listItem; }
protected:
friend class RenderListItem;
QString m_item;
CachedImage *m_listImage;
long m_value;
RenderListItem* m_listItem;
};
class RenderListItem : public RenderFlow
......@@ -81,8 +85,7 @@ public:
virtual void setStyle(RenderStyle *style);
virtual bool isListItem() const { return true; }
virtual bool containsSpecial() { return (specialObjects != 0 && specialObjects->count() > 1 ); }
long value() const { return m_marker->m_value; }
void setValue( long v ) { predefVal = v; }
void calcListValue();
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment