[SCM] WebKit Debian packaging branch, debian/unstable, updated. debian/1.1.15-1-40151-g37bb677

hyatt hyatt at 268f45cc-cd09-0410-ab3c-d52691b4dbfc
Sat Sep 26 08:23:34 UTC 2009


The following commit has been merged in the debian/unstable branch:
commit ab855d81cdd3465bdfd6e085841d005ee1ef2c0a
Author: hyatt <hyatt at 268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Mon Jan 26 19:24:20 2004 +0000

    	Preserve the integrity of the line box tree when elements get removed.  Change RenderText over to using
    	the same data structures as inlines and blocks for maintaining its list of line boxes.
    
            Reviewed by kocienda
    
            * khtml/khtml_part.cpp:
            (KHTMLPart::text):
            (KHTMLPart::customEvent):
            * khtml/khtml_selection.cpp:
            (KHTMLSelection::nextCharacterPosition):
            (firstRunAt):
            (lastRunAt):
            * khtml/rendering/bidi.cpp:
            (khtml::RenderBlock::layoutInlineChildren):
            * khtml/rendering/render_block.cpp:
            (khtml::RenderBlock::removeChild):
            * khtml/rendering/render_box.cpp:
            (RenderBox::RenderBox):
            (RenderBox::detach):
            (RenderBox::position):
            (RenderBox::inlineBoxWrapper):
            (RenderBox::deleteLineBoxWrapper):
            * khtml/rendering/render_box.h:
            * khtml/rendering/render_container.cpp:
            (RenderContainer::removeChildNode):
            * khtml/rendering/render_flow.cpp:
            (RenderFlow::detach):
            * khtml/rendering/render_line.cpp:
            (InlineFlowBox::removeChild):
            * khtml/rendering/render_line.h:
            (khtml::InlineBox::nextOnLine):
            (khtml::InlineBox::prevOnLine):
            (khtml::InlineBox::setNextOnLine):
            (khtml::InlineBox::setPrevOnLine):
            (khtml::InlineRunBox::prevLineBox):
            (khtml::InlineRunBox::nextLineBox):
            * khtml/rendering/render_object.cpp:
            (RenderObject::isEditable):
            (RenderObject::inlineBoxWrapper):
            (RenderObject::deleteLineBoxWrapper):
            * khtml/rendering/render_object.h:
            (khtml::RenderObject::documentBeingDestroyed):
            * khtml/rendering/render_text.cpp:
            (RenderText::RenderText):
            (RenderText::detach):
            (RenderText::deleteTextBoxes):
            (RenderText::absoluteRects):
            (RenderText::findNextInlineTextBox):
            (RenderText::nodeAtPoint):
            (RenderText::checkSelectionPointIgnoringContinuations):
            (RenderText::caretPos):
            (RenderText::paintObject):
            (RenderText::paint):
            (RenderText::minXPos):
            (RenderText::xPos):
            (RenderText::yPos):
            (RenderText::height):
            (RenderText::createInlineBox):
            (RenderText::position):
            (RenderText::width):
            (RenderText::caretMinOffset):
            (RenderText::caretMaxOffset):
            * khtml/rendering/render_text.h:
            (khtml::InlineTextBox:::InlineRunBox):
            (khtml::InlineTextBox::nextTextBox):
            (khtml::InlineTextBox::prevTextBox):
            (khtml::RenderText::firstTextBox):
            (khtml::RenderText::lastTextBox):
            * kwq/KWQAccObject.mm:
            (-[KWQAccObject accessibilityIsIgnored]):
            * kwq/KWQDef.h:
            * kwq/KWQKHTMLPart.mm:
            (KWQKHTMLPart::attributedString):
            * kwq/KWQRenderTreeDebug.cpp:
            (write):
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@5974 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/WebCore/ChangeLog-2005-08-23 b/WebCore/ChangeLog-2005-08-23
index de68b6f..b51bb3e 100644
--- a/WebCore/ChangeLog-2005-08-23
+++ b/WebCore/ChangeLog-2005-08-23
@@ -1,3 +1,81 @@
+2004-01-26  David Hyatt  <hyatt at apple.com>
+
+	Preserve the integrity of the line box tree when elements get removed.  Change RenderText over to using
+	the same data structures as inlines and blocks for maintaining its list of line boxes.
+	
+        Reviewed by kocienda
+
+        * khtml/khtml_part.cpp:
+        (KHTMLPart::text):
+        (KHTMLPart::customEvent):
+        * khtml/khtml_selection.cpp:
+        (KHTMLSelection::nextCharacterPosition):
+        (firstRunAt):
+        (lastRunAt):
+        * khtml/rendering/bidi.cpp:
+        (khtml::RenderBlock::layoutInlineChildren):
+        * khtml/rendering/render_block.cpp:
+        (khtml::RenderBlock::removeChild):
+        * khtml/rendering/render_box.cpp:
+        (RenderBox::RenderBox):
+        (RenderBox::detach):
+        (RenderBox::position):
+        (RenderBox::inlineBoxWrapper):
+        (RenderBox::deleteLineBoxWrapper):
+        * khtml/rendering/render_box.h:
+        * khtml/rendering/render_container.cpp:
+        (RenderContainer::removeChildNode):
+        * khtml/rendering/render_flow.cpp:
+        (RenderFlow::detach):
+        * khtml/rendering/render_line.cpp:
+        (InlineFlowBox::removeChild):
+        * khtml/rendering/render_line.h:
+        (khtml::InlineBox::nextOnLine):
+        (khtml::InlineBox::prevOnLine):
+        (khtml::InlineBox::setNextOnLine):
+        (khtml::InlineBox::setPrevOnLine):
+        (khtml::InlineRunBox::prevLineBox):
+        (khtml::InlineRunBox::nextLineBox):
+        * khtml/rendering/render_object.cpp:
+        (RenderObject::isEditable):
+        (RenderObject::inlineBoxWrapper):
+        (RenderObject::deleteLineBoxWrapper):
+        * khtml/rendering/render_object.h:
+        (khtml::RenderObject::documentBeingDestroyed):
+        * khtml/rendering/render_text.cpp:
+        (RenderText::RenderText):
+        (RenderText::detach):
+        (RenderText::deleteTextBoxes):
+        (RenderText::absoluteRects):
+        (RenderText::findNextInlineTextBox):
+        (RenderText::nodeAtPoint):
+        (RenderText::checkSelectionPointIgnoringContinuations):
+        (RenderText::caretPos):
+        (RenderText::paintObject):
+        (RenderText::paint):
+        (RenderText::minXPos):
+        (RenderText::xPos):
+        (RenderText::yPos):
+        (RenderText::height):
+        (RenderText::createInlineBox):
+        (RenderText::position):
+        (RenderText::width):
+        (RenderText::caretMinOffset):
+        (RenderText::caretMaxOffset):
+        * khtml/rendering/render_text.h:
+        (khtml::InlineTextBox:::InlineRunBox):
+        (khtml::InlineTextBox::nextTextBox):
+        (khtml::InlineTextBox::prevTextBox):
+        (khtml::RenderText::firstTextBox):
+        (khtml::RenderText::lastTextBox):
+        * kwq/KWQAccObject.mm:
+        (-[KWQAccObject accessibilityIsIgnored]):
+        * kwq/KWQDef.h:
+        * kwq/KWQKHTMLPart.mm:
+        (KWQKHTMLPart::attributedString):
+        * kwq/KWQRenderTreeDebug.cpp:
+        (write):
+
 2004-01-24  David Hyatt  <hyatt at apple.com>
 
 	Polish the error message from the xml tokenizer.
diff --git a/WebCore/khtml/editing/SelectionController.cpp b/WebCore/khtml/editing/SelectionController.cpp
index e4e9cfa..f54e555 100644
--- a/WebCore/khtml/editing/SelectionController.cpp
+++ b/WebCore/khtml/editing/SelectionController.cpp
@@ -54,7 +54,6 @@ using DOM::NodeImpl;
 using DOM::Range;
 using DOM::TextImpl;
 using khtml::InlineTextBox;
-using khtml::InlineTextBoxArray;
 using khtml::RenderObject;
 using khtml::RenderText;
 
@@ -601,18 +600,16 @@ DOMPosition KHTMLSelection::nextCharacterPosition()
     RenderObject *renderer = node->renderer();
     if (renderer->isText()) {
         RenderText *textRenderer = static_cast<khtml::RenderText *>(renderer);
-        InlineTextBoxArray runs = textRenderer->inlineTextBoxes();
-        unsigned i = 0;
-        for (i = 0; i < runs.count(); i++) {
-            long start = runs[i]->m_start;
-            long end = runs[i]->m_start + runs[i]->m_len;
+        for (InlineTextBox* box = textRenderer->firstTextBox(); box; box = box->nextTextBox()) {
+            long start = box->m_start;
+            long end = box->m_start + box->m_len;
             if (desiredOffset > end) {
                 // Skip this node.
                 // It is too early in the text runs to be involved.
                 continue;
             }
             else if (desiredOffset >= start && 
-                (desiredOffset < end || (desiredOffset == end && i + 1 == runs.count() && !renderer->nextEditable())) ||
+                (desiredOffset < end || (desiredOffset == end && !box->nextTextBox() && !renderer->nextEditable())) ||
                 (desiredOffset == end && textRenderer->precedesLineBreak() && !textRenderer->followsLineBreak())) {
                 // Desired offset is in this node.
                 // Either it is:
@@ -641,9 +638,8 @@ DOMPosition KHTMLSelection::nextCharacterPosition()
     while (renderer) {
         if (renderer->isText()) {
             RenderText *textRenderer = static_cast<khtml::RenderText *>(renderer);
-            InlineTextBoxArray runs = textRenderer->inlineTextBoxes();
-            if (runs.count())
-                return DOMPosition(renderer->element(), runs[0]->m_start);
+            if (textRenderer->firstTextBox())
+                return DOMPosition(renderer->element(), textRenderer->firstTextBox()->m_start);
         }
         else {
             return DOMPosition(renderer->element(), renderer->caretMinOffset());
@@ -764,11 +760,10 @@ static bool firstRunAt(RenderObject *renderNode, int y, NodeImpl *&startNode, lo
     for (RenderObject *n = renderNode; n; n = n->nextSibling()) {
         if (n->isText()) {
             RenderText *textRenderer = static_cast<khtml::RenderText *>(n);
-            InlineTextBoxArray runs = textRenderer->inlineTextBoxes();
-            for (unsigned i = 0; i != runs.count(); i++) {
-                if (runs[i]->m_y == y) {
+            for (InlineTextBox* box = textRenderer->firstTextBox(); box; box = box->nextTextBox()) {
+                if (box->m_y == y) {
                     startNode = textRenderer->element();
-                    startOffset = runs[i]->m_start;
+                    startOffset = box->m_start;
                     return true;
                 }
             }
@@ -800,11 +795,10 @@ static bool lastRunAt(RenderObject *renderNode, int y, NodeImpl *&endNode, long
     
         if (n->isText()) {
             RenderText *textRenderer =  static_cast<khtml::RenderText *>(n);
-            InlineTextBoxArray runs = textRenderer->inlineTextBoxes();
-            for (int i = (int)runs.count()-1; i >= 0; i--) {
-                if (runs[i]->m_y == y) {
+            for (InlineTextBox* box = textRenderer->lastTextBox(); box; box = box->prevTextBox()) {
+                if (box->m_y == y) {
                     endNode = textRenderer->element();
-                    endOffset = runs[i]->m_start + runs[i]->m_len;
+                    endOffset = box->m_start + box->m_len;
                     return true;
                 }
             }
diff --git a/WebCore/khtml/editing/selection.cpp b/WebCore/khtml/editing/selection.cpp
index e4e9cfa..f54e555 100644
--- a/WebCore/khtml/editing/selection.cpp
+++ b/WebCore/khtml/editing/selection.cpp
@@ -54,7 +54,6 @@ using DOM::NodeImpl;
 using DOM::Range;
 using DOM::TextImpl;
 using khtml::InlineTextBox;
-using khtml::InlineTextBoxArray;
 using khtml::RenderObject;
 using khtml::RenderText;
 
@@ -601,18 +600,16 @@ DOMPosition KHTMLSelection::nextCharacterPosition()
     RenderObject *renderer = node->renderer();
     if (renderer->isText()) {
         RenderText *textRenderer = static_cast<khtml::RenderText *>(renderer);
-        InlineTextBoxArray runs = textRenderer->inlineTextBoxes();
-        unsigned i = 0;
-        for (i = 0; i < runs.count(); i++) {
-            long start = runs[i]->m_start;
-            long end = runs[i]->m_start + runs[i]->m_len;
+        for (InlineTextBox* box = textRenderer->firstTextBox(); box; box = box->nextTextBox()) {
+            long start = box->m_start;
+            long end = box->m_start + box->m_len;
             if (desiredOffset > end) {
                 // Skip this node.
                 // It is too early in the text runs to be involved.
                 continue;
             }
             else if (desiredOffset >= start && 
-                (desiredOffset < end || (desiredOffset == end && i + 1 == runs.count() && !renderer->nextEditable())) ||
+                (desiredOffset < end || (desiredOffset == end && !box->nextTextBox() && !renderer->nextEditable())) ||
                 (desiredOffset == end && textRenderer->precedesLineBreak() && !textRenderer->followsLineBreak())) {
                 // Desired offset is in this node.
                 // Either it is:
@@ -641,9 +638,8 @@ DOMPosition KHTMLSelection::nextCharacterPosition()
     while (renderer) {
         if (renderer->isText()) {
             RenderText *textRenderer = static_cast<khtml::RenderText *>(renderer);
-            InlineTextBoxArray runs = textRenderer->inlineTextBoxes();
-            if (runs.count())
-                return DOMPosition(renderer->element(), runs[0]->m_start);
+            if (textRenderer->firstTextBox())
+                return DOMPosition(renderer->element(), textRenderer->firstTextBox()->m_start);
         }
         else {
             return DOMPosition(renderer->element(), renderer->caretMinOffset());
@@ -764,11 +760,10 @@ static bool firstRunAt(RenderObject *renderNode, int y, NodeImpl *&startNode, lo
     for (RenderObject *n = renderNode; n; n = n->nextSibling()) {
         if (n->isText()) {
             RenderText *textRenderer = static_cast<khtml::RenderText *>(n);
-            InlineTextBoxArray runs = textRenderer->inlineTextBoxes();
-            for (unsigned i = 0; i != runs.count(); i++) {
-                if (runs[i]->m_y == y) {
+            for (InlineTextBox* box = textRenderer->firstTextBox(); box; box = box->nextTextBox()) {
+                if (box->m_y == y) {
                     startNode = textRenderer->element();
-                    startOffset = runs[i]->m_start;
+                    startOffset = box->m_start;
                     return true;
                 }
             }
@@ -800,11 +795,10 @@ static bool lastRunAt(RenderObject *renderNode, int y, NodeImpl *&endNode, long
     
         if (n->isText()) {
             RenderText *textRenderer =  static_cast<khtml::RenderText *>(n);
-            InlineTextBoxArray runs = textRenderer->inlineTextBoxes();
-            for (int i = (int)runs.count()-1; i >= 0; i--) {
-                if (runs[i]->m_y == y) {
+            for (InlineTextBox* box = textRenderer->lastTextBox(); box; box = box->prevTextBox()) {
+                if (box->m_y == y) {
                     endNode = textRenderer->element();
-                    endOffset = runs[i]->m_start + runs[i]->m_len;
+                    endOffset = box->m_start + box->m_len;
                     return true;
                 }
             }
diff --git a/WebCore/khtml/khtml_part.cpp b/WebCore/khtml/khtml_part.cpp
index f1dfe64..512e41f 100644
--- a/WebCore/khtml/khtml_part.cpp
+++ b/WebCore/khtml/khtml_part.cpp
@@ -100,7 +100,7 @@ using namespace DOM;
 using khtml::Decoder;
 using khtml::RenderObject;
 using khtml::RenderText;
-using khtml::InlineTextBoxArray;
+using khtml::InlineTextBox;
 
 using KParts::BrowserInterface;
 
@@ -2310,27 +2310,26 @@ QString KHTMLPart::text(const DOM::Range &r) const
               }
               else {
                   RenderText* textObj = static_cast<RenderText*>(n.handle()->renderer());
-                  InlineTextBoxArray runs = textObj->inlineTextBoxes();
-                  if (runs.count() == 0 && str.length() > 0) {
+                  if (!textObj->firstTextBox() && str.length() > 0) {
                       // We have no runs, but we do have a length.  This means we must be
                       // whitespace that collapsed away at the end of a line.
                       needSpace = true;
                   }
                   else {
-                      for (unsigned i = 0; i < runs.count(); i++) {
-                          int runStart = (start == -1) ? runs[i]->m_start : start;
-                          int runEnd = (end == -1) ? runs[i]->m_start + runs[i]->m_len : end;
-                          runEnd = QMIN(runEnd, runs[i]->m_start + runs[i]->m_len);
-                          if (runStart >= runs[i]->m_start &&
-                              runStart < runs[i]->m_start + runs[i]->m_len) {
-                              if (i == 0 && runs[0]->m_start == runStart && runStart > 0)
+                      for (InlineTextBox* box = textObj->firstTextBox(); box; box = box->nextTextBox()) {
+                          int runStart = (start == -1) ? box->m_start : start;
+                          int runEnd = (end == -1) ? box->m_start + box->m_len : end;
+                          runEnd = QMIN(runEnd, box->m_start + box->m_len);
+                          if (runStart >= box->m_start &&
+                              runStart < box->m_start + box->m_len) {
+                              if (box == textObj->firstTextBox() && box->m_start == runStart && runStart > 0)
                                   needSpace = true; // collapsed space at the start
                               if (needSpace && !addedSpace)
                                   text += ' ';
                               QString runText = str.mid(runStart, runEnd - runStart);
                               runText.replace('\n', ' ');
                               text += runText;
-                              int nextRunStart = (i+1 < runs.count()) ? runs[i+1]->m_start : str.length();
+                              int nextRunStart = box->nextTextBox() ? box->nextTextBox()->m_start : str.length(); // collapsed space between runs or at the end
                               needSpace = nextRunStart > runEnd; // collapsed space between runs or at the end
                               addedSpace = str[runEnd-1].direction() == QChar::DirWS;
                               start = -1;
@@ -4340,112 +4339,6 @@ void KHTMLPart::customEvent( QCustomEvent *event )
   KParts::ReadOnlyPart::customEvent( event );
 }
 
-#if 0
-
-static bool firstRunAt(RenderObject *renderNode, int y, NodeImpl *&startNode, long &startOffset)
-{
-    for (RenderObject *n = renderNode; n; n = n->nextSibling()) {
-        if (n->isText()) {
-            RenderText *textRenderer = static_cast<khtml::RenderText *>(n);
-            InlineTextBoxArray runs = textRenderer->inlineTextBoxes();
-            for (unsigned i = 0; i != runs.count(); i++) {
-                if (runs[i]->m_y == y) {
-                    startNode = textRenderer->element();
-                    startOffset = runs[i]->m_start;
-                    return true;
-                }
-            }
-        }
-        
-        if (firstRunAt(n->firstChild(), y, startNode, startOffset)) {
-            return true;
-        }
-    }
-    
-    return false;
-}
-
-static bool lastRunAt(RenderObject *renderNode, int y, NodeImpl *&endNode, long &endOffset)
-{
-    RenderObject *n = renderNode;
-    if (!n) {
-        return false;
-    }
-    RenderObject *next;
-    while ((next = n->nextSibling())) {
-        n = next;
-    }
-    
-    while (1) {
-        if (lastRunAt(n->firstChild(), y, endNode, endOffset)) {
-            return true;
-        }
-    
-        if (n->isText()) {
-            RenderText *textRenderer =  static_cast<khtml::RenderText *>(n);
-            InlineTextBoxArray runs = textRenderer->inlineTextBoxes();
-            for (int i = (int)runs.count()-1; i >= 0; i--) {
-                if (runs[i]->m_y == y) {
-                    endNode = textRenderer->element();
-                    endOffset = runs[i]->m_start + runs[i]->m_len;
-                    return true;
-                }
-            }
-        }
-        
-        if (n == renderNode) {
-            return false;
-        }
-        
-        n = n->previousSibling();
-    }
-}
-
-static bool startAndEndLineNodesIncludingNode(DOM::NodeImpl *node, int offset, KHTMLSelection &selection)
-{
-    if (node && (node->nodeType() == Node::TEXT_NODE || node->nodeType() == Node::CDATA_SECTION_NODE)){
-        int pos;
-        int selectionPointY;
-        khtml::RenderText *renderer = static_cast<khtml::RenderText *>(node->renderer());
-        khtml::InlineTextBox * run = renderer->findNextInlineTextBox( offset, pos );
-        DOMString t = node->nodeValue();
-        
-        if (!run)
-            return false;
-            
-        selectionPointY = run->m_y;
-        
-        // Go up to first non-inline element.
-        khtml::RenderObject *renderNode = renderer;
-        while (renderNode && renderNode->isInline())
-            renderNode = renderNode->parent();
-        
-        renderNode = renderNode->firstChild();
-        
-        DOM::NodeImpl *startNode = 0;
-        DOM::NodeImpl *endNode = 0;
-        long startOffset;
-        long endOffset;
-        
-        // Look for all the first child in the block that is on the same line
-        // as the selection point.
-        if (!firstRunAt (renderNode, selectionPointY, startNode, startOffset))
-            return false;
-    
-        // Look for all the last child in the block that is on the same line
-        // as the selection point.
-        if (!lastRunAt (renderNode, selectionPointY, endNode, endOffset))
-            return false;
-        
-        selection.setSelection(startNode, startOffset, endNode, endOffset);
-        
-        return true;
-    }
-    return false;
-}
-
-#endif
-
 bool KHTMLPart::isPointInsideSelection(int x, int y)
 {
     // Treat an empty selection like no selection.
diff --git a/WebCore/khtml/khtml_selection.cpp b/WebCore/khtml/khtml_selection.cpp
index e4e9cfa..f54e555 100644
--- a/WebCore/khtml/khtml_selection.cpp
+++ b/WebCore/khtml/khtml_selection.cpp
@@ -54,7 +54,6 @@ using DOM::NodeImpl;
 using DOM::Range;
 using DOM::TextImpl;
 using khtml::InlineTextBox;
-using khtml::InlineTextBoxArray;
 using khtml::RenderObject;
 using khtml::RenderText;
 
@@ -601,18 +600,16 @@ DOMPosition KHTMLSelection::nextCharacterPosition()
     RenderObject *renderer = node->renderer();
     if (renderer->isText()) {
         RenderText *textRenderer = static_cast<khtml::RenderText *>(renderer);
-        InlineTextBoxArray runs = textRenderer->inlineTextBoxes();
-        unsigned i = 0;
-        for (i = 0; i < runs.count(); i++) {
-            long start = runs[i]->m_start;
-            long end = runs[i]->m_start + runs[i]->m_len;
+        for (InlineTextBox* box = textRenderer->firstTextBox(); box; box = box->nextTextBox()) {
+            long start = box->m_start;
+            long end = box->m_start + box->m_len;
             if (desiredOffset > end) {
                 // Skip this node.
                 // It is too early in the text runs to be involved.
                 continue;
             }
             else if (desiredOffset >= start && 
-                (desiredOffset < end || (desiredOffset == end && i + 1 == runs.count() && !renderer->nextEditable())) ||
+                (desiredOffset < end || (desiredOffset == end && !box->nextTextBox() && !renderer->nextEditable())) ||
                 (desiredOffset == end && textRenderer->precedesLineBreak() && !textRenderer->followsLineBreak())) {
                 // Desired offset is in this node.
                 // Either it is:
@@ -641,9 +638,8 @@ DOMPosition KHTMLSelection::nextCharacterPosition()
     while (renderer) {
         if (renderer->isText()) {
             RenderText *textRenderer = static_cast<khtml::RenderText *>(renderer);
-            InlineTextBoxArray runs = textRenderer->inlineTextBoxes();
-            if (runs.count())
-                return DOMPosition(renderer->element(), runs[0]->m_start);
+            if (textRenderer->firstTextBox())
+                return DOMPosition(renderer->element(), textRenderer->firstTextBox()->m_start);
         }
         else {
             return DOMPosition(renderer->element(), renderer->caretMinOffset());
@@ -764,11 +760,10 @@ static bool firstRunAt(RenderObject *renderNode, int y, NodeImpl *&startNode, lo
     for (RenderObject *n = renderNode; n; n = n->nextSibling()) {
         if (n->isText()) {
             RenderText *textRenderer = static_cast<khtml::RenderText *>(n);
-            InlineTextBoxArray runs = textRenderer->inlineTextBoxes();
-            for (unsigned i = 0; i != runs.count(); i++) {
-                if (runs[i]->m_y == y) {
+            for (InlineTextBox* box = textRenderer->firstTextBox(); box; box = box->nextTextBox()) {
+                if (box->m_y == y) {
                     startNode = textRenderer->element();
-                    startOffset = runs[i]->m_start;
+                    startOffset = box->m_start;
                     return true;
                 }
             }
@@ -800,11 +795,10 @@ static bool lastRunAt(RenderObject *renderNode, int y, NodeImpl *&endNode, long
     
         if (n->isText()) {
             RenderText *textRenderer =  static_cast<khtml::RenderText *>(n);
-            InlineTextBoxArray runs = textRenderer->inlineTextBoxes();
-            for (int i = (int)runs.count()-1; i >= 0; i--) {
-                if (runs[i]->m_y == y) {
+            for (InlineTextBox* box = textRenderer->lastTextBox(); box; box = box->prevTextBox()) {
+                if (box->m_y == y) {
                     endNode = textRenderer->element();
-                    endOffset = runs[i]->m_start + runs[i]->m_len;
+                    endOffset = box->m_start + box->m_len;
                     return true;
                 }
             }
diff --git a/WebCore/khtml/rendering/bidi.cpp b/WebCore/khtml/rendering/bidi.cpp
index cfee729..bcda8d5 100644
--- a/WebCore/khtml/rendering/bidi.cpp
+++ b/WebCore/khtml/rendering/bidi.cpp
@@ -1311,9 +1311,12 @@ void RenderBlock::layoutInlineChildren(bool relayoutChildren)
                     o->containingBlock()->insertPositionedObject(o);
                 else
                     o->layoutIfNeeded();
+                
+                if (o->isReplaced())
+                    o->deleteLineBoxWrapper();
             }
-            else if(o->isText()) { // FIXME: Should be able to combine deleteLineBoxes/Runs
-                static_cast<RenderText *>(o)->deleteRuns();
+            else if(o->isText()) {
+                static_cast<RenderText *>(o)->deleteTextBoxes();
 #ifdef INCREMENTAL_REPAINTING
                 o->setNeedsLayout(false);
 #endif
diff --git a/WebCore/khtml/rendering/render_block.cpp b/WebCore/khtml/rendering/render_block.cpp
index fbdfe0a..a6b09d5 100644
--- a/WebCore/khtml/rendering/render_block.cpp
+++ b/WebCore/khtml/rendering/render_block.cpp
@@ -261,7 +261,7 @@ void RenderBlock::removeChild(RenderObject *oldChild)
     RenderObject* prev = oldChild->previousSibling();
     RenderObject* next = oldChild->nextSibling();
     bool mergedBlocks = false;
-    if (document()->renderer() && !isInline() && !oldChild->isInline() && !oldChild->continuation() &&
+    if (!documentBeingDestroyed() && !isInline() && !oldChild->isInline() && !oldChild->continuation() &&
         prev && prev->isAnonymous() && prev->childrenInline() &&
         next && next->isAnonymous() && next->childrenInline()) {
         // Take all the children out of the |next| block and put them in
diff --git a/WebCore/khtml/rendering/render_box.cpp b/WebCore/khtml/rendering/render_box.cpp
index 2f2687d..9ab5636 100644
--- a/WebCore/khtml/rendering/render_box.cpp
+++ b/WebCore/khtml/rendering/render_box.cpp
@@ -63,6 +63,7 @@ RenderBox::RenderBox(DOM::NodeImpl* node)
     m_staticX = 0;
     m_staticY = 0;
     m_layer = 0;
+    m_inlineBoxWrapper = 0;
 }
 
 void RenderBox::setStyle(RenderStyle *_style)
@@ -121,9 +122,14 @@ RenderBox::~RenderBox()
 void RenderBox::detach()
 {
     RenderLayer* layer = m_layer;
-
     RenderArena* arena = renderArena();
     
+    if (m_inlineBoxWrapper) {
+        if (!documentBeingDestroyed())
+            m_inlineBoxWrapper->parent()->removeChild(m_inlineBoxWrapper);
+        m_inlineBoxWrapper->detach(arena);
+    }
+
     RenderContainer::detach();
     
     if (layer)
@@ -563,17 +569,30 @@ void RenderBox::position(InlineBox* box, int from, int len, bool reverse)
             m_staticY = box->yPos();
 
         // Nuke the box.
+        box->parent()->removeChild(box);
         box->detach(renderArena());
     }
     else if (isReplaced()) {
         m_x = box->xPos();
         m_y = box->yPos();
-
-        // Nuke the box.  We don't need it for replaced elements.
-        box->detach(renderArena());
+        m_inlineBoxWrapper = box;
     }
 }
 
+// For inline replaced elements, this function returns the inline box that owns us.  Enables
+// the replaced RenderObject to quickly determine what line it is contained on and to easily
+// iterate over structures on the line.
+InlineBox* RenderBox::inlineBoxWrapper() const
+{
+    return m_inlineBoxWrapper;
+}
+
+void RenderBox::deleteLineBoxWrapper()
+{
+    if (m_inlineBoxWrapper)
+        m_inlineBoxWrapper->detach(renderArena());
+}
+
 QRect RenderBox::getAbsoluteRepaintRect()
 {
     int ow = style() ? style()->outlineSize() : 0;
diff --git a/WebCore/khtml/rendering/render_box.h b/WebCore/khtml/rendering/render_box.h
index 2725bb1..0917776 100644
--- a/WebCore/khtml/rendering/render_box.h
+++ b/WebCore/khtml/rendering/render_box.h
@@ -84,6 +84,12 @@ public:
 
     virtual void position(InlineBox* box, int from, int len, bool reverse);
     
+    // For inline replaced elements, this function returns the inline box that owns us.  Enables
+    // the replaced RenderObject to quickly determine what line it is contained on and to easily
+    // iterate over structures on the line.
+    virtual InlineBox* inlineBoxWrapper() const;
+    void deleteLineBoxWrapper();
+    
     virtual int lowestPosition(bool includeOverflowInterior=true, bool includeSelf=true) const;
     virtual int rightmostPosition(bool includeOverflowInterior=true, bool includeSelf=true) const;
     virtual int leftmostPosition(bool includeOverflowInterior=true, bool includeSelf=true) const;
@@ -174,6 +180,9 @@ protected:
     // A pointer to our layer if we have one.  Currently only positioned elements
     // and floaters have layers.
     RenderLayer* m_layer;
+    
+    // For inline replaced elements, the inline box that owns us.
+    InlineBox* m_inlineBoxWrapper;
 };
 
 
diff --git a/WebCore/khtml/rendering/render_container.cpp b/WebCore/khtml/rendering/render_container.cpp
index 4cac876..0848678 100644
--- a/WebCore/khtml/rendering/render_container.cpp
+++ b/WebCore/khtml/rendering/render_container.cpp
@@ -158,7 +158,7 @@ RenderObject* RenderContainer::removeChildNode(RenderObject* oldChild)
     // So that we'll get the appropriate dirty bit set (either that a normal flow child got yanked or
     // that a positioned child got yanked).  We also repaint, so that the area exposed when the child
     // disappears gets repainted properly.
-    if (document()->renderer()) {
+    if (!documentBeingDestroyed()) {
         oldChild->setNeedsLayoutAndMinMaxRecalc();
 #ifdef INCREMENTAL_REPAINTING
         oldChild->repaint();
diff --git a/WebCore/khtml/rendering/render_flow.cpp b/WebCore/khtml/rendering/render_flow.cpp
index f478f51..ea8c1db 100644
--- a/WebCore/khtml/rendering/render_flow.cpp
+++ b/WebCore/khtml/rendering/render_flow.cpp
@@ -142,6 +142,11 @@ void RenderFlow::deleteLineBoxes()
 
 void RenderFlow::detach()
 {
+    if (!documentBeingDestroyed() && m_firstLineBox && m_firstLineBox->parent()) {
+        for (InlineRunBox* box = m_firstLineBox; box; box = box->nextLineBox())
+            box->parent()->removeChild(box);
+    }
+
     deleteLineBoxes();
     RenderBox::detach();
 }
diff --git a/WebCore/khtml/rendering/render_line.cpp b/WebCore/khtml/rendering/render_line.cpp
index 3fa5585..72f1c44 100644
--- a/WebCore/khtml/rendering/render_line.cpp
+++ b/WebCore/khtml/rendering/render_line.cpp
@@ -128,6 +128,18 @@ int InlineFlowBox::getFlowSpacingWidth()
     return totWidth;
 }
 
+void InlineFlowBox::removeChild(InlineBox* child)
+{
+    if (child == m_firstChild)
+        m_firstChild = child->nextOnLine();
+    if (child == m_lastChild)
+        m_lastChild = child->prevOnLine();
+    if (child->nextOnLine())
+        child->nextOnLine()->setPrevOnLine(child->prevOnLine());
+    if (child->prevOnLine())
+        child->prevOnLine()->setNextOnLine(child->nextOnLine());
+}
+
 bool InlineFlowBox::nextOnLineExists()
 {
     if (!parent())
diff --git a/WebCore/khtml/rendering/render_line.h b/WebCore/khtml/rendering/render_line.h
index dedfc85..69b47b2 100644
--- a/WebCore/khtml/rendering/render_line.h
+++ b/WebCore/khtml/rendering/render_line.h
@@ -72,8 +72,11 @@ public:
 
     void setFirstLineStyleBit(bool f) { m_firstLine = f; }
 
-    InlineBox* nextOnLine() { return m_next; }
-    InlineBox* prevOnLine() { return m_prev; }
+    InlineBox* nextOnLine() const { return m_next; }
+    InlineBox* prevOnLine() const { return m_prev; }
+    void setNextOnLine(InlineBox* next) { m_next = next; }
+    void setPrevOnLine(InlineBox* prev) { m_prev = prev; }
+    
     RenderObject* object() { return m_object; }
 
     InlineFlowBox* parent() { return m_parent; }
@@ -131,8 +134,8 @@ public:
         m_nextLine = 0;
     }
 
-    InlineRunBox* prevLineBox() { return m_prevLine; }
-    InlineRunBox* nextLineBox() { return m_nextLine; }
+    InlineRunBox* prevLineBox() const { return m_prevLine; }
+    InlineRunBox* nextLineBox() const { return m_nextLine; }
     void setNextLineBox(InlineRunBox* n) { m_nextLine = n; }
     void setPreviousLineBox(InlineRunBox* p) { m_prevLine = p; }
 
@@ -222,6 +225,8 @@ public:
     
     virtual void setOverflowPositions(int top, int bottom) {}
     
+    void removeChild(InlineBox* child);
+    
 protected:
     InlineBox* m_firstChild;
     InlineBox* m_lastChild;
diff --git a/WebCore/khtml/rendering/render_object.cpp b/WebCore/khtml/rendering/render_object.cpp
index 4fa076b..afcf0b0 100644
--- a/WebCore/khtml/rendering/render_object.cpp
+++ b/WebCore/khtml/rendering/render_object.cpp
@@ -263,7 +263,7 @@ bool RenderObject::isEditable() const
 
     return style()->visibility() == VISIBLE && 
         element() && element()->isContentEditable() &&
-        (isReplaced() || (textRenderer && textRenderer->inlineTextBoxes().count() > 0));
+        (isReplaced() || (textRenderer && textRenderer->firstTextBox()));
 }
 
 RenderObject *RenderObject::nextEditable() const
@@ -2021,6 +2021,14 @@ InlineBox* RenderObject::createInlineBox(bool,bool isRootLineBox)
     return new (renderArena()) InlineBox(this);
 }
 
+InlineBox* RenderObject::inlineBoxWrapper() const
+{
+    return 0;
+}
+
+void RenderObject::deleteLineBoxWrapper()
+{}
+
 RenderStyle* RenderObject::style(bool firstLine) const {
     RenderStyle *s = m_style;
     if (firstLine) {
diff --git a/WebCore/khtml/rendering/render_object.h b/WebCore/khtml/rendering/render_object.h
index a9c05cf..597cd1c 100644
--- a/WebCore/khtml/rendering/render_object.h
+++ b/WebCore/khtml/rendering/render_object.h
@@ -34,7 +34,7 @@
 #include "misc/helper.h"
 #include "rendering/render_style.h"
 #include "khtml_events.h"
-#include "xml/dom_nodeimpl.h"
+#include "xml/dom_docimpl.h"
 
 // Uncomment to turn on incremental repainting.
 #define INCREMENTAL_REPAINTING 1
@@ -327,6 +327,12 @@ public:
     
     virtual InlineBox* createInlineBox(bool makePlaceHolderBox, bool isRootLineBox);
     
+    // For inline replaced elements, this function returns the inline box that owns us.  Enables
+    // the replaced RenderObject to quickly determine what line it is contained on and to easily
+    // iterate over structures on the line.
+    virtual InlineBox* inlineBoxWrapper() const;
+    void deleteLineBoxWrapper();
+    
     // for discussion of lineHeight see CSS2 spec
     virtual short lineHeight( bool firstLine, bool isRootLineBox=false ) const;
     // for the vertical-align property of inline elements
@@ -682,6 +688,10 @@ public:
     virtual void calcVerticalMargins() {}
     void removeFromObjectLists();
 
+    // When performing a global document tear-down, the renderer of the document is cleared.  We use this
+    // as a hook to detect the case of document destruction and don't waste time doing unnecessary work.
+    bool documentBeingDestroyed() const { return !document()->renderer(); }
+
     virtual void detach();
 
     const QFont &font(bool firstLine) const {
diff --git a/WebCore/khtml/rendering/render_text.cpp b/WebCore/khtml/rendering/render_text.cpp
index 101d72e..bab1bdf 100644
--- a/WebCore/khtml/rendering/render_text.cpp
+++ b/WebCore/khtml/rendering/render_text.cpp
@@ -234,58 +234,6 @@ FindSelectionResult InlineTextBox::checkSelectionPoint(int _x, int _y, int _tx,
     return SelectionPointInside;
 }
 
-// -----------------------------------------------------------------------------
-
-InlineTextBoxArray::InlineTextBoxArray()
-{
-    setAutoDelete(false);
-}
-
-int InlineTextBoxArray::compareItems( Item d1, Item d2 )
-{
-    assert(d1);
-    assert(d2);
-
-    return static_cast<InlineTextBox*>(d1)->m_y - static_cast<InlineTextBox*>(d2)->m_y;
-}
-
-// remove this once QVector::bsearch is fixed
-int InlineTextBoxArray::findFirstMatching(Item d) const
-{
-    int len = count();
-
-    if ( !len )
-	return -1;
-    if ( !d )
-	return -1;
-    int n1 = 0;
-    int n2 = len - 1;
-    int mid = 0;
-    bool found = FALSE;
-    while ( n1 <= n2 ) {
-	int  res;
-	mid = (n1 + n2)/2;
-	if ( (*this)[mid] == 0 )			// null item greater
-	    res = -1;
-	else
-	    res = ((QGVector*)this)->compareItems( d, (*this)[mid] );
-	if ( res < 0 )
-	    n2 = mid - 1;
-	else if ( res > 0 )
-	    n1 = mid + 1;
-	else {					// found it
-	    found = TRUE;
-	    break;
-	}
-    }
-    /* if ( !found )
-	return -1; */
-    // search to first one equal or bigger
-    while ( found && (mid > 0) && !((QGVector*)this)->compareItems(d, (*this)[mid-1]) )
-	mid--;
-    return mid;
-}
-
 // -------------------------------------------------------------------------------------
 
 RenderText::RenderText(DOM::NodeImpl* node, DOMStringImpl *_str)
@@ -310,6 +258,8 @@ RenderText::RenderText(DOM::NodeImpl* node, DOMStringImpl *_str)
     }
     KHTMLAssert(!str || !str->l || str->s);
 
+    m_firstTextBox = m_lastTextBox = 0;
+    
     m_selectionState = SelectionNone;
 
 #ifdef DEBUG_LAYOUT
@@ -347,28 +297,26 @@ RenderText::~RenderText()
 
 void RenderText::detach()
 {
-    deleteRuns();
+    if (!documentBeingDestroyed()) {
+        for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox())
+            box->parent()->removeChild(box);
+    }
+    deleteTextBoxes();
     RenderObject::detach();
 }
 
-void RenderText::deleteRuns()
+void RenderText::deleteTextBoxes()
 {
-    // this is a slight variant of QArray::clear().
-    // We don't delete the array itself here because its
-    // likely to be used in the same size later again, saves
-    // us resize() calls
-    unsigned int len = m_lines.size();
-    if (len) {
+    if (firstTextBox()) {
         RenderArena* arena = renderArena();
-        for(unsigned int i=0; i < len; i++) {
-            InlineTextBox* s = m_lines.at(i);
-            if (s)
-                s->detach(arena);
-            m_lines.remove(i);
+        InlineTextBox *curr = firstTextBox(), *next = 0;
+        while (curr) {
+            next = curr->nextTextBox();
+            curr->detach(arena);
+            curr = next;
         }
+        m_firstTextBox = m_lastTextBox = 0;
     }
-    
-    KHTMLAssert(m_lines.count() == 0);
 }
 
 bool RenderText::isTextFragment() const
@@ -383,29 +331,28 @@ DOM::DOMStringImpl* RenderText::originalString() const
 
 void RenderText::absoluteRects(QValueList<QRect>& rects, int _tx, int _ty)
 {
-    for (unsigned int i = 0; i < m_lines.count(); i++)
-        rects.append(QRect(_tx + m_lines[i]->xPos(), 
-                           _ty + m_lines[i]->yPos(), 
-                           m_lines[i]->width(), 
-                           m_lines[i]->height()));
+    for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox())
+        rects.append(QRect(_tx + box->xPos(), 
+                           _ty + box->yPos(), 
+                           box->width(), 
+                           box->height()));
 }
 
-InlineTextBox * RenderText::findNextInlineTextBox( int offset, int &pos )
+InlineTextBox* RenderText::findNextInlineTextBox(int offset, int &pos)
 {
     // The text runs point to parts of the rendertext's str string
     // (they don't include '\n')
     // Find the text run that includes the character at @p offset
     // and return pos, which is the position of the char in the run.
 
-    if ( m_lines.isEmpty() )
-        return 0L;
-
-    InlineTextBox* s = m_lines[0];
-    uint si = 1;
+    if (!m_firstTextBox)
+        return 0;
+    
+    InlineTextBox* s = m_firstTextBox;
     int off = s->m_len;
-    while(offset > off && si < m_lines.count())
+    while (offset > off && s->nextTextBox())
     {
-        s = m_lines[si++];
+        s = s->nextTextBox();
         off = s->m_start + s->m_len;
     }
     // we are now in the correct text run
@@ -418,16 +365,12 @@ bool RenderText::nodeAtPoint(NodeInfo& info, int _x, int _y, int _tx, int _ty,
 {
     assert(parent());
 
-    InlineTextBox *s = m_lines.count() ? m_lines[0] : 0;
-    int si = 0;
-    while(s) {
+    for (InlineTextBox *s = m_firstTextBox; s; s = s->nextTextBox()) {
         if((_y >=_ty + s->m_y) && (_y < _ty + s->m_y + s->height()) &&
            (_x >= _tx + s->m_x) && (_x <_tx + s->m_x + s->m_width) ) {
             inside = true;
             break;
         }
-
-        s = si < (int) m_lines.count()-1 ? m_lines[++si] : 0;
     }
 
     if (inside && element()) {
@@ -457,11 +400,9 @@ FindSelectionResult RenderText::checkSelectionPointIgnoringContinuations(int _x,
 //                   << " _tx=" << _tx << " _ty=" << _ty << endl;
     InlineTextBox *lastPointAfterInline=0;
 
-    for(unsigned int si = 0; si < m_lines.count(); si++)
-    {
-        InlineTextBox* s = m_lines[si];
+    for (InlineTextBox* s = firstTextBox(); s; s = s->nextTextBox()) {
         int result;
-        const Font *f = htmlFont( si==0 );
+        const Font *f = htmlFont(s == firstTextBox());
         result = s->checkSelectionPoint(_x, _y, _tx, _ty, f, this, offset, m_lineHeight);
 
 //         kdDebug(6040) << "RenderText::checkSelectionPoint " << this << " line " << si << " result=" << result << " offset=" << offset << endl;
@@ -473,7 +414,7 @@ FindSelectionResult RenderText::checkSelectionPointIgnoringContinuations(int _x,
             return SelectionPointInside;
         } else if ( result == SelectionPointBefore ) {
             // x,y is before the InlineTextBox -> stop here
-            if ( si > 0 && lastPointAfterInline ) {
+            if ( s != firstTextBox() && lastPointAfterInline ) {
                 offset = lastPointAfterInline->m_start + lastPointAfterInline->m_len;
                 //kdDebug(6040) << "RenderText::checkSelectionPoint before -> " << offset << endl;
                 node = element();
@@ -499,7 +440,7 @@ FindSelectionResult RenderText::checkSelectionPointIgnoringContinuations(int _x,
 
 void RenderText::caretPos(int offset, bool override, int &_x, int &_y, int &width, int &height)
 {
-  if (!m_lines.count()) {
+  if (!firstTextBox()) {
     _x = _y = height = -1;
     return;
   }
@@ -585,256 +526,250 @@ void RenderText::paintObject(QPainter *p, int /*x*/, int y, int /*w*/, int h,
     RenderStyle* pseudoStyle = style(true);
     if (pseudoStyle == style()) pseudoStyle = 0;
     int d = style()->textDecorationsInEffect();
-    InlineTextBox f(0, y-ty);
-    int si = m_lines.findFirstMatching(&f);
-    // something matching found, find the first one to print
     bool isPrinting = (p->device()->devType() == QInternal::Printer);
-    if(si >= 0)
-    {
-        // Move up until out of area to be printed
-        while(si > 0 && m_lines[si-1]->checkVerticalPoint(y, ty, h))
-            si--;
-
-        // Now calculate startPos and endPos, for printing selection.
-        // We print selection while endPos > 0
-        int endPos, startPos;
-        if (!isPrinting && (selectionState() != SelectionNone)) {
-            if (selectionState() == SelectionInside) {
-                //kdDebug(6040) << this << " SelectionInside -> 0 to end" << endl;
-                startPos = 0;
+    
+    // Walk forward until we hit the first line that needs to be painted.
+    InlineTextBox* s = firstTextBox();
+    for (; s && !s->checkVerticalPoint(y, ty, h); s = s->nextTextBox());
+    if (!s) return;
+    
+    // Now calculate startPos and endPos, for painting selection.
+    // We paint selection while endPos > 0
+    int endPos, startPos;
+    if (!isPrinting && (selectionState() != SelectionNone)) {
+        if (selectionState() == SelectionInside) {
+            //kdDebug(6040) << this << " SelectionInside -> 0 to end" << endl;
+            startPos = 0;
+            endPos = str->l;
+        } else {
+            selectionStartEnd(startPos, endPos);
+            if(selectionState() == SelectionStart)
                 endPos = str->l;
-            } else {
-                selectionStartEnd(startPos, endPos);
-                if(selectionState() == SelectionStart)
-                    endPos = str->l;
-                else if(selectionState() == SelectionEnd)
-                    startPos = 0;
-            }
-            //kdDebug(6040) << this << " Selection from " << startPos << " to " << endPos << endl;
+            else if(selectionState() == SelectionEnd)
+                startPos = 0;
         }
+        //kdDebug(6040) << this << " Selection from " << startPos << " to " << endPos << endl;
+    }
 
-        InlineTextBox* s;
-
-	const Font *font = &style()->htmlFont();
+    const Font *font = &style()->htmlFont();
 
 #if APPLE_CHANGES
-        // Do one pass for the selection, then another for the rest.
-        bool haveSelection = startPos != endPos && !isPrinting && selectionState() != SelectionNone;
-        if (!haveSelection && paintAction == PaintActionSelection) {
-            // When only painting the selection, don't bother to paint if there is none.
-            return;
-        }
-        int startLine = si;
-        for (int pass = 0; pass < (haveSelection ? 2 : 1); pass++) {
-            si = startLine;
-            
-            bool drawSelectionBackground = haveSelection && pass == 0 && paintAction != PaintActionSelection;
-            bool drawText = !haveSelection || pass == 1;
+    // Do one pass for the selection, then another for the rest.
+    bool haveSelection = startPos != endPos && !isPrinting && selectionState() != SelectionNone;
+    if (!haveSelection && paintAction == PaintActionSelection) {
+        // When only painting the selection, don't bother to paint if there is none.
+        return;
+    }
+
+    InlineTextBox* startBox = s;
+    for (int pass = 0; pass < (haveSelection ? 2 : 1); pass++) {
+        s = startBox;
+        bool drawSelectionBackground = haveSelection && pass == 0 && paintAction != PaintActionSelection;
+        bool drawText = !haveSelection || pass == 1;
 #endif
 
-        // run until we find one that is outside the range, then we
-        // know we can stop
-        do {
-            s = m_lines[si];
-
-	    if (isPrinting)
-	    {
-                // FIXME: Need to understand what this section is doing.
-                if (ty+s->m_y < y)
-                {
-                   // This has been printed already we suppose.
-                   continue;
-                }
+    // run until we find one that is outside the range, then we
+    // know we can stop
+    do {
+        if (isPrinting)
+        {
+            // FIXME: Need to understand what this section is doing.
+            if (ty+s->m_y < y)
+            {
+               // This has been printed already we suppose.
+               continue;
+            }
 
-                if (ty+s->m_y+s->height() > y+h)
-                {
-                   RenderCanvas* canvasObj = canvas();
-                   if (ty+s->m_y < canvasObj->truncatedAt())
+            if (ty+s->m_y+s->height() > y+h)
+            {
+               RenderCanvas* canvasObj = canvas();
+               if (ty+s->m_y < canvasObj->truncatedAt())
 #if APPLE_CHANGES
-                       canvasObj->setBestTruncatedAt(ty+s->m_y, this);
+                   canvasObj->setBestTruncatedAt(ty+s->m_y, this);
 #else
-                       canvasObj->setTruncatedAt(ty+s->m_y);
+                   canvasObj->setTruncatedAt(ty+s->m_y);
 #endif
-                   // Let's stop here.
-                   break;
-                }
+               // Let's stop here.
+               break;
             }
+        }
 
-            RenderStyle* _style = pseudoStyle && s->m_firstLine ? pseudoStyle : style();
+        RenderStyle* _style = pseudoStyle && s->m_firstLine ? pseudoStyle : style();
 
-            if (_style->font() != p->font())
-                p->setFont(_style->font());
+        if (_style->font() != p->font())
+            p->setFont(_style->font());
 
-            font = &_style->htmlFont(); // Always update, since smallCaps is not stored in the QFont.
+        font = &_style->htmlFont(); // Always update, since smallCaps is not stored in the QFont.
 
 #if APPLE_CHANGES
-            if (drawText) {
+        if (drawText) {
 #endif
-            
-            QColor textColor = _style->color();
-            if (_style->shouldCorrectTextColor()) {
-                textColor = correctedTextColor(textColor, _style->backgroundColor());
-            }
+        
+        QColor textColor = _style->color();
+        if (_style->shouldCorrectTextColor()) {
+            textColor = correctedTextColor(textColor, _style->backgroundColor());
+        }
 
-            if(textColor != p->pen().color())
-                p->setPen(textColor);
+        if(textColor != p->pen().color())
+            p->setPen(textColor);
 
 #if APPLE_CHANGES
-            // Set a text shadow if we have one.
-            // FIXME: Support multiple shadow effects.  Need more from the CG API before
-            // we can do this.
-            bool setShadow = false;
-            if (_style->textShadow()) {
-                p->setShadow(_style->textShadow()->x, _style->textShadow()->y,
-                             _style->textShadow()->blur, _style->textShadow()->color);
-                setShadow = true;
-            }
+        // Set a text shadow if we have one.
+        // FIXME: Support multiple shadow effects.  Need more from the CG API before
+        // we can do this.
+        bool setShadow = false;
+        if (_style->textShadow()) {
+            p->setShadow(_style->textShadow()->x, _style->textShadow()->y,
+                         _style->textShadow()->blur, _style->textShadow()->color);
+            setShadow = true;
+        }
 #endif
-            
-            if (s->m_len > 0) {
-                bool paintSelectedTextOnly = (paintAction == PaintActionSelection);
-                bool paintSelectedTextSeparately = false; // Whether or not we have to do multiple paints.  Only
-                                               // necessary when a custom ::selection foreground color is applied.
-                QColor selectionColor = p->pen().color();
-                ShadowData* selectionTextShadow = 0;
-                if (haveSelection) {
-                    RenderStyle* pseudoStyle = getPseudoStyle(RenderStyle::SELECTION);
-                    if (pseudoStyle) {
-                        if (pseudoStyle->color() != selectionColor || pseudoStyle->textShadow()) {
-                            if (!paintSelectedTextOnly)
-                                paintSelectedTextSeparately = true;
-                            if (pseudoStyle->color() != selectionColor)
-                                selectionColor = pseudoStyle->color();
-                            if (pseudoStyle->textShadow())
-                                selectionTextShadow = pseudoStyle->textShadow();
-                        }
+        
+        if (s->m_len > 0) {
+            bool paintSelectedTextOnly = (paintAction == PaintActionSelection);
+            bool paintSelectedTextSeparately = false; // Whether or not we have to do multiple paints.  Only
+                                           // necessary when a custom ::selection foreground color is applied.
+            QColor selectionColor = p->pen().color();
+            ShadowData* selectionTextShadow = 0;
+            if (haveSelection) {
+                RenderStyle* pseudoStyle = getPseudoStyle(RenderStyle::SELECTION);
+                if (pseudoStyle) {
+                    if (pseudoStyle->color() != selectionColor || pseudoStyle->textShadow()) {
+                        if (!paintSelectedTextOnly)
+                            paintSelectedTextSeparately = true;
+                        if (pseudoStyle->color() != selectionColor)
+                            selectionColor = pseudoStyle->color();
+                        if (pseudoStyle->textShadow())
+                            selectionTextShadow = pseudoStyle->textShadow();
                     }
                 }
-                
-                if (!paintSelectedTextOnly && !paintSelectedTextSeparately) {
+            }
+            
+            if (!paintSelectedTextOnly && !paintSelectedTextSeparately) {
 #if APPLE_CHANGES
-                    font->drawText(p, s->m_x + tx, s->m_y + ty + s->m_baseline,
-                                   str->s, str->l, s->m_start, s->m_len,
-                                   s->m_toAdd, s->m_reversed ? QPainter::RTL : QPainter::LTR, style()->visuallyOrdered());
+                font->drawText(p, s->m_x + tx, s->m_y + ty + s->m_baseline,
+                               str->s, str->l, s->m_start, s->m_len,
+                               s->m_toAdd, s->m_reversed ? QPainter::RTL : QPainter::LTR, style()->visuallyOrdered());
 #else
-                    font->drawText(p, s->m_x + tx, s->m_y + ty + s->m_baseline,
-                                   str->s, str->l, s->m_start, s->m_len,
-                                   s->m_toAdd, s->m_reversed ? QPainter::RTL : QPainter::LTR);
+                font->drawText(p, s->m_x + tx, s->m_y + ty + s->m_baseline,
+                               str->s, str->l, s->m_start, s->m_len,
+                               s->m_toAdd, s->m_reversed ? QPainter::RTL : QPainter::LTR);
 #endif
-                }
-                else {
-                    int offset = s->m_start;
-                    int sPos = QMAX( startPos - offset, 0 );
-                    int ePos = QMIN( endPos - offset, s->m_len );
-                    if (paintSelectedTextSeparately) {
-                        if (sPos >= ePos)
+            }
+            else {
+                int offset = s->m_start;
+                int sPos = QMAX( startPos - offset, 0 );
+                int ePos = QMIN( endPos - offset, s->m_len );
+                if (paintSelectedTextSeparately) {
+                    if (sPos >= ePos)
 #if APPLE_CHANGES
-                            font->drawText(p, s->m_x + tx, s->m_y + ty + s->m_baseline,
-                                           str->s, str->l, s->m_start, s->m_len,
-                                           s->m_toAdd, s->m_reversed ? QPainter::RTL : QPainter::LTR, style()->visuallyOrdered());
+                        font->drawText(p, s->m_x + tx, s->m_y + ty + s->m_baseline,
+                                       str->s, str->l, s->m_start, s->m_len,
+                                       s->m_toAdd, s->m_reversed ? QPainter::RTL : QPainter::LTR, style()->visuallyOrdered());
 #else
-                            font->drawText(p, s->m_x + tx, s->m_y + ty + s->m_baseline,
-                                           str->s, str->l, s->m_start, s->m_len,
-                                           s->m_toAdd, s->m_reversed ? QPainter::RTL : QPainter::LTR);
+                        font->drawText(p, s->m_x + tx, s->m_y + ty + s->m_baseline,
+                                       str->s, str->l, s->m_start, s->m_len,
+                                       s->m_toAdd, s->m_reversed ? QPainter::RTL : QPainter::LTR);
 #endif
-                        else {
-                            if (sPos-1 >= 0)
+                    else {
+                        if (sPos-1 >= 0)
 #if APPLE_CHANGES
-                                font->drawText(p, s->m_x + tx, s->m_y + ty + s->m_baseline, str->s,
-                                            str->l, s->m_start, s->m_len,
-                                            s->m_toAdd, s->m_reversed ? QPainter::RTL : QPainter::LTR, style()->visuallyOrdered(), 0, sPos);
+                            font->drawText(p, s->m_x + tx, s->m_y + ty + s->m_baseline, str->s,
+                                        str->l, s->m_start, s->m_len,
+                                        s->m_toAdd, s->m_reversed ? QPainter::RTL : QPainter::LTR, style()->visuallyOrdered(), 0, sPos);
 #else
-                                font->drawText(p, s->m_x + tx, s->m_y + ty + s->m_baseline, str->s,
-                                            str->l, s->m_start, s->m_len,
-                                            s->m_toAdd, s->m_reversed ? QPainter::RTL : QPainter::LTR, 0, sPos);
+                            font->drawText(p, s->m_x + tx, s->m_y + ty + s->m_baseline, str->s,
+                                        str->l, s->m_start, s->m_len,
+                                        s->m_toAdd, s->m_reversed ? QPainter::RTL : QPainter::LTR, 0, sPos);
 #endif
-                            if (ePos < s->m_start+s->m_len)
+                        if (ePos < s->m_start+s->m_len)
 #if APPLE_CHANGES
-                                font->drawText(p, s->m_x + tx, s->m_y + ty + s->m_baseline, str->s,
-                                            str->l, s->m_start, s->m_len,
-                                            s->m_toAdd, s->m_reversed ? QPainter::RTL : QPainter::LTR, style()->visuallyOrdered(), ePos, -1);
+                            font->drawText(p, s->m_x + tx, s->m_y + ty + s->m_baseline, str->s,
+                                        str->l, s->m_start, s->m_len,
+                                        s->m_toAdd, s->m_reversed ? QPainter::RTL : QPainter::LTR, style()->visuallyOrdered(), ePos, -1);
 #else
-                                font->drawText(p, s->m_x + tx, s->m_y + ty + s->m_baseline, str->s,
-                                            str->l, s->m_start, s->m_len,
-                                            s->m_toAdd, s->m_reversed ? QPainter::RTL : QPainter::LTR, ePos, -1);
+                            font->drawText(p, s->m_x + tx, s->m_y + ty + s->m_baseline, str->s,
+                                        str->l, s->m_start, s->m_len,
+                                        s->m_toAdd, s->m_reversed ? QPainter::RTL : QPainter::LTR, ePos, -1);
 #endif
-                        }
                     }
-                    
-                    if ( sPos < ePos ) {
-                        if (selectionColor != p->pen().color())
-                            p->setPen(selectionColor);
+                }
+                
+                if ( sPos < ePos ) {
+                    if (selectionColor != p->pen().color())
+                        p->setPen(selectionColor);
 
 #if APPLE_CHANGES
-                        if (selectionTextShadow)
-                            p->setShadow(selectionTextShadow->x,
-                                         selectionTextShadow->y,
-                                         selectionTextShadow->blur,
-                                         selectionTextShadow->color);
+                    if (selectionTextShadow)
+                        p->setShadow(selectionTextShadow->x,
+                                     selectionTextShadow->y,
+                                     selectionTextShadow->blur,
+                                     selectionTextShadow->color);
 #endif                       
 
 #if APPLE_CHANGES
-                        font->drawText(p, s->m_x + tx, s->m_y + ty + s->m_baseline, str->s,
-                                       str->l, s->m_start, s->m_len,
-                                       s->m_toAdd, s->m_reversed ? QPainter::RTL : QPainter::LTR, style()->visuallyOrdered(), sPos, ePos);
+                    font->drawText(p, s->m_x + tx, s->m_y + ty + s->m_baseline, str->s,
+                                   str->l, s->m_start, s->m_len,
+                                   s->m_toAdd, s->m_reversed ? QPainter::RTL : QPainter::LTR, style()->visuallyOrdered(), sPos, ePos);
 #else
-                        font->drawText(p, s->m_x + tx, s->m_y + ty + s->m_baseline, str->s,
-                                       str->l, s->m_start, s->m_len,
-                                       s->m_toAdd, s->m_reversed ? QPainter::RTL : QPainter::LTR, sPos, ePos);
+                    font->drawText(p, s->m_x + tx, s->m_y + ty + s->m_baseline, str->s,
+                                   str->l, s->m_start, s->m_len,
+                                   s->m_toAdd, s->m_reversed ? QPainter::RTL : QPainter::LTR, sPos, ePos);
 #endif
 
 #if APPLE_CHANGES
-                        if (selectionTextShadow)
-                            p->clearShadow();
+                    if (selectionTextShadow)
+                        p->clearShadow();
 #endif
-                    }
-                } 
-            }
-            
-            if (d != TDNONE && paintAction == PaintActionForeground &&
-                style()->htmlHacks()) {
-                p->setPen(_style->color());
-                s->paintDecoration(p, tx, ty, d);
-            }
+                }
+            } 
+        }
+        
+        if (d != TDNONE && paintAction == PaintActionForeground &&
+            style()->htmlHacks()) {
+            p->setPen(_style->color());
+            s->paintDecoration(p, tx, ty, d);
+        }
 
 #if APPLE_CHANGES
-            if (setShadow)
-                p->clearShadow();
-            
-            } // drawText
+        if (setShadow)
+            p->clearShadow();
+        
+        } // drawText
 #endif
 
 #if APPLE_CHANGES
-            if (drawSelectionBackground)
+        if (drawSelectionBackground)
 #endif
-            if (!isPrinting && (selectionState() != SelectionNone))
-            {
-		int offset = s->m_start;
-		int sPos = QMAX( startPos - offset, 0 );
-		int ePos = QMIN( endPos - offset, s->m_len );
-                //kdDebug(6040) << this << " paintSelection with startPos=" << sPos << " endPos=" << ePos << endl;
-		if ( sPos < ePos )
-		    s->paintSelection(font, this, p, _style, tx, ty, sPos, ePos);
+        if (!isPrinting && (selectionState() != SelectionNone))
+        {
+            int offset = s->m_start;
+            int sPos = QMAX( startPos - offset, 0 );
+            int ePos = QMIN( endPos - offset, s->m_len );
+            //kdDebug(6040) << this << " paintSelection with startPos=" << sPos << " endPos=" << ePos << endl;
+            if ( sPos < ePos )
+                s->paintSelection(font, this, p, _style, tx, ty, sPos, ePos);
 
-            }
+        }
 
 #ifdef BIDI_DEBUG
-            {
-                int h = lineHeight( false ) + paddingTop() + paddingBottom() + borderTop() + borderBottom();
-                QColor c2 = QColor("#0000ff");
-                drawBorder(p, tx, ty, tx+1, ty + h,
-                              RenderObject::BSLeft, c2, c2, SOLID, 1, 1);
-                drawBorder(p, tx + s->m_width, ty, tx + s->m_width + 1, ty + h,
-                              RenderObject::BSRight, c2, c2, SOLID, 1, 1);
-            }
+        {
+            int h = lineHeight( false ) + paddingTop() + paddingBottom() + borderTop() + borderBottom();
+            QColor c2 = QColor("#0000ff");
+            drawBorder(p, tx, ty, tx+1, ty + h,
+                          RenderObject::BSLeft, c2, c2, SOLID, 1, 1);
+            drawBorder(p, tx + s->m_width, ty, tx + s->m_width + 1, ty + h,
+                          RenderObject::BSRight, c2, c2, SOLID, 1, 1);
+        }
 #endif
 
-        } while (++si < (int)m_lines.count() && m_lines[si]->checkVerticalPoint(y, ty, h));
+        s = s->nextTextBox();
+        
+    } while (s && s->checkVerticalPoint(y, ty, h));
 
 #if APPLE_CHANGES
-        } // end of for loop
+    } // end of for loop
 #endif
-    }
 }
 
 void RenderText::paint(QPainter *p, int x, int y, int w, int h,
@@ -846,12 +781,11 @@ void RenderText::paint(QPainter *p, int x, int y, int w, int h,
     if (style()->visibility() != VISIBLE)
         return;
 
-    int s = m_lines.count() - 1;
-    if ( s < 0 )
+    if (!firstTextBox())
         return;
-
-    if (ty + m_lines[0]->yPos() > y + h) return;
-    if (ty + m_lines[s]->yPos() + m_lines[s]->height() < y ) return;
+    
+    if (ty + firstTextBox()->yPos() > y + h) return;
+    if (ty + lastTextBox()->yPos() + lastTextBox()->height() < y ) return;
 
     paintObject(p, x, y, w, h, tx, ty, paintAction);
 }
@@ -1159,30 +1093,21 @@ bool RenderText::containsOnlyWhitespace(unsigned int from, unsigned int len) con
 
 int RenderText::minXPos() const
 {
-    if (!m_lines.count())
-	return 0;
+    if (!m_firstTextBox) return 0;
     int retval=6666666;
-    for (unsigned i=0;i < m_lines.count(); i++)
-    {
-	retval = QMIN ( retval, m_lines[i]->m_x);
-    }
+    for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox())
+	retval = kMin(retval, (int)box->m_x);
     return retval;
 }
 
 int RenderText::xPos() const
 {
-    if (m_lines.count())
-	return m_lines[0]->m_x;
-    else
-	return 0;
+    return m_firstTextBox ? m_firstTextBox->m_x : 0;
 }
 
 int RenderText::yPos() const
 {
-    if (m_lines.count())
-        return m_lines[0]->m_y;
-    else
-        return 0;
+    return m_firstTextBox ? m_firstTextBox->m_y : 0;
 }
 
 const QFont &RenderText::font()
@@ -1232,9 +1157,10 @@ void RenderText::setText(DOMStringImpl *text, bool force)
 
 int RenderText::height() const
 {
+    // FIXME: Why use line-height? Shouldn't we be adding in the height of the last text box? -dwh
     int retval = 0;
-    if ( m_lines.count() )
-        retval = m_lines[m_lines.count()-1]->m_y + m_lineHeight - m_lines[0]->m_y;
+    if (firstTextBox())
+        retval = lastTextBox()->m_y + m_lineHeight - firstTextBox()->m_y;
     return retval;
 }
 
@@ -1255,9 +1181,16 @@ short RenderText::baselinePosition( bool firstLine, bool ) const
 
 InlineBox* RenderText::createInlineBox(bool, bool isRootLineBox)
 {
-    // FIXME: Either ditch the array or get this object into it.
     KHTMLAssert(!isRootLineBox);
-    return new (renderArena()) InlineTextBox(this);
+    InlineTextBox* textBox = new (renderArena()) InlineTextBox(this);
+    if (!m_firstTextBox)
+        m_firstTextBox = m_lastTextBox = textBox;
+    else {
+        m_lastTextBox->setNextLineBox(textBox);
+        textBox->setPreviousLineBox(m_lastTextBox);
+        m_lastTextBox = textBox;
+    }
+    return textBox;
 }
 
 void RenderText::position(InlineBox* box, int from, int len, bool reverse)
@@ -1268,7 +1201,9 @@ void RenderText::position(InlineBox* box, int from, int len, bool reverse)
     if (len == 0 || isBR()) {
         // We want the box to be destroyed.  This is a <br>, and we don't
         // need <br>s to be included.
+        s->parent()->removeChild(s);
         s->detach(renderArena());
+        m_firstTextBox = m_lastTextBox = 0;
         return;
     }
     
@@ -1283,11 +1218,6 @@ void RenderText::position(InlineBox* box, int from, int len, bool reverse)
     s->m_reversed = reverse;
     s->m_start = from;
     s->m_len = len;
-    
-    if(m_lines.count() == m_lines.size())
-        m_lines.resize(m_lines.size()*2+1);
-
-    m_lines.insert(m_lines.count(), s);
 }
 
 unsigned int RenderText::width(unsigned int from, unsigned int len, bool firstLine) const
@@ -1324,15 +1254,14 @@ short RenderText::width() const
     int minx = 100000000;
     int maxx = 0;
     // slooow
-    for(unsigned int si = 0; si < m_lines.count(); si++) {
-        InlineTextBox* s = m_lines[si];
+    for (InlineTextBox* s = firstTextBox(); s; s = s->nextTextBox()) {
         if(s->m_x < minx)
             minx = s->m_x;
         if(s->m_x + s->m_width > maxx)
             maxx = s->m_x + s->m_width;
     }
 
-    w = QMAX(0, maxx-minx);
+    w = kMax(0, maxx-minx);
 
     return w;
 }
@@ -1365,25 +1294,24 @@ const Font *RenderText::htmlFont(bool firstLine) const
 
 long RenderText::caretMinOffset() const
 {
-    if (!m_lines.count()) 
+    if (!firstTextBox()) 
         return 0;
     // EDIT FIXME: it is *not* guaranteed that the first run contains the lowest offset
     // Either make this a linear search (slow),
     // or maintain an index (needs much mem),
     // or calculate and store it in bidi.cpp (needs calculation even if not needed)
-    return m_lines[0]->m_start;
+    return firstTextBox()->m_start;
 }
 
 long RenderText::caretMaxOffset() const
 {
-    int count = m_lines.count();
-    if (!count) 
+    if (!firstTextBox()) 
         return str->l;
     // EDIT FIXME: it is *not* guaranteed that the last run contains the highest offset
     // Either make this a linear search (slow),
     // or maintain an index (needs much mem),
     // or calculate and store it in bidi.cpp (needs calculation even if not needed)
-    return m_lines[count - 1]->m_start + m_lines[count - 1]->m_len;
+    return lastTextBox()->m_start + lastTextBox()->m_len;
 }
 
 bool RenderText::precedesLineBreak() const
diff --git a/WebCore/khtml/rendering/render_text.h b/WebCore/khtml/rendering/render_text.h
index 08c0286..1c11ce0 100644
--- a/WebCore/khtml/rendering/render_text.h
+++ b/WebCore/khtml/rendering/render_text.h
@@ -41,11 +41,11 @@ namespace khtml
     class RenderText;
     class RenderStyle;
 
-class InlineTextBox : public InlineBox
+class InlineTextBox : public InlineRunBox
 {
 public:
     InlineTextBox(RenderObject* obj)
-    :InlineBox(obj)
+    :InlineRunBox(obj)
     {
         m_start = 0;
         m_len = 0;
@@ -53,6 +53,9 @@ public:
         m_toAdd = 0;
     }
     
+    InlineTextBox* nextTextBox() const { return static_cast<InlineTextBox*>(nextLineBox()); }
+    InlineTextBox* prevTextBox() const { return static_cast<InlineTextBox*>(prevLineBox()); }
+    
     void detach(RenderArena* arena);
     
     // Overloaded new operator.  Derived classes must override operator new
@@ -95,28 +98,9 @@ public:
     bool m_reversed : 1;
     int m_toAdd : 14; // for justified text
 private:
-    // this is just for QVector::bsearch. Don't use it otherwise
-    InlineTextBox(int _x, int _y)
-        :InlineBox(0)
-    {
-        m_x = _x;
-        m_y = _y;
-        m_reversed = false;
-    };
     friend class RenderText;
 };
 
-class InlineTextBoxArray : public QPtrVector<InlineTextBox>
-{
-public:
-    InlineTextBoxArray();
-
-    InlineTextBox* first();
-
-    int	  findFirstMatching( Item ) const;
-    virtual int compareItems( Item, Item );
-};
-
 class RenderText : public RenderObject
 {
     friend class InlineTextBox;
@@ -137,7 +121,7 @@ public:
     virtual void paintObject(QPainter *, int x, int y, int w, int h,
                              int tx, int ty, PaintAction paintAction);
 
-    void deleteRuns();
+    void deleteTextBoxes();
     virtual void detach();
     
     DOM::DOMString data() const { return str; }
@@ -214,8 +198,10 @@ public:
     DOM::TextImpl *element() const
     { return static_cast<DOM::TextImpl*>(RenderObject::element()); }
 
+    InlineTextBox* firstTextBox() const { return m_firstTextBox; }
+    InlineTextBox* lastTextBox() const { return m_lastTextBox; }
+    
 #if APPLE_CHANGES
-    InlineTextBoxArray inlineTextBoxes() const { return m_lines; }
     int widthFromCache(const Font *, int start, int len) const;
     bool shouldUseMonospaceCache(const Font *) const;
     void cacheWidths();
@@ -234,9 +220,11 @@ public:
     InlineTextBox * findNextInlineTextBox( int offset, int &pos );
 
 protected: // members
-    InlineTextBoxArray m_lines;
-    DOM::DOMStringImpl *str; //
-
+    DOM::DOMStringImpl *str;
+    
+    InlineTextBox* m_firstTextBox;
+    InlineTextBox* m_lastTextBox;
+    
     short m_lineHeight;
     short m_minWidth;
     short m_maxWidth;
diff --git a/WebCore/khtml/xml/dom_selection.cpp b/WebCore/khtml/xml/dom_selection.cpp
index e4e9cfa..f54e555 100644
--- a/WebCore/khtml/xml/dom_selection.cpp
+++ b/WebCore/khtml/xml/dom_selection.cpp
@@ -54,7 +54,6 @@ using DOM::NodeImpl;
 using DOM::Range;
 using DOM::TextImpl;
 using khtml::InlineTextBox;
-using khtml::InlineTextBoxArray;
 using khtml::RenderObject;
 using khtml::RenderText;
 
@@ -601,18 +600,16 @@ DOMPosition KHTMLSelection::nextCharacterPosition()
     RenderObject *renderer = node->renderer();
     if (renderer->isText()) {
         RenderText *textRenderer = static_cast<khtml::RenderText *>(renderer);
-        InlineTextBoxArray runs = textRenderer->inlineTextBoxes();
-        unsigned i = 0;
-        for (i = 0; i < runs.count(); i++) {
-            long start = runs[i]->m_start;
-            long end = runs[i]->m_start + runs[i]->m_len;
+        for (InlineTextBox* box = textRenderer->firstTextBox(); box; box = box->nextTextBox()) {
+            long start = box->m_start;
+            long end = box->m_start + box->m_len;
             if (desiredOffset > end) {
                 // Skip this node.
                 // It is too early in the text runs to be involved.
                 continue;
             }
             else if (desiredOffset >= start && 
-                (desiredOffset < end || (desiredOffset == end && i + 1 == runs.count() && !renderer->nextEditable())) ||
+                (desiredOffset < end || (desiredOffset == end && !box->nextTextBox() && !renderer->nextEditable())) ||
                 (desiredOffset == end && textRenderer->precedesLineBreak() && !textRenderer->followsLineBreak())) {
                 // Desired offset is in this node.
                 // Either it is:
@@ -641,9 +638,8 @@ DOMPosition KHTMLSelection::nextCharacterPosition()
     while (renderer) {
         if (renderer->isText()) {
             RenderText *textRenderer = static_cast<khtml::RenderText *>(renderer);
-            InlineTextBoxArray runs = textRenderer->inlineTextBoxes();
-            if (runs.count())
-                return DOMPosition(renderer->element(), runs[0]->m_start);
+            if (textRenderer->firstTextBox())
+                return DOMPosition(renderer->element(), textRenderer->firstTextBox()->m_start);
         }
         else {
             return DOMPosition(renderer->element(), renderer->caretMinOffset());
@@ -764,11 +760,10 @@ static bool firstRunAt(RenderObject *renderNode, int y, NodeImpl *&startNode, lo
     for (RenderObject *n = renderNode; n; n = n->nextSibling()) {
         if (n->isText()) {
             RenderText *textRenderer = static_cast<khtml::RenderText *>(n);
-            InlineTextBoxArray runs = textRenderer->inlineTextBoxes();
-            for (unsigned i = 0; i != runs.count(); i++) {
-                if (runs[i]->m_y == y) {
+            for (InlineTextBox* box = textRenderer->firstTextBox(); box; box = box->nextTextBox()) {
+                if (box->m_y == y) {
                     startNode = textRenderer->element();
-                    startOffset = runs[i]->m_start;
+                    startOffset = box->m_start;
                     return true;
                 }
             }
@@ -800,11 +795,10 @@ static bool lastRunAt(RenderObject *renderNode, int y, NodeImpl *&endNode, long
     
         if (n->isText()) {
             RenderText *textRenderer =  static_cast<khtml::RenderText *>(n);
-            InlineTextBoxArray runs = textRenderer->inlineTextBoxes();
-            for (int i = (int)runs.count()-1; i >= 0; i--) {
-                if (runs[i]->m_y == y) {
+            for (InlineTextBox* box = textRenderer->lastTextBox(); box; box = box->prevTextBox()) {
+                if (box->m_y == y) {
                     endNode = textRenderer->element();
-                    endOffset = runs[i]->m_start + runs[i]->m_len;
+                    endOffset = box->m_start + box->m_len;
                     return true;
                 }
             }
diff --git a/WebCore/kwq/KWQAccObject.mm b/WebCore/kwq/KWQAccObject.mm
index 3654632..7190638 100644
--- a/WebCore/kwq/KWQAccObject.mm
+++ b/WebCore/kwq/KWQAccObject.mm
@@ -351,7 +351,7 @@ static QRect boundingBoxRect(RenderObject* obj)
         return YES;
 
     if (m_renderer->isText())
-        return static_cast<RenderText*>(m_renderer)->inlineTextBoxes().count() == 0;
+        return !static_cast<RenderText*>(m_renderer)->firstTextBox();
     
     if (m_renderer->element() && m_renderer->element()->hasAnchor())
         return NO;
diff --git a/WebCore/kwq/KWQDef.h b/WebCore/kwq/KWQDef.h
index 5582d68..cad7f6c 100644
--- a/WebCore/kwq/KWQDef.h
+++ b/WebCore/kwq/KWQDef.h
@@ -36,6 +36,9 @@ typedef unsigned long ulong;
 typedef int Q_INT32;
 typedef unsigned int Q_UINT32;
 
+typedef short Q_INT16;
+typedef unsigned short Q_UINT16;
+
 #define QMAX(a,b) ((a) > (b) ? (a) : (b))
 #define QMIN(a,b) ((a) < (b) ? (a) : (b))
 
diff --git a/WebCore/kwq/KWQKHTMLPart.mm b/WebCore/kwq/KWQKHTMLPart.mm
index 208fc1a..84974c4 100644
--- a/WebCore/kwq/KWQKHTMLPart.mm
+++ b/WebCore/kwq/KWQKHTMLPart.mm
@@ -84,7 +84,7 @@ using khtml::RenderStyle;
 using khtml::RenderTableCell;
 using khtml::RenderText;
 using khtml::RenderWidget;
-using khtml::InlineTextBoxArray;
+using khtml::InlineTextBox;
 using khtml::VISIBLE;
 
 using KIO::Job;
@@ -2278,8 +2278,7 @@ NSAttributedString *KWQKHTMLPart::attributedString(NodeImpl *_start, int startOf
                     }
                     else {
                         RenderText* textObj = static_cast<RenderText*>(renderer);
-                        InlineTextBoxArray runs = textObj->inlineTextBoxes();
-                        if (runs.count() == 0 && str.length() > 0 && !addedSpace) {
+                        if (!textObj->firstTextBox() && str.length() > 0 && !addedSpace) {
                             // We have no runs, but we do have a length.  This means we must be
                             // whitespace that collapsed away at the end of a line.
                             text += " ";
@@ -2287,13 +2286,13 @@ NSAttributedString *KWQKHTMLPart::attributedString(NodeImpl *_start, int startOf
                         }
                         else {
                             addedSpace = false;
-                            for (unsigned i = 0; i < runs.count(); i++) {
-                                int runStart = (start == -1) ? runs[i]->m_start : start;
-                                int runEnd = (end == -1) ? runs[i]->m_start + runs[i]->m_len : end;
-                                runEnd = QMIN(runEnd, runs[i]->m_start + runs[i]->m_len);
-                                if (runStart >= runs[i]->m_start &&
-                                    runStart < runs[i]->m_start + runs[i]->m_len) {
-                                    if (i == 0 && runs[0]->m_start == runStart && runStart > 0) {
+                            for (InlineTextBox* box = textObj->firstTextBox(); box; box = box->nextTextBox()) {
+                                int runStart = (start == -1) ? box->m_start : start;
+                                int runEnd = (end == -1) ? box->m_start + box->m_len : end;
+                                runEnd = kMin(runEnd, box->m_start + box->m_len);
+                                if (runStart >= box->m_start &&
+                                    runStart < box->m_start + box->m_len) {
+                                    if (box == textObj->firstTextBox() && box->m_start == runStart && runStart > 0) {
                                         needSpace = true; // collapsed space at the start
                                     }
                                     if (needSpace && !addedSpace) {
@@ -2309,7 +2308,7 @@ NSAttributedString *KWQKHTMLPart::attributedString(NodeImpl *_start, int startOf
                                     QString runText = str.mid(runStart, runEnd - runStart);
                                     runText.replace('\n', ' ');
                                     text += runText;
-                                    int nextRunStart = (i+1 < runs.count()) ? runs[i+1]->m_start : str.length(); // collapsed space between runs or at the end
+                                    int nextRunStart = box->nextTextBox() ? box->nextTextBox()->m_start : str.length(); // collapsed space between runs or at the end
                                     needSpace = nextRunStart > runEnd;
                                     [pendingStyledSpace release];
                                     pendingStyledSpace = nil;
diff --git a/WebCore/kwq/KWQRenderTreeDebug.cpp b/WebCore/kwq/KWQRenderTreeDebug.cpp
index fd1eaa5..2efd96f 100644
--- a/WebCore/kwq/KWQRenderTreeDebug.cpp
+++ b/WebCore/kwq/KWQRenderTreeDebug.cpp
@@ -42,7 +42,6 @@ using khtml::RenderWidget;
 using khtml::RenderText;
 using khtml::RenderCanvas;
 using khtml::InlineTextBox;
-using khtml::InlineTextBoxArray;
 using khtml::BorderValue;
 using khtml::EBorderStyle;
 using khtml::transparentColor;
@@ -237,10 +236,9 @@ static void write(QTextStream &ts, const RenderObject &o, int indent = 0)
     
     if (o.isText()) {
         const RenderText &text = static_cast<const RenderText &>(o);
-        InlineTextBoxArray runs = text.inlineTextBoxes();
-        for (unsigned int i = 0; i < runs.count(); i++) {
+        for (InlineTextBox* box = text.firstTextBox(); box; box = box->nextTextBox()) {
             writeIndent(ts, indent+1);
-            writeTextRun(ts, text, *runs[i]);
+            writeTextRun(ts, text, *box);
         }
     }
 

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list