[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:24:23 UTC 2009


The following commit has been merged in the debian/unstable branch:
commit ffe7871e5bf1594f987f1e7111f6f5f635138762
Author: hyatt <hyatt at 268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Tue Feb 11 01:59:29 2003 +0000

    	Inline box model landing, stage 1.  Doesn't really change
    	much of anything visually yet.  Just builds a bunch of boxes
    	and positions them, but those boxes aren't used yet.
    
    	Also fixing repaint() to understand not to dirty outside
    	overflow:hidden clipped ancestors.
    
    	Fixed two table bugs in table painting as well.
    
            Reviewed by kocienda
    
            * WebCore.pbproj/project.pbxproj:
            * khtml/rendering/bidi.cpp:
            * khtml/rendering/bidi.h:
            * khtml/rendering/render_block.cpp:
            * khtml/rendering/render_block.h:
            * khtml/rendering/render_box.cpp:
            (RenderBox::position):
            (RenderBox::repaintRectangle):
            * khtml/rendering/render_box.h:
            * khtml/rendering/render_flow.cpp:
            (RenderFlow::addChild):
            (RenderFlow::deleteLineBoxes):
            (RenderFlow::detach):
            (RenderFlow::createInlineBox):
            * khtml/rendering/render_flow.h:
            * khtml/rendering/render_image.cpp:
            (RenderImage::paintObject):
            * khtml/rendering/render_inline.cpp:
            * khtml/rendering/render_inline.h:
            * khtml/rendering/render_line.cpp: Added.
            (InlineBox::detach):
            (throw):
            (InlineBox::operator delete):
            (InlineFlowBox::marginLeft):
            (InlineFlowBox::marginRight):
            (InlineFlowBox::marginBorderPaddingLeft):
            (InlineFlowBox::marginBorderPaddingRight):
            (InlineFlowBox::getFlowSpacingWidth):
            (InlineFlowBox::nextOnLineExists):
            (InlineFlowBox::prevOnLineExists):
            (InlineFlowBox::onEndChain):
            (InlineFlowBox::determineSpacingForFlowBoxes):
            (InlineFlowBox::placeBoxesHorizontally):
            (InlineFlowBox::verticallyAlignBoxes):
            (InlineFlowBox::adjustMaxAscentAndDescent):
            (InlineFlowBox::computeLogicalBoxHeights):
            (InlineFlowBox::placeBoxesVertically):
            * khtml/rendering/render_line.h: Added.
            * khtml/rendering/render_object.cpp:
            (RenderObject::createInlineBox):
            * khtml/rendering/render_object.h:
            * khtml/rendering/render_replaced.cpp:
            * khtml/rendering/render_replaced.h:
            * khtml/rendering/render_table.cpp:
            (RenderTableSection::paint):
            (RenderTableCell::repaintRectangle):
            (RenderTableCell::paint):
            * khtml/rendering/render_table.h:
            * khtml/rendering/render_text.cpp:
            (RenderText::nodeAtPoint):
            (RenderText::paintObject):
            (RenderText::height):
            (RenderText::createInlineBox):
            (RenderText::position):
            (RenderText::width):
            (RenderText::metrics):
            * khtml/rendering/render_text.h:
            * khtml/xml/dom_docimpl.h:
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@3627 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/WebCore/ChangeLog-2003-10-25 b/WebCore/ChangeLog-2003-10-25
index 4e46c25..af4ce04 100644
--- a/WebCore/ChangeLog-2003-10-25
+++ b/WebCore/ChangeLog-2003-10-25
@@ -1,3 +1,75 @@
+2003-02-10  David Hyatt  <hyatt at apple.com>
+
+	Inline box model landing, stage 1.  Doesn't really change
+	much of anything visually yet.  Just builds a bunch of boxes
+	and positions them, but those boxes aren't used yet.
+
+	Also fixing repaint() to understand not to dirty outside
+	overflow:hidden clipped ancestors.
+
+	Fixed two table bugs in table painting as well.
+	
+        Reviewed by kocienda
+
+        * WebCore.pbproj/project.pbxproj:
+        * khtml/rendering/bidi.cpp:
+        * khtml/rendering/bidi.h:
+        * khtml/rendering/render_block.cpp:
+        * khtml/rendering/render_block.h:
+        * khtml/rendering/render_box.cpp:
+        (RenderBox::position):
+        (RenderBox::repaintRectangle):
+        * khtml/rendering/render_box.h:
+        * khtml/rendering/render_flow.cpp:
+        (RenderFlow::addChild):
+        (RenderFlow::deleteLineBoxes):
+        (RenderFlow::detach):
+        (RenderFlow::createInlineBox):
+        * khtml/rendering/render_flow.h:
+        * khtml/rendering/render_image.cpp:
+        (RenderImage::paintObject):
+        * khtml/rendering/render_inline.cpp:
+        * khtml/rendering/render_inline.h:
+        * khtml/rendering/render_line.cpp: Added.
+        (InlineBox::detach):
+        (throw):
+        (InlineBox::operator delete):
+        (InlineFlowBox::marginLeft):
+        (InlineFlowBox::marginRight):
+        (InlineFlowBox::marginBorderPaddingLeft):
+        (InlineFlowBox::marginBorderPaddingRight):
+        (InlineFlowBox::getFlowSpacingWidth):
+        (InlineFlowBox::nextOnLineExists):
+        (InlineFlowBox::prevOnLineExists):
+        (InlineFlowBox::onEndChain):
+        (InlineFlowBox::determineSpacingForFlowBoxes):
+        (InlineFlowBox::placeBoxesHorizontally):
+        (InlineFlowBox::verticallyAlignBoxes):
+        (InlineFlowBox::adjustMaxAscentAndDescent):
+        (InlineFlowBox::computeLogicalBoxHeights):
+        (InlineFlowBox::placeBoxesVertically):
+        * khtml/rendering/render_line.h: Added.
+        * khtml/rendering/render_object.cpp:
+        (RenderObject::createInlineBox):
+        * khtml/rendering/render_object.h:
+        * khtml/rendering/render_replaced.cpp:
+        * khtml/rendering/render_replaced.h:
+        * khtml/rendering/render_table.cpp:
+        (RenderTableSection::paint):
+        (RenderTableCell::repaintRectangle):
+        (RenderTableCell::paint):
+        * khtml/rendering/render_table.h:
+        * khtml/rendering/render_text.cpp:
+        (RenderText::nodeAtPoint):
+        (RenderText::paintObject):
+        (RenderText::height):
+        (RenderText::createInlineBox):
+        (RenderText::position):
+        (RenderText::width):
+        (RenderText::metrics):
+        * khtml/rendering/render_text.h:
+        * khtml/xml/dom_docimpl.h:
+
 2003-02-10  Darin Adler  <darin at apple.com>
 
         Reviewed by Richard.
diff --git a/WebCore/ChangeLog-2005-08-23 b/WebCore/ChangeLog-2005-08-23
index 4e46c25..af4ce04 100644
--- a/WebCore/ChangeLog-2005-08-23
+++ b/WebCore/ChangeLog-2005-08-23
@@ -1,3 +1,75 @@
+2003-02-10  David Hyatt  <hyatt at apple.com>
+
+	Inline box model landing, stage 1.  Doesn't really change
+	much of anything visually yet.  Just builds a bunch of boxes
+	and positions them, but those boxes aren't used yet.
+
+	Also fixing repaint() to understand not to dirty outside
+	overflow:hidden clipped ancestors.
+
+	Fixed two table bugs in table painting as well.
+	
+        Reviewed by kocienda
+
+        * WebCore.pbproj/project.pbxproj:
+        * khtml/rendering/bidi.cpp:
+        * khtml/rendering/bidi.h:
+        * khtml/rendering/render_block.cpp:
+        * khtml/rendering/render_block.h:
+        * khtml/rendering/render_box.cpp:
+        (RenderBox::position):
+        (RenderBox::repaintRectangle):
+        * khtml/rendering/render_box.h:
+        * khtml/rendering/render_flow.cpp:
+        (RenderFlow::addChild):
+        (RenderFlow::deleteLineBoxes):
+        (RenderFlow::detach):
+        (RenderFlow::createInlineBox):
+        * khtml/rendering/render_flow.h:
+        * khtml/rendering/render_image.cpp:
+        (RenderImage::paintObject):
+        * khtml/rendering/render_inline.cpp:
+        * khtml/rendering/render_inline.h:
+        * khtml/rendering/render_line.cpp: Added.
+        (InlineBox::detach):
+        (throw):
+        (InlineBox::operator delete):
+        (InlineFlowBox::marginLeft):
+        (InlineFlowBox::marginRight):
+        (InlineFlowBox::marginBorderPaddingLeft):
+        (InlineFlowBox::marginBorderPaddingRight):
+        (InlineFlowBox::getFlowSpacingWidth):
+        (InlineFlowBox::nextOnLineExists):
+        (InlineFlowBox::prevOnLineExists):
+        (InlineFlowBox::onEndChain):
+        (InlineFlowBox::determineSpacingForFlowBoxes):
+        (InlineFlowBox::placeBoxesHorizontally):
+        (InlineFlowBox::verticallyAlignBoxes):
+        (InlineFlowBox::adjustMaxAscentAndDescent):
+        (InlineFlowBox::computeLogicalBoxHeights):
+        (InlineFlowBox::placeBoxesVertically):
+        * khtml/rendering/render_line.h: Added.
+        * khtml/rendering/render_object.cpp:
+        (RenderObject::createInlineBox):
+        * khtml/rendering/render_object.h:
+        * khtml/rendering/render_replaced.cpp:
+        * khtml/rendering/render_replaced.h:
+        * khtml/rendering/render_table.cpp:
+        (RenderTableSection::paint):
+        (RenderTableCell::repaintRectangle):
+        (RenderTableCell::paint):
+        * khtml/rendering/render_table.h:
+        * khtml/rendering/render_text.cpp:
+        (RenderText::nodeAtPoint):
+        (RenderText::paintObject):
+        (RenderText::height):
+        (RenderText::createInlineBox):
+        (RenderText::position):
+        (RenderText::width):
+        (RenderText::metrics):
+        * khtml/rendering/render_text.h:
+        * khtml/xml/dom_docimpl.h:
+
 2003-02-10  Darin Adler  <darin at apple.com>
 
         Reviewed by Richard.
diff --git a/WebCore/WebCore.pbproj/project.pbxproj b/WebCore/WebCore.pbproj/project.pbxproj
index c63af36..f85bdd6 100644
--- a/WebCore/WebCore.pbproj/project.pbxproj
+++ b/WebCore/WebCore.pbproj/project.pbxproj
@@ -486,6 +486,7 @@
 				6504A7BF03DCE19800000124,
 				BC7C965303E9EE7000A80004,
 				BC7C965503E9EE7000A80004,
+				BCC60E5903F5055A00A80004,
 			);
 			isa = PBXHeadersBuildPhase;
 			runOnlyForDeploymentPostprocessing = 0;
@@ -729,6 +730,7 @@
 				93955A4403D72932008635CE,
 				BC7C965203E9EE7000A80004,
 				BC7C965403E9EE7000A80004,
+				BCC60E5803F5055A00A80004,
 			);
 			isa = PBXSourcesBuildPhase;
 			runOnlyForDeploymentPostprocessing = 0;
@@ -1526,6 +1528,30 @@
 			settings = {
 			};
 		};
+		BCC60E5603F5055A00A80004 = {
+			fileEncoding = 30;
+			isa = PBXFileReference;
+			path = render_line.cpp;
+			refType = 4;
+		};
+		BCC60E5703F5055A00A80004 = {
+			fileEncoding = 30;
+			isa = PBXFileReference;
+			path = render_line.h;
+			refType = 4;
+		};
+		BCC60E5803F5055A00A80004 = {
+			fileRef = BCC60E5603F5055A00A80004;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		BCC60E5903F5055A00A80004 = {
+			fileRef = BCC60E5703F5055A00A80004;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
 		BCF0192403D3802200B2D04D = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
@@ -4210,6 +4236,8 @@
 				BC7C965103E9EE7000A80004,
 				F690CFEA031C47F401CA2AC4,
 				F690CFEB031C47F401CA2AC4,
+				BCC60E5603F5055A00A80004,
+				BCC60E5703F5055A00A80004,
 				F523D2B902DE4438018635CA,
 				F523D2BA02DE4438018635CA,
 				F523D2BC02DE4438018635CA,
diff --git a/WebCore/khtml/rendering/bidi.cpp b/WebCore/khtml/rendering/bidi.cpp
index 5abb141..9b46605 100644
--- a/WebCore/khtml/rendering/bidi.cpp
+++ b/WebCore/khtml/rendering/bidi.cpp
@@ -27,8 +27,6 @@
 #include "render_arena.h"
 #include "xml/dom_docimpl.h"
 
-using namespace khtml;
-
 #include "kdebug.h"
 #include "qdatetime.h"
 #include "qfontmetrics.h"
@@ -36,7 +34,8 @@ using namespace khtml;
 #define BIDI_DEBUG 0
 //#define DEBUG_LINEBREAKS
 
-
+namespace khtml {
+    
 static BidiIterator sor;
 static BidiIterator eor;
 static BidiIterator last;
@@ -55,6 +54,43 @@ static int numSpaces;
 static void embed( QChar::Direction d );
 static void appendRun();
 
+static int getBPMWidth(int childValue, Length cssUnit)
+{
+    if (cssUnit.type != Variable)
+        return (cssUnit.type == Fixed ? cssUnit.value : childValue);
+    return 0;
+}
+
+static int getBorderPaddingMargin(RenderObject* child, bool endOfInline)
+{
+    RenderStyle* cstyle = child->style();
+    int result = 0;
+    bool leftSide = (cstyle->direction() == LTR) ? !endOfInline : endOfInline;
+    result += getBPMWidth((leftSide ? child->marginLeft() : child->marginRight()),
+                          (leftSide ? cstyle->marginLeft() :
+                           cstyle->marginRight()));
+    result += getBPMWidth((leftSide ? child->paddingLeft() : child->paddingRight()),
+                          (leftSide ? cstyle->paddingLeft() :
+                           cstyle->paddingRight()));
+    result += leftSide ? child->borderLeft() : child->borderRight();
+    return result;
+}
+
+static int inlineWidth(RenderObject* child, bool start = true, bool end = true)
+{
+    int extraWidth = 0;
+    RenderObject* parent = child->parent();
+    while (parent->isInline()) {
+        if (start && parent->firstChild() == child)
+            extraWidth += getBorderPaddingMargin(parent, false);
+        if (end && parent->lastChild() == child)
+            extraWidth += getBorderPaddingMargin(parent, true);
+        child = parent;
+        parent = child->parent();
+    }
+    return extraWidth;
+}
+
 #ifndef NDEBUG
 static bool inBidiIteratorDetach;
 #endif
@@ -86,6 +122,51 @@ void BidiIterator::operator delete(void* ptr, size_t sz)
     *(size_t*)ptr = sz;
 }
 
+#ifndef NDEBUG
+static bool inBidiRunDetach;
+#endif
+
+void BidiRun::detach(RenderArena* renderArena)
+{
+#ifndef NDEBUG
+    inBidiRunDetach = true;
+#endif
+    delete this;
+#ifndef NDEBUG
+    inBidiRunDetach = false;
+#endif
+
+    // Recover the size left there for us by operator delete and free the memory.
+    renderArena->free(*(size_t *)this, this);
+}
+
+void* BidiRun::operator new(size_t sz, RenderArena* renderArena) throw()
+{
+    return renderArena->allocate(sz);
+}
+
+void BidiRun::operator delete(void* ptr, size_t sz)
+{
+    assert(inBidiRunDetach);
+
+    // Stash size where detach can find it.
+    *(size_t*)ptr = sz;
+}
+
+static void deleteBidiRuns(RenderArena* arena)
+{
+    if (!sruns)
+        return;
+
+    unsigned int len = sruns->count();
+    for(unsigned int i=0; i < len; i++) {
+        BidiRun* s = sruns->at(i);
+        if (s)
+            s->detach(arena);
+    }
+    sruns->clear();
+}
+
 // ---------------------------------------------------------------------
 
 /* a small helper class used internally to resolve Bidi embedding levels.
@@ -136,52 +217,79 @@ inline bool operator!=( const BidiIterator &it1, const BidiIterator &it2 )
     return false;
 }
 
-static inline RenderObject *Bidinext(RenderObject *par, RenderObject *current)
+static inline RenderObject *Bidinext(RenderObject *par, RenderObject *current,
+                                     bool skipInlines = true, bool* endOfInline = 0)
 {
     RenderObject *next = 0;
+    bool oldEndOfInline = endOfInline ? *endOfInline : false;
+    if (endOfInline)
+        *endOfInline = false;
+
     while(current != 0)
     {
         //kdDebug( 6040 ) << "current = " << current << endl;
-	if(!current->isFloating() && !current->isReplaced() && !current->isPositioned()) {
-	    next = current->firstChild();
-	    if ( next && adjustEmbeddding ) {
-		EUnicodeBidi ub = next->style()->unicodeBidi();
-		if ( ub != UBNormal && !emptyRun ) {
-		    EDirection dir = next->style()->direction();
-		    QChar::Direction d = ( ub == Embed ? ( dir == RTL ? QChar::DirRLE : QChar::DirLRE )
-					   : ( dir == RTL ? QChar::DirRLO : QChar::DirLRO ) );
-		    embed( d );
-		}
-	    }
-	}
-	if(!next) {
-	    while(current && current != par) {
-		next = current->nextSibling();
-		if(next) break;
-		if ( adjustEmbeddding && current->style()->unicodeBidi() != UBNormal && !emptyRun ) {
-		    embed( QChar::DirPDF );
-		}
-		current = current->parent();
-	    }
-	}
+        if (!oldEndOfInline && !current->isFloating() && !current->isReplaced() && !current->isPositioned()) {
+            next = current->firstChild();
+            if ( next && adjustEmbeddding ) {
+                EUnicodeBidi ub = next->style()->unicodeBidi();
+                if ( ub != UBNormal && !emptyRun ) {
+                    EDirection dir = next->style()->direction();
+QChar::Direction d = ( ub == Embed ? ( dir == RTL ? QChar::DirRLE : QChar::DirLRE )
+                                   : ( dir == RTL ? QChar::DirRLO : QChar::DirLRO ) );
+                    embed( d );
+                }
+            }
+        }
+        if (!next) {
+            if (!skipInlines && !oldEndOfInline && current->isInlineFlow())
+            {
+                next = current;
+                if (endOfInline)
+                    *endOfInline = true;
+                break;
+            }
 
-        if(!next) break;
+            while (current && current != par) {
+                next = current->nextSibling();
+                if (next) break;
+                if ( adjustEmbeddding && current->style()->unicodeBidi() != UBNormal && !emptyRun ) {
+                    embed( QChar::DirPDF );
+                }
+                current = current->parent();
+                if (!skipInlines && current && current != par && current->isInlineFlow()) {
+                    next = current;
+                    if (endOfInline)
+                        *endOfInline = true;
+                    break;
+                }
+            }
+        }
+
+        if (!next) break;
 
-        if(next->isText() || next->isBR() || next->isFloating() || next->isReplaced() || next->isPositioned())
+        if (next->isText() || next->isBR() || next->isFloating() || next->isReplaced() || next->isPositioned()
+            || ((!skipInlines || !next->firstChild()) // Always return EMPTY inlines.
+                && next->isInlineFlow()))
             break;
         current = next;
     }
     return next;
 }
 
-static RenderObject *first( RenderObject *par )
+static RenderObject *first( RenderObject *par, bool skipInlines = true )
 {
     if(!par->firstChild()) return 0;
     RenderObject *o = par->firstChild();
 
-    if(!o->isText() && !o->isBR() && !o->isReplaced() && !o->isFloating() && !o->isPositioned())
-        o = Bidinext( par, o );
-
+    if (o->isInlineFlow()) {
+        if (skipInlines && o->firstChild())
+            o = Bidinext( par, o, skipInlines );
+        else
+            return o; // Never skip empty inlines.
+    }
+        
+    if (!o->isText() && !o->isBR() && !o->isReplaced() && !o->isFloating() && !o->isPositioned())
+        o = Bidinext( par, o, skipInlines );
     return o;
 }
 
@@ -282,14 +390,15 @@ static void appendRunsForObject(int start, int end, RenderObject* obj)
     }
     else {
         if (!smidpoints || !nextMidpoint || (obj != nextMidpoint->obj)) {
-            sruns->append( new BidiRun(start, end, obj, context, dir) );
+            sruns->append( new (obj->renderArena()) BidiRun(start, end, obj, context, dir) );
             return;
         }
         
         // An end midpoint has been encounted within our object.  We
         // need to go ahead and append a run with our endpoint.
         if (int(nextMidpoint->pos+1) <= end) {
-            sruns->append( new BidiRun(start, nextMidpoint->pos+1, obj, context, dir) );
+            sruns->append( new (obj->renderArena())
+                                BidiRun(start, nextMidpoint->pos+1, obj, context, dir) );
             betweenMidpoints = true;
             int nextPos = nextMidpoint->pos+1;
             smidpoints->removeFirst();
@@ -297,7 +406,7 @@ static void appendRunsForObject(int start, int end, RenderObject* obj)
             return appendRunsForObject(nextPos, end, obj);
         }
         else
-            sruns->append( new BidiRun(start, end, obj, context, dir) );
+            sruns->append( new (obj->renderArena()) BidiRun(start, end, obj, context, dir) );
     }
 }
 
@@ -398,6 +507,172 @@ static void embed( QChar::Direction d )
     adjustEmbeddding = b;
 }
 
+InlineFlowBox* RenderBlock::createLineBoxes(RenderObject* obj)
+{
+    // See if we have an unconstructed line box for this object that is also
+    // the last item on the line.
+    KHTMLAssert(obj->isInlineFlow() || obj == this);
+    RenderFlow* flow = static_cast<RenderFlow*>(obj);
+
+    // Get the last box we made for this render object.
+    InlineFlowBox* box = flow->lastLineBox();
+
+    // If this box is constructed then it is from a previous line, and we need
+    // to make a new box for our line.  If this box is unconstructed but it has
+    // something following it on the line, then we know we have to make a new box
+    // as well.  In this situation our inline has actually been split in two on
+    // the same line (this can happen with very fancy language mixtures).
+    if (!box || box->isConstructed() || box->nextOnLine()) {
+        // We need to make a new box for this render object.  Once
+        // made, we need to place it at the end of the current line.
+        InlineBox* newBox = obj->createInlineBox();
+        KHTMLAssert(newBox->isInlineFlowBox());
+        box = static_cast<InlineFlowBox*>(newBox);
+        box->setFirstLineStyleBit(m_firstLine);
+        
+        // We have a new box. Append it to the inline box we get by constructing our
+        // parent.  If we have hit the block itself, then |box| represents the root
+        // inline box for the line, and it doesn't have to be appended to any parent
+        // inline.
+        if (obj != this) {
+            InlineFlowBox* parentBox = createLineBoxes(obj->parent());
+            parentBox->addToLine(box);
+        }
+    }
+
+    return box;
+}
+
+InlineFlowBox* RenderBlock::constructLine(QPtrList<BidiRun>& runs,
+                                          const BidiIterator &start, const BidiIterator &end)
+{
+    BidiRun *r = runs.first();
+    if (!r)
+        return 0; // We had no runs. Don't make a root inline box at all. The line is empty.
+
+    InlineFlowBox* parentBox = 0;
+    while (r) {
+        // Create a box for our object.
+        r->box = r->obj->createInlineBox();
+        
+        // If we have no parent box yet, or if the run is not simply a sibling,
+        // then we need to construct inline boxes as necessary to properly enclose the
+        // run's inline box.
+        if (!parentBox || (parentBox->object() != r->obj->parent()))
+            // Create new inline boxes all the way back to the appropriate insertion point.
+            parentBox = createLineBoxes(r->obj->parent());
+
+        // Append the inline box to this line.
+        parentBox->addToLine(r->box);
+
+        // Advance to the next run.
+        r = runs.next();
+    }
+
+    // We should have a root inline box.  It should be unconstructed and
+    // be the last continuation of our line list.
+    KHTMLAssert(lastLineBox() && !lastLineBox()->isConstructed());
+
+    // Set bits on our inline flow boxes that indicate which sides should
+    // paint borders/margins/padding.  This knowledge will ultimately be used when
+    // we determine the horizontal positions and widths of all the inline boxes on
+    // the line.
+    RenderObject* endObject = 0;
+    bool lastLine = !end.obj;
+    if (end.obj && end.pos == 0)
+        endObject = end.obj;
+    lastLineBox()->determineSpacingForFlowBoxes(lastLine, endObject);
+
+    // Now mark the line boxes as being constructed.
+    lastLineBox()->setConstructed();
+
+    // Return the last line.
+    return lastLineBox();
+}
+
+void RenderBlock::computeHorizontalPositionsForLine(InlineFlowBox* lineBox, QPtrList<BidiRun>& runs,
+                                                    BidiContext* endEmbed)
+{
+    // First determine our total width.
+    int totWidth = lineBox->getFlowSpacingWidth();
+    BidiRun* r = runs.first();
+    while (r) {
+        if (r->obj->isText())
+            r->box->setWidth(static_cast<RenderText *>(r->obj)->width(r->start, r->stop-r->start, m_firstLine));
+        else if (!r->obj->isInlineFlow()) {
+            r->obj->calcWidth();
+            r->box->setWidth(r->obj->width());
+            totWidth += r->obj->marginLeft() + r->obj->marginRight();
+        }
+        totWidth += r->box->width();
+        r = runs.next();
+    }
+
+    // Armed with the total width of the line (without justification),
+    // we now examine our text-align property in order to determine where to position the
+    // objects horizontally.  The total width of the line can be increased if we end up
+    // justifying text.
+    int x = leftOffset(m_height);
+    int availableWidth = lineWidth(m_height);
+    switch(style()->textAlign()) {
+        case LEFT:
+            numSpaces = 0;
+            break;
+        case JUSTIFY:
+            if (numSpaces != 0 && !current.atEnd() && !current.obj->isBR() )
+                break;
+            // fall through
+        case TAAUTO:
+            numSpaces = 0;
+            // for right to left fall through to right aligned
+            if (endEmbed->basicDir == QChar::DirL)
+                break;
+        case RIGHT:
+            x += availableWidth - totWidth;
+            numSpaces = 0;
+            break;
+        case CENTER:
+        case KONQ_CENTER:
+            int xd = (availableWidth - totWidth)/2;
+            x += xd >0 ? xd : 0;
+            numSpaces = 0;
+            break;
+    }
+
+    r = runs.first();
+    while (r) {
+        int spaceAdd = 0;
+        if (numSpaces > 0 && r->obj->isText()) {
+            // get the number of spaces in the run
+            int spaces = 0;
+            for ( int i = r->start; i < r->stop; i++ )
+                if ( static_cast<RenderText *>(r->obj)->text()[i].direction() == QChar::DirWS )
+                    spaces++;
+            KHTMLAssert(spaces <= numSpaces);
+            spaceAdd = (availableWidth - totWidth)*spaces/numSpaces;
+            numSpaces -= spaces;
+            totWidth += spaceAdd;
+            static_cast<TextRun*>(r->box)->setSpaceAdd(spaceAdd);
+        }
+        r = runs.next();
+    }
+
+    // The widths of all runs are now known.  We can now place every inline box (and
+    // compute accurate widths for the inline flow boxes).
+    lineBox->placeBoxesHorizontally(x);
+}
+
+void RenderBlock::computeVerticalPositionsForLine(InlineFlowBox* lineBox, QPtrList<BidiRun>& runs)
+{
+    lineBox->verticallyAlignBoxes(m_height);
+
+    // Now make sure we place replaced render objects correctly.
+    BidiRun* r = runs.first();
+    while (r) {
+        r->obj->position(r->box, r->box->yPos(), r->start, r->stop - r->start, r->level%2);
+        r = runs.next();
+    }    
+}
 
 // collects one line of the paragraph and transforms it to visual order
 void RenderBlock::bidiReorderLine(const BidiIterator &start, const BidiIterator &end)
@@ -408,12 +683,13 @@ void RenderBlock::bidiReorderLine(const BidiIterator &start, const BidiIterator
         }
         return;
     }
+
 #if BIDI_DEBUG > 1
     kdDebug(6041) << "reordering Line from " << start.obj << "/" << start.pos << " to " << end.obj << "/" << end.pos << endl;
 #endif
 
     QPtrList<BidiRun> runs;
-    runs.setAutoDelete(true);
+    runs.setAutoDelete(false);
     sruns = &runs;
 
     //    context->ref();
@@ -856,147 +1132,20 @@ void RenderBlock::bidiReorderLine(const BidiIterator &start, const BidiIterator
     }
 #endif
 
-    int maxPositionTop = 0;
-    int maxPositionBottom = 0;
-    int maxAscent = 0;
-    int maxDescent = 0;
-    r = runs.first();
-    while ( r ) {
-        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( m_firstLine );
-        //kdDebug(6041) << "object="<< r->obj << " height="<<r->height<<" baseline="<< r->baseline << " vertical=" << r->vertical <<endl;
-        //int ascent;
-        if ( r->vertical == PositionTop ) {
-            if ( maxPositionTop < r->height ) maxPositionTop = r->height;
-        }
-        else if ( r->vertical == PositionBottom ) {
-            if ( maxPositionBottom < r->height ) maxPositionBottom = r->height;
-        }
-        else {
-            int ascent = r->baseline - r->vertical;
-            int descent = r->height - ascent;
-            if(maxAscent < ascent) maxAscent = ascent;
-            if(maxDescent < descent) maxDescent = descent;
-        }
-        r = runs.next();
-    }
-    if ( maxAscent+maxDescent < QMAX( maxPositionTop, maxPositionBottom ) ) {
-        // now the computed lineheight needs to be extended for the
-        // positioned elements
-        // see khtmltests/rendering/html_align.html
-        // ### only iterate over the positioned ones!
-        for ( r = runs.first(); r; r = runs.next() ) {
-            if ( r->vertical == PositionTop ) {
-                if ( maxAscent + maxDescent < r->height )
-                    maxDescent = r->height - maxAscent;
-            }
-            else if ( r->vertical == PositionBottom ) {
-                if ( maxAscent + maxDescent < r->height )
-                    maxAscent = r->height - maxDescent;
-            }
-            else
-                continue;
-
-            if ( maxAscent + maxDescent >= QMAX( maxPositionTop, maxPositionBottom ) )
-                break;
-
-        }
-    }
-    int maxHeight = maxAscent + maxDescent;
-    // CSS2: 10.8.1: line-height on the block level element specifies the *minimum*
-    // height of the generated line box
-    r = runs.first();
-    // ### we have no reliable way of detecting empty lineboxes - which
-    // are not allowed to have any height. sigh.(Dirk)
-//     if ( r ) {
-//         int blockHeight = lineHeight( firstLine );
-//         if ( blockHeight > maxHeight )
-//             maxHeight = blockHeight;
-//     }
-    int totWidth = 0;
-#if BIDI_DEBUG > 0
-    kdDebug( 6040 ) << "starting run.." << endl;
-#endif
-    while ( r ) {
-        if(r->vertical == PositionTop)
-            r->vertical = m_height;
-        else if(r->vertical == PositionBottom)
-            r->vertical = m_height + maxHeight - r->height;
-        else
-            r->vertical += m_height + maxAscent - r->baseline;
-
-#if BIDI_DEBUG > 0
-	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, m_firstLine);
-        else {
-            r->obj->calcWidth();
-            r->width = r->obj->width()+r->obj->marginLeft()+r->obj->marginRight();
-        }
-        totWidth += r->width;
-        r = runs.next();
-    }
-    //kdDebug(6040) << "yPos of line=" << m_height << "  lineBoxHeight=" << maxHeight << endl;
-
-    // now construct the reordered string out of the runs...
-
-    r = runs.first();
-    int x = leftOffset(m_height);
-    int availableWidth = lineWidth(m_height);
-    switch(style()->textAlign()) {
-    case LEFT:
-	numSpaces = 0;
-        break;
-    case JUSTIFY:
-        if(numSpaces != 0 && !current.atEnd() && !current.obj->isBR() )
-            break;
-	// fall through
-    case TAAUTO:
-	numSpaces = 0;
-        // for right to left fall through to right aligned
-	if ( endEmbed->basicDir == QChar::DirL )
-	    break;
-    case RIGHT:
-        x += availableWidth - totWidth;
-	numSpaces = 0;
-        break;
-    case CENTER:
-    case KONQ_CENTER:
-        int xd = (availableWidth - totWidth)/2;
-        x += xd>0?xd:0;
-	numSpaces = 0;
-        break;
-    }
-    while ( r ) {
-#if BIDI_DEBUG > 1
-        kdDebug(6040) << "positioning " << r->obj << " start=" << r->start << " stop=" << r->stop << " yPos=" << r->vertical << endl;
-#endif
-	int spaceAdd = 0;
-	if ( numSpaces > 0 ) {
-	    if ( r->obj->isText() ) {
-		// get number of spaces in run
-		int spaces = 0;
-		for ( int i = r->start; i < r->stop; i++ )
-		    if ( static_cast<RenderText *>(r->obj)->text()[i].direction() == QChar::DirWS )
-			spaces++;
-		if ( spaces > numSpaces ) // should never happen...
-		    spaces = numSpaces;
-		spaceAdd = (availableWidth - totWidth)*spaces/numSpaces;
-		numSpaces -= spaces;
-		totWidth += 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();
-    }
+    // Now that the runs have been ordered, we create the line boxes.
+    // At the same time we figure out where border/padding/margin should be applied for
+    // inline flow boxes.
+    InlineFlowBox* lineBox = constructLine(runs, start, end);
+    if (!lineBox)
+        return;
 
-    m_height += maxHeight;
+    // Now we position all of our text runs horizontally.
+    computeHorizontalPositionsForLine(lineBox, runs, endEmbed);
 
+    // Now position our text runs vertically.
+    computeVerticalPositionsForLine(lineBox, runs);
+    
+    deleteBidiRuns(renderArena());
     sruns = 0;
 }
 
@@ -1033,10 +1182,14 @@ void RenderBlock::layoutInlineChildren(bool relayoutChildren)
 
     m_height += paddingTop();
     toAdd += paddingBottom();
+
+    // Clear out our line boxes.
+    deleteLineBoxes();
     
-    if(firstChild()) {
+    if (firstChild()) {
         // layout replaced elements
-        RenderObject *o = first( this );
+        bool endOfInline = false;
+        RenderObject *o = first( this, false );
         while ( o ) {
             if(o->isReplaced() || o->isFloating() || o->isPositioned()) {
                 //kdDebug(6041) << "layouting replaced or floating child" << endl;
@@ -1047,9 +1200,11 @@ void RenderBlock::layoutInlineChildren(bool relayoutChildren)
                 if(o->isPositioned())
                     o->containingBlock()->insertSpecialObject(o);
             }
-            else if(o->isText())
+            else if(o->isText()) // FIXME: Should be able to combine deleteLineBoxes/Runs
                 static_cast<RenderText *>(o)->deleteRuns();
-            o = Bidinext( this, o );
+            else if (o->isInlineFlow() && !endOfInline)
+                static_cast<RenderFlow*>(o)->deleteLineBoxes();
+            o = Bidinext( this, o, false, &endOfInline);
         }
 
         BidiContext *startEmbed;
@@ -1224,6 +1379,11 @@ BidiIterator RenderBlock::findNextLineBreak(BidiIterator &start, QPtrList<BidiIt
             } else if(o->isPositioned()) {
                 o->containingBlock()->insertSpecialObject(o);
             }
+        } else if (o->isInlineFlow()) {
+            // Only empty inlines matter.  We treat those similarly to replaced elements.
+            KHTMLAssert(!o->firstChild());
+            tmpW += o->marginLeft()+o->borderLeft()+o->paddingLeft()+
+                    o->marginRight()+o->borderRight()+o->paddingRight();
         } else if ( o->isReplaced() ) {
             if (o->style()->whiteSpace() != NOWRAP || last->style()->whiteSpace() != NOWRAP) {
                 w += tmpW;
@@ -1232,7 +1392,7 @@ BidiIterator RenderBlock::findNextLineBreak(BidiIterator &start, QPtrList<BidiIt
                 lBreak.pos = 0;
             }
 
-            tmpW += o->width()+o->marginLeft()+o->marginRight();
+            tmpW += o->width()+o->marginLeft()+o->marginRight()+inlineWidth(o);
             if (ignoringSpaces) {
                 BidiIterator* startMid = new (o->renderArena()) BidiIterator();
                 startMid->obj = o;
@@ -1275,9 +1435,11 @@ BidiIterator RenderBlock::findNextLineBreak(BidiIterator &start, QPtrList<BidiIt
             int lastSpace = pos;
             bool isPre = o->style()->whiteSpace() == PRE;
             int wordSpacing = o->style()->wordSpacing();
-            
-            //QChar space[1]; space[0] = ' ';
-            //int spaceWidth = f->width(space, 1, 0);
+
+            bool appliedStartWidth = pos > 0; // If the span originated on a previous line,
+                                              // then assume the start width has been applied.
+            bool appliedEndWidth = false;
+
             while(len) {
                 //XXXdwh This is wrong. Still mutating the DOM
                 // string for newlines... will fix in second stage.
@@ -1314,6 +1476,11 @@ BidiIterator RenderBlock::findNextLineBreak(BidiIterator &start, QPtrList<BidiIt
                     if (currentCharacterIsSpace && !previousCharacterIsSpace)
                         lastSpacePos = pos;
                     tmpW += t->width(lastSpace, pos - lastSpace, f);
+                    if (!appliedStartWidth) {
+                        tmpW += inlineWidth(o, true, false);
+                        appliedStartWidth = true;
+                    }
+                    
                     applyWordSpacing = (wordSpacing && currentCharacterIsSpace && !previousCharacterIsSpace &&
                         t->containsOnlyWhitespace(pos+1, strlen-(pos+1)));
 
@@ -1406,6 +1573,10 @@ BidiIterator RenderBlock::findNextLineBreak(BidiIterator &start, QPtrList<BidiIt
             // IMPORTANT: pos is > length here!
             if (!ignoringSpaces)
                 tmpW += t->width(lastSpace, pos - lastSpace, f);
+            if (!appliedStartWidth)
+                tmpW += inlineWidth(o, true, false);
+            if (!appliedEndWidth)
+                tmpW += inlineWidth(o, false, true);
         } else
             KHTMLAssert( false );
 
@@ -1561,3 +1732,5 @@ BidiIterator RenderBlock::findNextLineBreak(BidiIterator &start, QPtrList<BidiIt
 #undef BIDI_DEBUG
 #undef DEBUG_LINEBREAKS
 #undef DEBUG_LAYOUT
+
+}
diff --git a/WebCore/khtml/rendering/bidi.h b/WebCore/khtml/rendering/bidi.h
index 8b80894..6d73a99 100644
--- a/WebCore/khtml/rendering/bidi.h
+++ b/WebCore/khtml/rendering/bidi.h
@@ -30,6 +30,7 @@ class RenderArena;
 namespace khtml {
     class RenderBlock;
     class RenderObject;
+    class InlineBox;
 
     class BidiContext {
     public:
@@ -53,8 +54,7 @@ namespace khtml {
 
     struct BidiRun {
 	BidiRun(int _start, int _stop, RenderObject *_obj, BidiContext *context, QChar::Direction dir)
-	    :  vertical( 0 ), baseline( 0 ), height( 0 ), width( 0 ),
-	       start( _start ), stop( _stop ), obj( _obj )
+	    :  start( _start ), stop( _stop ), obj( _obj ), box(0)
 	{
 	    if(dir == QChar::DirON) dir = context->dir;
 
@@ -72,15 +72,25 @@ namespace khtml {
 	    }
 	}
 
-	int vertical;
-	short baseline;
-	short height;
-	int width;
+        void detach(RenderArena* renderArena);
 
+        // Overloaded new operator.
+        void* operator new(size_t sz, RenderArena* renderArena) throw();
+
+        // Overridden to prevent the normal delete from being called.
+        void operator delete(void* ptr, size_t sz);
+
+private:
+        // The normal operator new is disallowed.
+        void* operator new(size_t sz) throw();
+
+public:
 	int start;
 	int stop;
-	RenderObject *obj;
 
+        RenderObject *obj;
+        InlineBox* box;
+        
 	// explicit + implicit levels here
 	uchar level;
     };
diff --git a/WebCore/khtml/rendering/render_block.cpp b/WebCore/khtml/rendering/render_block.cpp
index 7bc6145..1205ef9 100644
--- a/WebCore/khtml/rendering/render_block.cpp
+++ b/WebCore/khtml/rendering/render_block.cpp
@@ -1785,7 +1785,7 @@ RenderObject* InlineMinMaxIterator::next()
             result = current->firstChild();
         if (!result) {
             // We hit the end of our inline. (It was empty, e.g., <span></span>.)
-            if (!oldEndOfInline && (current->isRenderInline() || current->isRunIn())) {
+            if (!oldEndOfInline && current->isInlineFlow()) {
                 result = current;
                 endOfInline = true;
                 break;
@@ -1795,8 +1795,7 @@ RenderObject* InlineMinMaxIterator::next()
                 result = current->nextSibling();
                 if (result) break;
                 current = current->parent();
-                if (current && current != parent &&
-                    (current->isRenderInline() || current->isRunIn())) {
+                if (current && current != parent && current->isInlineFlow()) {
                     result = current;
                     endOfInline = true;
                     break;
@@ -1808,7 +1807,7 @@ RenderObject* InlineMinMaxIterator::next()
 
         if (result->isText() || result->isBR() ||
             result->isFloating() || result->isReplaced() ||
-            result->isRenderInline() || result->isRunIn())
+            result->isInlineFlow())
             break;
         
         current = result;
@@ -1905,7 +1904,7 @@ void RenderBlock::calcInlineMinMaxWidth()
 
             if (!child->isText()) {
                 // Case (1) and (2).  Inline replaced and inline flow elements.
-                if (child->isRenderInline() || child->isRunIn()) {
+                if (child->isInlineFlow()) {
                     // Add in padding/border/margin from the appropriate side of
                     // the element.
                     int bpm = getBorderPaddingMargin(child, childIterator.endOfInline);
diff --git a/WebCore/khtml/rendering/render_block.h b/WebCore/khtml/rendering/render_block.h
index 41b035d..64c1ecc 100644
--- a/WebCore/khtml/rendering/render_block.h
+++ b/WebCore/khtml/rendering/render_block.h
@@ -90,9 +90,16 @@ public:
     void layoutInlineChildren( bool relayoutChildren );
     void layoutSpecialObjects( bool relayoutChildren );
 
-    // the implementation of the following two functions is in bidi.cpp
+    // the implementation of the following functions is in bidi.cpp
     void bidiReorderLine(const BidiIterator &start, const BidiIterator &end);
     BidiIterator findNextLineBreak(BidiIterator &start, QPtrList<BidiIterator>& midpoints);
+    InlineFlowBox* constructLine(QPtrList<BidiRun>& runs, const BidiIterator& start,
+                             const BidiIterator& end);
+    InlineFlowBox* createLineBoxes(RenderObject* obj);
+    void computeHorizontalPositionsForLine(InlineFlowBox* lineBox, QPtrList<BidiRun>& runs,
+                                           BidiContext* endEmbed);
+    void computeVerticalPositionsForLine(InlineFlowBox* lineBox, QPtrList<BidiRun>& runs);
+    // end bidi.cpp functions
     
     virtual void paint(QPainter *, int x, int y, int w, int h,
                        int tx, int ty, PaintAction paintAction);
diff --git a/WebCore/khtml/rendering/render_box.cpp b/WebCore/khtml/rendering/render_box.cpp
index 781aa27..e80dbfd 100644
--- a/WebCore/khtml/rendering/render_box.cpp
+++ b/WebCore/khtml/rendering/render_box.cpp
@@ -437,12 +437,10 @@ bool RenderBox::absolutePosition(int &xPos, int &yPos, bool f)
     }
 }
 
-void RenderBox::position(int x, int y, int, int, int, bool, bool, int)
+void RenderBox::position(InlineBox* box, int y, int from, int len, bool reverse)
 {
-    m_x = x + marginLeft();
-    m_y = y;
-    // ### paddings
-    //m_width = width;
+    m_x = box->xPos();
+    m_y = y + marginTop();
 }
 
 void RenderBox::repaint(bool immediate)
@@ -454,6 +452,19 @@ void RenderBox::repaint(bool immediate)
 
 void RenderBox::repaintRectangle(int x, int y, int w, int h, bool immediate, bool f)
 {
+    if (style()->overflow() == OHIDDEN) {
+        int ow = style() ? style()->outlineWidth() : 0;
+        QRect boxRect(-ow, -ow, overflowWidth()+ow*2, overflowHeight()+ow*2);
+        QRect repaintRect(x, y, w, h);
+        if (!repaintRect.intersects(boxRect))
+            return;
+        repaintRect = repaintRect.intersect(boxRect);
+        x = repaintRect.x();
+        y = repaintRect.y();
+        w = repaintRect.width();
+        h = repaintRect.height();
+    }
+        
     x += m_x;
     y += m_y;
     
diff --git a/WebCore/khtml/rendering/render_box.h b/WebCore/khtml/rendering/render_box.h
index faed5bd..fe965d5 100644
--- a/WebCore/khtml/rendering/render_box.h
+++ b/WebCore/khtml/rendering/render_box.h
@@ -83,7 +83,7 @@ public:
     // shifted. -dwh
     void calcHorizontalMargins(const Length& ml, const Length& mr, int cw);
 
-    virtual void position(int x, int y, int from, int len, int width, bool reverse, bool firstLine, int);
+    virtual void position(InlineBox* box, int y, int from, int len, bool reverse);
     
     virtual int lowestPosition() const;
     virtual int rightmostPosition() const;
diff --git a/WebCore/khtml/rendering/render_flow.cpp b/WebCore/khtml/rendering/render_flow.cpp
index eebdc7a..6dcf570 100644
--- a/WebCore/khtml/rendering/render_flow.cpp
+++ b/WebCore/khtml/rendering/render_flow.cpp
@@ -36,6 +36,8 @@
 #include "html/html_formimpl.h"
 #include "render_inline.h"
 #include "render_block.h"
+#include "render_arena.h"
+#include "render_line.h"
 
 #include "khtmlview.h"
 #include "htmltags.h"
@@ -127,3 +129,39 @@ void RenderFlow::addChild(RenderObject *newChild, RenderObject *beforeChild)
     return addChildToFlow(newChild, beforeChild);
 }
 
+void RenderFlow::deleteLineBoxes(RenderArena* arena)
+{
+    if (m_firstLineBox) {
+        if (!arena)
+            arena = renderArena();
+        InlineRunBox *curr=m_firstLineBox, *next=0;
+        while (curr) {
+            next = curr->nextLineBox();
+            curr->detach(arena);
+            curr = next;
+        }
+        m_firstLineBox = 0;
+        m_lastLineBox = 0;
+    }
+}
+
+void RenderFlow::detach(RenderArena* renderArena)
+{
+    deleteLineBoxes(renderArena);
+    RenderBox::detach(renderArena);
+}
+
+InlineBox* RenderFlow::createInlineBox()
+{
+    InlineFlowBox* flowBox = new (renderArena()) InlineFlowBox(this);
+    if (!m_firstLineBox)
+        m_firstLineBox = m_lastLineBox = flowBox;
+    else {
+        m_lastLineBox->setNextLineBox(flowBox);
+        flowBox->setPreviousLineBox(m_lastLineBox);
+        m_lastLineBox = flowBox;
+    }
+
+    return flowBox;
+}
+
diff --git a/WebCore/khtml/rendering/render_flow.h b/WebCore/khtml/rendering/render_flow.h
index e40a668..f774a27 100644
--- a/WebCore/khtml/rendering/render_flow.h
+++ b/WebCore/khtml/rendering/render_flow.h
@@ -26,6 +26,7 @@
 
 #include "render_box.h"
 #include "bidi.h"
+#include "render_line.h"
 
 namespace khtml {
 
@@ -43,7 +44,7 @@ class RenderFlow : public RenderBox
 public:
     RenderFlow(DOM::NodeImpl* node)
       : RenderBox(node)
-      { m_continuation = 0; }
+    { m_continuation = 0; m_firstLineBox = 0; m_lastLineBox = 0; }
     
     virtual RenderFlow* continuation() const { return m_continuation; }
     void setContinuation(RenderFlow* c) { m_continuation = c; }
@@ -55,12 +56,26 @@ public:
 
     static RenderFlow* createFlow(DOM::NodeImpl* node, RenderStyle* style, RenderArena* arena);
 
+    void deleteLineBoxes(RenderArena* arena=0);
+    virtual void detach(RenderArena* arena);
+
+    InlineFlowBox* firstLineBox() { return m_firstLineBox; }
+    InlineFlowBox* lastLineBox() { return m_lastLineBox; }
+
+    virtual InlineBox* createInlineBox();
+    
 protected:
     // 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;
+
+    // For block flows, each box represents the root inline box for a line in the
+    // paragraph.
+    // For inline flows, each box represents a portion of that inline.
+    InlineFlowBox* m_firstLineBox;
+    InlineFlowBox* m_lastLineBox;
 };
 
     
diff --git a/WebCore/khtml/rendering/render_image.cpp b/WebCore/khtml/rendering/render_image.cpp
index 7c34eef..a86603b 100644
--- a/WebCore/khtml/rendering/render_image.cpp
+++ b/WebCore/khtml/rendering/render_image.cpp
@@ -204,7 +204,8 @@ void RenderImage::paintObject(QPainter *p, int /*_x*/, int /*_y*/, int /*_w*/, i
                 //qDebug("qDrawShadePanel %d/%d/%d/%d", _tx + leftBorder, _ty + topBorder, cWidth, cHeight);
                 p->setPen (Qt::lightGray);
                 p->setBrush (Qt::NoBrush);
-                p->drawRect (_tx, _ty, cWidth, cHeight);
+                p->drawRect (_tx + leftBorder + leftPad, _ty + topBorder + topPad,
+                             cWidth, cHeight);
 	    }
 #else /* not APPLE_CHANGES */
             if ( !berrorPic ) {
diff --git a/WebCore/khtml/rendering/render_inline.cpp b/WebCore/khtml/rendering/render_inline.cpp
index a9a7300..f38b8ae 100644
--- a/WebCore/khtml/rendering/render_inline.cpp
+++ b/WebCore/khtml/rendering/render_inline.cpp
@@ -21,6 +21,7 @@
  */
 
 #include <kglobal.h>
+#include "render_arena.h"
 #include "render_inline.h"
 #include "render_block.h"
 
diff --git a/WebCore/khtml/rendering/render_inline.h b/WebCore/khtml/rendering/render_inline.h
index b372e59..9d8e604 100644
--- a/WebCore/khtml/rendering/render_inline.h
+++ b/WebCore/khtml/rendering/render_inline.h
@@ -63,7 +63,7 @@ public:
     virtual short offsetWidth() const;
     virtual int offsetHeight() const;
     virtual int offsetLeft() const;
-    virtual int offsetTop() const;    
+    virtual int offsetTop() const;
 };
 
 }; // namespace
diff --git a/WebCore/khtml/rendering/render_line.cpp b/WebCore/khtml/rendering/render_line.cpp
new file mode 100644
index 0000000..7f68d77
--- /dev/null
+++ b/WebCore/khtml/rendering/render_line.cpp
@@ -0,0 +1,378 @@
+/**
+* This file is part of the html renderer for KDE.
+ *
+ * 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 <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_inline.h"
+#include "render_block.h"
+#include "render_arena.h"
+#include "render_line.h"
+
+#include "khtmlview.h"
+#include "htmltags.h"
+
+using namespace DOM;
+using namespace khtml;
+
+#ifndef NDEBUG
+static bool inInlineBoxDetach;
+#endif
+
+void InlineBox::detach(RenderArena* renderArena)
+{
+#ifndef NDEBUG
+    inInlineBoxDetach = true;
+#endif
+    delete this;
+#ifndef NDEBUG
+    inInlineBoxDetach = false;
+#endif
+
+    // Recover the size left there for us by operator delete and free the memory.
+    renderArena->free(*(size_t *)this, this);
+}
+
+void* InlineBox::operator new(size_t sz, RenderArena* renderArena) throw()
+{
+    return renderArena->allocate(sz);
+}
+
+
+void InlineBox::operator delete(void* ptr, size_t sz)
+{
+    assert(inInlineBoxDetach);
+
+    // Stash size where detach can find it.
+    *(size_t *)ptr = sz;
+}
+
+int InlineFlowBox::marginLeft()
+{
+    if (!includeLeftEdge())
+        return 0;
+    
+    RenderStyle* cstyle = object()->style();
+    Length margin = cstyle->marginLeft();
+    if (margin.type != Variable)
+        return (margin.type == Fixed ? margin.value : object()->marginLeft());
+    return 0;
+}
+
+int InlineFlowBox::marginRight()
+{
+    if (!includeRightEdge())
+        return 0;
+    
+    RenderStyle* cstyle = object()->style();
+    Length margin = cstyle->marginRight();
+    if (margin.type != Variable)
+        return (margin.type == Fixed ? margin.value : object()->marginRight());
+    return 0;
+}
+
+int InlineFlowBox::marginBorderPaddingLeft()
+{
+    return marginLeft() + borderLeft() + paddingLeft();
+}
+
+int InlineFlowBox::marginBorderPaddingRight()
+{
+    return marginRight() + borderRight() + paddingRight();
+}
+
+int InlineFlowBox::getFlowSpacingWidth()
+{
+    int totWidth = marginBorderPaddingLeft() + marginBorderPaddingRight();
+    for (InlineBox* curr = firstChild(); curr; curr = curr->nextOnLine()) {
+        if (curr->isInlineFlowBox())
+            totWidth += static_cast<InlineFlowBox*>(curr)->getFlowSpacingWidth();
+    }
+    return totWidth;
+}
+
+bool InlineFlowBox::nextOnLineExists()
+{
+    if (!parent())
+        return false;
+
+    if (nextOnLine())
+        return true;
+
+    return parent()->nextOnLineExists();
+}
+
+bool InlineFlowBox::prevOnLineExists()
+{
+    if (!parent())
+        return false;
+
+    if (prevOnLine())
+        return true;
+
+    return parent()->prevOnLineExists();
+}
+
+bool InlineFlowBox::onEndChain(RenderObject* endObject)
+{
+    if (!endObject)
+        return false;
+    
+    if (endObject == object())
+        return true;
+
+    RenderObject* curr = endObject;
+    RenderObject* parent = curr->parent();
+    while (parent && !parent->isRenderBlock()) {
+        if (parent->lastChild() != curr)
+            return false;
+        curr = parent;
+        parent = curr->parent();
+    }
+
+    return true;
+}
+
+void InlineFlowBox::determineSpacingForFlowBoxes(bool lastLine, RenderObject* endObject)
+{
+    // All boxes start off open.  They will not apply any margins/border/padding on
+    // any side.
+    bool includeLeftEdge = false;
+    bool includeRightEdge = false;
+
+    RenderFlow* flow = static_cast<RenderFlow*>(object());
+    
+    if (!flow->firstChild())
+        includeLeftEdge = includeRightEdge = true; // Empty inlines never split across lines.
+    else if (parent()) { // The root inline box never has borders/margins/padding.
+        bool ltr = flow->style()->direction() == LTR;
+        
+        // Check to see if all initial lines are unconstructed.  If so, then
+        // we know the inline began on this line.
+        if (!flow->firstLineBox()->isConstructed()) {
+            if (ltr && flow->firstLineBox() == this)
+                includeLeftEdge = true;
+            else if (!ltr && flow->lastLineBox() == this)
+                includeRightEdge = true;
+        }
+    
+        // In order to determine if the inline ends on this line, we check three things:
+        // (1) If we are the last line and we don't have a continuation(), then we can
+        // close up.
+        // (2) If the last line box for the flow has an object following it on the line (ltr,
+        // reverse for rtl), then the inline has closed.
+        // (3) The line may end on the inline.  If we are the last child (climbing up
+        // the end object's chain), then we just closed as well.
+        if (!flow->lastLineBox()->isConstructed()) {
+            if (ltr) {
+                if (!nextLineBox() &&
+                    ((lastLine && !object()->continuation()) || nextOnLineExists()
+                     || onEndChain(endObject)))
+                    includeRightEdge = true;
+            }
+            else {
+                if ((!prevLineBox() || !prevLineBox()->isConstructed()) &&
+                    ((lastLine && !object()->continuation()) ||
+                     prevOnLineExists() || onEndChain(endObject)))
+                    includeLeftEdge = true;
+            }
+            
+        }
+    }
+
+    setEdges(includeLeftEdge, includeRightEdge);
+
+    // Recur into our children.
+    for (InlineBox* currChild = firstChild(); currChild; currChild = currChild->nextOnLine()) {
+        if (currChild->isInlineFlowBox()) {
+            InlineFlowBox* currFlow = static_cast<InlineFlowBox*>(currChild);
+            currFlow->determineSpacingForFlowBoxes(lastLine, endObject);
+        }
+    }
+}
+
+int InlineFlowBox::placeBoxesHorizontally(int x)
+{
+    // Set our x position.
+    setXPos(x);
+
+    int startX = x;
+    x += borderLeft() + paddingLeft();
+    
+    for (InlineBox* curr = firstChild(); curr; curr = curr->nextOnLine()) {
+        if (curr->object()->isText()) {
+            TextRun* text = static_cast<TextRun*>(curr);
+            text->setXPos(x);
+            x += text->width();
+        }
+        else {
+            if (curr->object()->isInlineFlow()) {
+                InlineFlowBox* flow = static_cast<InlineFlowBox*>(curr);
+                x += flow->marginLeft();
+                x = flow->placeBoxesHorizontally(x);
+                x += flow->marginRight();
+            }
+            else {
+                x += curr->object()->marginLeft();
+                curr->setXPos(x);
+                x += curr->width() + curr->object()->marginRight();
+            }
+        }
+    }
+
+    x += borderRight() + paddingRight();
+    setWidth(x-startX);
+    return x;
+}
+
+void InlineFlowBox::verticallyAlignBoxes(int& heightOfBlock)
+{
+    int maxPositionTop = 0;
+    int maxPositionBottom = 0;
+    int maxAscent = 0;
+    int maxDescent = 0;
+
+    // Figure out if we're in strict mode.
+    RenderObject* curr = object();
+    while (curr && !curr->element())
+        curr = curr->container();
+    bool strictMode = (curr && curr->element()->getDocument()->inStrictMode());
+    
+    computeLogicalBoxHeights(maxPositionTop, maxPositionBottom, maxAscent, maxDescent, strictMode);
+
+    if (maxAscent + maxDescent < QMAX(maxPositionTop, maxPositionBottom))
+        adjustMaxAscentAndDescent(maxAscent, maxDescent, maxPositionTop, maxPositionBottom);
+
+    int maxHeight = maxAscent + maxDescent;
+    placeBoxesVertically(heightOfBlock, maxHeight, maxAscent, strictMode);
+    heightOfBlock += maxHeight;
+}
+
+void InlineFlowBox::adjustMaxAscentAndDescent(int& maxAscent, int& maxDescent,
+                                              int maxPositionTop, int maxPositionBottom)
+{
+    for (InlineBox* curr = firstChild(); curr; curr = curr->nextOnLine()) {
+        // The computed lineheight needs to be extended for the
+        // positioned elements
+        if (curr->yPos() == PositionTop || curr->yPos() == PositionBottom) {
+            if (curr->yPos() == PositionTop) {
+                if (maxAscent + maxDescent < curr->height())
+                    maxDescent = curr->height() - maxAscent;
+            }
+            else {
+                if (maxAscent + maxDescent < curr->height())
+                    maxAscent = curr->height() - maxDescent;
+            }
+
+            if ( maxAscent + maxDescent >= QMAX( maxPositionTop, maxPositionBottom ) )
+                break;
+        }
+
+        if (curr->isInlineFlowBox())
+            static_cast<InlineFlowBox*>(curr)->adjustMaxAscentAndDescent(maxAscent, maxDescent, maxPositionTop, maxPositionBottom);
+    }
+}
+
+void InlineFlowBox::computeLogicalBoxHeights(int& maxPositionTop, int& maxPositionBottom,
+                                             int& maxAscent, int& maxDescent, bool strictMode)
+{
+    if (!parent()) {
+        // Examine our root box.
+        setHeight(object()->lineHeight(m_firstLine));
+        bool isTableCell = object()->isTableCell();
+        if (isTableCell) {
+            RenderTableCell* tableCell = static_cast<RenderTableCell*>(object());
+            setBaseline(tableCell->RenderBlock::baselinePosition(m_firstLine));
+        }
+        else
+            setBaseline(object()->baselinePosition(m_firstLine));
+        if (hasTextChildren() || strictMode) {
+            int ascent = baseline();
+            int descent = height() - ascent;
+            if (maxAscent < ascent)
+                maxAscent = ascent;
+            if (maxDescent < descent)
+                maxDescent = descent;
+        }
+    }
+    
+    for (InlineBox* curr = firstChild(); curr; curr = curr->nextOnLine()) {
+        curr->setHeight(curr->object()->lineHeight(m_firstLine));
+        curr->setBaseline(curr->object()->baselinePosition(m_firstLine));
+        curr->setYPos(curr->object()->verticalPositionHint(m_firstLine));
+        if (curr->yPos() == PositionTop) {
+            if (maxPositionTop < curr->height())
+                maxPositionTop = curr->height();
+        }
+        else if (curr->yPos() == PositionBottom) {
+            if (maxPositionBottom < curr->height())
+                maxPositionBottom = curr->height();
+        }
+        else if (curr->hasTextChildren() || strictMode) {
+            int ascent = curr->baseline() - curr->yPos();
+            int descent = curr->height() - ascent;
+            if (maxAscent < ascent)
+                maxAscent = ascent;
+            if (maxDescent < descent)
+                maxDescent = descent;
+        }
+
+        if (curr->isInlineFlowBox())
+            static_cast<InlineFlowBox*>(curr)->computeLogicalBoxHeights(maxPositionTop, maxPositionBottom, maxAscent, maxDescent, strictMode);
+    }
+}
+
+void InlineFlowBox::placeBoxesVertically(int y, int maxHeight, int maxAscent, bool strictMode)
+{
+    if (!parent()) {
+        if (hasTextChildren() || strictMode)
+            setYPos(y + maxAscent - baseline());// Place our root box.
+        // FIXME: Use the tallest y/height out of our children. 
+    }
+    
+    for (InlineBox* curr = firstChild(); curr; curr = curr->nextOnLine()) {
+        if (curr->yPos() == PositionTop)
+            curr->setYPos(y);
+        else if (curr->yPos() == PositionBottom)
+            curr->setYPos(y + maxHeight - curr->height());
+        else if (curr->hasTextChildren() || strictMode)
+            // FIXME: Use the tallest y/height out of our children. 
+            curr->setYPos(curr->yPos() + y + maxAscent - curr->baseline());
+
+        // FIXME: Adjust the y position and heights of replaced elements for margins.
+        // Adjust inline flows to use the font box height and not the logical height.
+        if (curr->isInlineFlowBox())
+            static_cast<InlineFlowBox*>(curr)->placeBoxesVertically(y, maxHeight, maxAscent,
+                                                                    strictMode);
+    }
+}
+
+
diff --git a/WebCore/khtml/rendering/render_line.h b/WebCore/khtml/rendering/render_line.h
new file mode 100644
index 0000000..12ba150
--- /dev/null
+++ b/WebCore/khtml/rendering/render_line.h
@@ -0,0 +1,212 @@
+/*
+ * This file is part of the line box implementation for KDE.
+ *
+ * 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_LINE_H
+#define RENDER_LINE_H
+
+namespace khtml {
+
+class InlineFlowBox;
+
+// InlineBox represents a rectangle that occurs on a line.  It corresponds to
+// some RenderObject (i.e., it represents a portion of that RenderObject).
+class InlineBox
+{
+public:
+    InlineBox(RenderObject* obj)
+    :m_object(obj), m_x(0), m_y(0), m_width(0), m_height(0), m_baseline(0),
+     m_firstLine(false), m_constructed(false)
+    {
+        m_next = 0;
+        m_prev = 0;
+        m_parent = 0;
+    }
+
+    virtual ~InlineBox() {};
+
+    void detach(RenderArena* renderArena);
+
+    // Overloaded new operator.
+    void* operator new(size_t sz, RenderArena* renderArena) throw();
+
+    // Overridden to prevent the normal delete from being called.
+    void operator delete(void* ptr, size_t sz);
+
+private:
+    // The normal operator new is disallowed.
+    void* operator new(size_t sz) throw();
+    
+public:
+    virtual bool isInlineBox() { return false; }
+    virtual bool isInlineFlowBox() { return false; }
+    virtual bool isContainer() { return false; }
+    virtual bool isTextRun() { return false; }
+    
+    bool isConstructed() { return m_constructed; }
+    virtual void setConstructed() {
+        m_constructed = true;
+        if (m_next)
+            m_next->setConstructed();
+    }
+
+    void setFirstLineStyleBit(bool f) { m_firstLine = f; }
+
+    InlineBox* nextOnLine() { return m_next; }
+    InlineBox* prevOnLine() { return m_prev; }
+    RenderObject* object() { return m_object; }
+
+    InlineFlowBox* parent() { return m_parent; }
+    void setParent(InlineFlowBox* par) { m_parent = par; }
+
+    void setWidth(short w) { m_width = w; }
+    short width() { return m_width; }
+
+    void setXPos(short x) { m_x = x; }
+    short xPos() { return m_x; }
+
+    void setYPos(int y) { m_y = y; }
+    int yPos() { return m_y; }
+
+    void setHeight(int h) { m_height = h; }
+    int height() { return m_height; }
+    
+    void setBaseline(int b) { m_baseline = b; }
+    int baseline() { return m_baseline; }
+
+    virtual bool hasTextChildren() { return true; }
+    
+public: // FIXME: Would like to make this protected, but methods are accessing these
+        // members over in the part.
+    RenderObject* m_object;
+
+    short m_x;
+    int m_y;
+    short m_width;
+    int m_height;
+    int m_baseline;
+    
+    bool m_firstLine : 1;
+    bool m_constructed : 1;
+
+    InlineBox* m_next; // The next element on the same line as us.
+    InlineBox* m_prev; // The previous element on the same line as us.
+
+    InlineFlowBox* m_parent; // The box that contains us.
+};
+
+class InlineRunBox : public InlineBox
+{
+public:
+    InlineRunBox(RenderObject* obj)
+    :InlineBox(obj)
+    {
+        m_prevLine = 0;
+        m_nextLine = 0;
+    }
+
+    InlineRunBox* prevLineBox() { return m_prevLine; }
+    InlineRunBox* nextLineBox() { return m_nextLine; }
+    void setNextLineBox(InlineRunBox* n) { m_nextLine = n; }
+    void setPreviousLineBox(InlineRunBox* p) { m_prevLine = p; }
+    
+protected:
+    InlineRunBox* m_prevLine;  // The previous box that also uses our RenderObject
+    InlineRunBox* m_nextLine;  // The next box that also uses our RenderObject
+};
+
+class InlineFlowBox : public InlineRunBox
+{
+public:
+    InlineFlowBox(RenderObject* obj)
+    :InlineRunBox(obj)
+    {
+        m_firstChild = 0;
+        m_lastChild = 0;
+        m_includeLeftEdge = m_includeRightEdge = false;
+        m_hasTextChildren = false;
+    }
+
+    virtual bool isInlineFlowBox() { return true; }
+
+    InlineBox* firstChild() { return m_firstChild; }
+    InlineBox* lastChild() { return m_lastChild; }
+    
+    virtual void setConstructed() {
+        InlineBox::setConstructed();
+        if (m_firstChild)
+            m_firstChild->setConstructed();
+    }
+    void addToLine(InlineBox* child) {
+        if (!m_firstChild)
+            m_firstChild = m_lastChild = child;
+        else {
+            m_lastChild->m_next = child;
+            child->m_prev = m_lastChild;
+            m_lastChild = child;
+        }
+        child->setFirstLineStyleBit(m_firstLine);
+        child->setParent(this);
+        if (child->isTextRun())
+            m_hasTextChildren = true;
+    }
+
+    int marginBorderPaddingLeft();
+    int marginBorderPaddingRight();
+    int marginLeft();
+    int marginRight();
+    int borderLeft() { if (includeLeftEdge()) return object()->borderLeft(); return 0; }
+    int borderRight() { if (includeRightEdge()) return object()->borderRight(); return 0; }
+    int paddingLeft() { if (includeLeftEdge()) return object()->paddingLeft(); return 0; }
+    int paddingRight() { if (includeRightEdge()) return object()->paddingRight(); return 0; }
+    
+    bool includeLeftEdge() { return m_includeLeftEdge; }
+    bool includeRightEdge() { return m_includeRightEdge; }
+    void setEdges(bool includeLeft, bool includeRight) {
+        m_includeLeftEdge = includeLeft;
+        m_includeRightEdge = includeRight;
+    }
+    virtual bool hasTextChildren() { return m_hasTextChildren; }
+    
+    // Helper functions used during line construction and placement.
+    void determineSpacingForFlowBoxes(bool lastLine, RenderObject* endObject);
+    int getFlowSpacingWidth();
+    bool nextOnLineExists();
+    bool prevOnLineExists();
+    bool onEndChain(RenderObject* endObject);
+    int placeBoxesHorizontally(int x);
+    void verticallyAlignBoxes(int& heightOfBlock);
+    void computeLogicalBoxHeights(int& maxPositionTop, int& maxPositionBottom,
+                                  int& maxAscent, int& maxDescent, bool strictMode);
+    void adjustMaxAscentAndDescent(int& maxAscent, int& maxDescent,
+                                   int maxPositionTop, int maxPositionBottom);
+    void placeBoxesVertically(int y, int maxHeight, int maxAscent, bool strictMode);
+    
+protected:
+    InlineBox* m_firstChild;
+    InlineBox* m_lastChild;
+    bool m_includeLeftEdge : 1;
+    bool m_includeRightEdge : 1;
+    bool m_hasTextChildren : 1;
+};
+
+}; //namespace
+
+#endif
diff --git a/WebCore/khtml/rendering/render_object.cpp b/WebCore/khtml/rendering/render_object.cpp
index 76bc211..a58b43d 100644
--- a/WebCore/khtml/rendering/render_object.cpp
+++ b/WebCore/khtml/rendering/render_object.cpp
@@ -1382,3 +1382,9 @@ void RenderObject::scheduleRelayout(RenderObject* clippedObj)
 void RenderObject::removeLeftoverAnonymousBoxes()
 {
 }
+
+InlineBox* RenderObject::createInlineBox()
+{
+    return new (renderArena()) InlineBox(this);
+}
+
diff --git a/WebCore/khtml/rendering/render_object.h b/WebCore/khtml/rendering/render_object.h
index 9540581..545c51e 100644
--- a/WebCore/khtml/rendering/render_object.h
+++ b/WebCore/khtml/rendering/render_object.h
@@ -86,6 +86,7 @@ namespace khtml {
     class RenderText;
     class RenderFrameSet;
     class RenderLayer;
+    class InlineBox;
 
 /**
  * Base Class for all rendering tree objects.
@@ -167,6 +168,7 @@ public:
     // some helper functions...
     virtual bool isRenderBlock() const { return false; }
     virtual bool isRenderInline() const { return false; }
+    virtual bool isInlineFlow() const { return isRenderInline() || isRunIn(); }
     virtual bool childrenInline() const { return false; }
     virtual void setChildrenInline(bool b) { };
     virtual RenderFlow* continuation() const { return 0; }
@@ -247,6 +249,8 @@ public:
 
     void scheduleRelayout(RenderObject* clippedObj = 0);
 
+    virtual InlineBox* createInlineBox();
+    
     // for discussion of lineHeight see CSS2 spec
     virtual short lineHeight( bool firstLine ) const;
     // for the vertical-align property of inline elements
@@ -501,7 +505,7 @@ public:
     virtual bool hasOverhangingFloats() { return false; }
 
     // positioning of inline childs (bidi)
-    virtual void position(int, int, int, int, int, bool, bool, int) {}
+    virtual void position(InlineBox*, int, int, int, bool) {}
 
     enum SelectionState {
         SelectionNone,
diff --git a/WebCore/khtml/rendering/render_replaced.cpp b/WebCore/khtml/rendering/render_replaced.cpp
index 49da097..d2c689c 100644
--- a/WebCore/khtml/rendering/render_replaced.cpp
+++ b/WebCore/khtml/rendering/render_replaced.cpp
@@ -107,12 +107,6 @@ short RenderReplaced::baselinePosition( bool ) const
     return height()+marginTop()+marginBottom();
 }
 
-void RenderReplaced::position(int x, int y, int, int, int, bool, bool, int)
-{
-    m_x = x + marginLeft();
-    m_y = y + marginTop();
-}
-
 bool RenderReplaced::canHaveChildren() const
 {
     // We should not really be a RenderContainer subclass.
diff --git a/WebCore/khtml/rendering/render_replaced.h b/WebCore/khtml/rendering/render_replaced.h
index 0634bc2..5c05c58 100644
--- a/WebCore/khtml/rendering/render_replaced.h
+++ b/WebCore/khtml/rendering/render_replaced.h
@@ -52,8 +52,6 @@ public:
     void setIntrinsicWidth(int w) {  m_intrinsicWidth = w; }
     void setIntrinsicHeight(int h) { m_intrinsicHeight = h; }
 
-    virtual void position(int x, int y, int from, int len, int width, bool reverse, bool firstLine, int);
-    
     virtual bool canHaveChildren() const;
 
 private:
diff --git a/WebCore/khtml/rendering/render_table.cpp b/WebCore/khtml/rendering/render_table.cpp
index f06f78d..995fb67 100644
--- a/WebCore/khtml/rendering/render_table.cpp
+++ b/WebCore/khtml/rendering/render_table.cpp
@@ -99,13 +99,6 @@ void RenderTable::setStyle(RenderStyle *_style)
     }
 }
 
-void RenderTable::position(int x, int y, int, int, int, bool, bool, int)
-{
-    //for inline tables only
-    m_x = x + marginLeft();
-    m_y = y + marginTop();
-}
-
 short RenderTable::lineHeight(bool b) const
 {
     // Inline tables are replaced elements. Otherwise, just pass off to
@@ -1173,6 +1166,7 @@ void RenderTableSection::paint( QPainter *p, int x, int y, int w, int h,
 		break;
 	}
     }
+    
     if ( startcol < endcol ) {
 	// draw the cells
 	for ( unsigned int r = startrow; r < endrow; r++ ) {
@@ -1435,8 +1429,7 @@ void RenderTableCell::close()
 
 void RenderTableCell::repaintRectangle(int x, int y, int w, int h, bool immediate, bool f)
 {
-    y += _topExtra;
-    RenderBlock::repaintRectangle(x, y, w, h, immediate, f);
+    RenderBlock::repaintRectangle(x, y, w, h+_topExtra+_bottomExtra, immediate, f);
 }
 
 bool RenderTableCell::absolutePosition(int &xPos, int &yPos, bool f)
@@ -1505,7 +1498,7 @@ void RenderTableCell::paint(QPainter *p, int _x, int _y,
 
     // check if we need to do anything at all...
     if(!overhangingContents() && ((_ty-_topExtra > _y + _h)
-        || (_ty + m_height+_topExtra+_bottomExtra < _y))) return;
+        || (_ty + m_height + _bottomExtra < _y))) return;
 
     paintObject(p, _x, _y, _w, _h, _tx, _ty, paintAction);
 
diff --git a/WebCore/khtml/rendering/render_table.h b/WebCore/khtml/rendering/render_table.h
index 4e07e56..305cf05 100644
--- a/WebCore/khtml/rendering/render_table.h
+++ b/WebCore/khtml/rendering/render_table.h
@@ -108,8 +108,6 @@ public:
 
     virtual void setCellWidths( );
 
-    virtual void position(int x, int y, int from, int len, int width, bool reverse, bool firstLine, int);
-
     virtual void calcWidth();
 
     virtual int borderTopExtra();
diff --git a/WebCore/khtml/rendering/render_text.cpp b/WebCore/khtml/rendering/render_text.cpp
index 29313eb..2aa5394 100644
--- a/WebCore/khtml/rendering/render_text.cpp
+++ b/WebCore/khtml/rendering/render_text.cpp
@@ -158,7 +158,7 @@ void TextRun::paintBoxDecorations(QPainter *pt, RenderStyle* style, RenderText *
     _tx += m_x;
     _ty += m_y + halfleading - topExtra;
 
-    int width = m_width;
+    int width = m_width + p->borderLeft() + p->borderRight() + p->paddingLeft() + p->paddingRight();
 
     // the height of the decorations is:  topBorder + topPadding + CSS font-size + bottomPadding + bottomBorder
     int height = style->font().pixelSize() + topExtra + bottomExtra;
@@ -450,11 +450,7 @@ bool RenderText::nodeAtPoint(NodeInfo& info, int _x, int _y, int _tx, int _ty, b
 {
     assert(parent());
 
-    _tx -= paddingLeft() + borderLeft();
-    _ty -= borderTop() + paddingTop();
-
-    int height = m_lineHeight + borderTop() + paddingTop() +
-                 borderBottom() + paddingBottom();
+    int height = m_lineHeight;
 
     TextRun *s = m_lines.count() ? m_lines[0] : 0;
     int si = 0;
@@ -716,7 +712,6 @@ void RenderText::paintObject(QPainter *p, int /*x*/, int y, int /*w*/, int h,
                (!pseudoStyle || s->m_firstLine))
                 s->paintBoxDecorations(p, _style, this, tx, ty, si == 0, si == (int)m_lines.count()-1);
 
-
 #if APPLE_CHANGES
             if (drawText) {
 #endif
@@ -1171,8 +1166,9 @@ int RenderText::height() const
     else
         retval = metrics( false ).height();
 
-    retval += paddingTop() + paddingBottom() + borderTop() + borderBottom();
-
+    // FIXME: Totally bogus.
+    retval += borderTop() + paddingTop() + borderBottom() + paddingBottom();
+    
     return retval;
 }
 
@@ -1191,7 +1187,13 @@ short RenderText::baselinePosition( bool firstLine ) const
         ( lineHeight( firstLine ) - fm.height() ) / 2;
 }
 
-void RenderText::position(int x, int y, int from, int len, int width, bool reverse, bool firstLine, int spaceAdd)
+InlineBox* RenderText::createInlineBox()
+{
+    // FIXME: Either ditch the array or get this object into it.
+    return new (renderArena()) TextRun(this);
+}
+
+void RenderText::position(InlineBox* box, int y, int from, int len, bool reverse)
 {
     // ### should not be needed!!!
     if (len == 0 || (str->l && len == 1 && *(str->s+from) == '\n'))
@@ -1199,26 +1201,19 @@ void RenderText::position(int x, int y, int from, int len, int width, bool rever
 
     reverse = reverse && !style()->visuallyOrdered();
 
-    // ### margins and RTL
-    if(from == 0 && parent()->isInline() && parent()->firstChild()==this)
-    {
-        x += paddingLeft() + borderLeft() + marginLeft();
-        width -= marginLeft();
-    }
-
-    if(from + len >= int(str->l) && parent()->isInline() && parent()->lastChild()==this)
-        width -= marginRight();
-
 #ifdef DEBUG_LAYOUT
     QChar *ch = str->s+from;
     QConstString cstr(ch, len);
     qDebug("setting run text to *%s*, len=%d, w)=%d" , cstr.string().latin1(), len, width );//" << y << ")" << " height=" << lineHeight(false) << " fontHeight=" << metrics(false).height() << " ascent =" << metrics(false).ascent() << endl;
 #endif
 
-    TextRun *s = new (renderArena()) TextRun(x, y, from, len,
-                                 baselinePosition( firstLine ),
-                                 width+spaceAdd, reverse, spaceAdd, firstLine);
-
+    TextRun *s = static_cast<TextRun*>(box);
+    s->m_reversed = reverse;
+    s->m_y = y;
+    s->m_start = from;
+    s->m_len = len;
+    s->m_baseline = baselinePosition(s->m_firstLine);
+    
     if(m_lines.count() == m_lines.size())
         m_lines.resize(m_lines.size()*2+1);
 
@@ -1249,17 +1244,6 @@ unsigned int RenderText::width(unsigned int from, unsigned int len, const Font *
     else
 	w = f->width(str->s, str->l, from, len );
 
-    // ### add margins and support for RTL
-
-    if(parent()->isInline())
-    {
-        if(from == 0 && parent()->firstChild() == static_cast<const RenderObject*>(this))
-            w += borderLeft() + paddingLeft() + marginLeft();
-        if(from + len == str->l &&
-           parent()->lastChild() == static_cast<const RenderObject*>(this))
-            w += borderRight() + paddingRight() +marginRight();
-    }
-
     //kdDebug( 6040 ) << "RenderText::width(" << from << ", " << len << ") = " << w << endl;
     return w;
 }
@@ -1280,14 +1264,6 @@ short RenderText::width() const
 
     w = QMAX(0, maxx-minx);
 
-    if(parent()->isInline())
-    {
-        if(parent()->firstChild() == static_cast<const RenderObject*>(this))
-            w += borderLeft() + paddingLeft();
-        if(parent()->lastChild() == static_cast<const RenderObject*>(this))
-            w += borderRight() + paddingRight();
-    }
-
     return w;
 }
 
@@ -1310,12 +1286,7 @@ short RenderText::verticalPositionHint( bool firstLine ) const
 
 const QFontMetrics &RenderText::metrics(bool firstLine) const
 {
-    if( firstLine && hasFirstLine() ) {
-	RenderStyle *pseudoStyle  = style()->getPseudoStyle(RenderStyle::FIRST_LINE);
-	if ( pseudoStyle )
-	    return pseudoStyle->fontMetrics();
-    }
-    return style()->fontMetrics();
+    return style(firstLine)->fontMetrics();
 }
 
 const Font *RenderText::htmlFont(bool firstLine) const
diff --git a/WebCore/khtml/rendering/render_text.h b/WebCore/khtml/rendering/render_text.h
index 881bfad..da2699e 100644
--- a/WebCore/khtml/rendering/render_text.h
+++ b/WebCore/khtml/rendering/render_text.h
@@ -28,6 +28,7 @@
 #include "xml/dom_stringimpl.h"
 #include "xml/dom_textimpl.h"
 #include "rendering/render_object.h"
+#include "rendering/render_flow.h"
 
 #include <qptrvector.h>
 #include <assert.h>
@@ -40,22 +41,17 @@ namespace khtml
     class RenderText;
     class RenderStyle;
 
-class TextRun
+class TextRun : public InlineBox
 {
 public:
-    TextRun(int x, int y, int start, int len,
-	      int baseline, int width,
-              bool reversed = false, int toAdd = 0, bool firstLine = false)
+    TextRun(RenderObject* obj)
+    :InlineBox(obj)
     {
-        m_x = x;
-        m_y = y;
-        m_start = start;
-        m_len = len;
-        m_baseline = baseline;
-        m_width = width;
-        m_reversed = reversed;
-        m_firstLine = firstLine;
-        m_toAdd = toAdd;
+        m_start = 0;
+        m_len = 0;
+        m_baseline = 0;
+        m_reversed = false;
+        m_toAdd = 0;
     }
     
     void detach(RenderArena* renderArena);
@@ -72,7 +68,11 @@ private:
     void* operator new(size_t sz) throw();
 
 public:
+    void setSpaceAdd(int add) { m_width -= m_toAdd; m_toAdd = add; m_width += m_toAdd; }
+    int spaceAdd() { return m_toAdd; }
 
+    virtual bool isTextRun() { return true; }
+    
 #ifdef APPLE_CHANGES
     void paintDecoration( QPainter *pt, const Font *, RenderText* p,
                           int _tx, int _ty, int decoration, bool begin, bool end, int from=-1, int to=-1);
@@ -94,18 +94,15 @@ public:
     { if((_ty + m_y > _y + _h) || (_ty + m_y + m_baseline + height < _y)) return false; return true; }
 
     int m_start;
-    int m_y;
     unsigned short m_len;
-    short m_x;
     unsigned short m_baseline;
-    unsigned short m_width;
-
+    
     bool m_reversed : 1;
-    bool m_firstLine : 1;
     int m_toAdd : 14; // for justified text
 private:
     // this is just for QVector::bsearch. Don't use it otherwise
     TextRun(int _x, int _y)
+        :InlineBox(0)
     {
         m_x = _x;
         m_y = _y;
@@ -148,6 +145,8 @@ public:
     DOM::DOMString data() const { return str; }
     DOM::DOMStringImpl *string() const { return str; }
 
+    virtual InlineBox* createInlineBox();
+    
     virtual void layout() {assert(false);}
 
     virtual bool nodeAtPoint(NodeInfo& info, int x, int y, int tx, int ty, bool inside = false);
@@ -159,7 +158,7 @@ public:
     unsigned int length() const { return str->l; }
     QChar *text() const { return str->s; }
     unsigned int stringLength() const { return str->l; } // non virtual implementation of length()
-    virtual void position(int x, int y, int from, int len, int width, bool reverse, bool firstLine, int spaceAdd);
+    virtual void position(InlineBox* box, int y, int from, int len, bool reverse);
 
     virtual unsigned int width(unsigned int from, unsigned int len, const Font *f) const;
     virtual unsigned int width(unsigned int from, unsigned int len, bool firstLine = false) const;
diff --git a/WebCore/khtml/xml/dom_docimpl.h b/WebCore/khtml/xml/dom_docimpl.h
index 553bbff..5badb0d 100644
--- a/WebCore/khtml/xml/dom_docimpl.h
+++ b/WebCore/khtml/xml/dom_docimpl.h
@@ -298,6 +298,8 @@ public:
     ParseMode parseMode() const { return pMode; }
 
     bool inQuirksMode() { return pMode == Compat; }
+    bool inAlmostStrictMode() { return pMode == AlmostStrict; }
+    bool inStrictMode() { return pMode == Strict; }
     
     void setHTMLMode( HTMLMode m ) { hMode = m; }
     HTMLMode htmlMode() const { return hMode; }

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list