2006-05-12 Eric Seidel <eseidel@apple.com>
authoreseidel <eseidel@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 13 May 2006 00:54:02 +0000 (00:54 +0000)
committereseidel <eseidel@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 13 May 2006 00:54:02 +0000 (00:54 +0000)
        Reviewed by beth.

        Split out render_line.* into separate files (one per class).

        * WebCore.xcodeproj/project.pbxproj:
        * dom/ContainerNode.cpp:
        * rendering/EllipsisBox.cpp: Added.
        * rendering/EllipsisBox.h: Added.
        (WebCore::EllipsisBox::EllipsisBox):
        * rendering/InlineBox.cpp: Added.
        * rendering/InlineBox.h: Added.
        (WebCore::InlineBox::InlineBox):
        (WebCore::InlineBox::~InlineBox):
        (WebCore::InlineBox::bottomOverflow):
        (WebCore::InlineBox::rightOverflow):
        * rendering/InlineFlowBox.cpp: Added.
        (WebCore::InlineFlowBox::placeBoxesHorizontally):
        * rendering/InlineFlowBox.h: Added.
        * rendering/InlineRunBox.h: Added.
        (WebCore::InlineRunBox::InlineRunBox):
        (WebCore::InlineRunBox::paintBackgroundAndBorder):
        (WebCore::InlineRunBox::paintDecorations):
        * rendering/InlineTextBox.h:
        * rendering/RenderBlock.h:
        * rendering/RenderFlow.h:
        * rendering/RenderReplaced.cpp:
        * rendering/RootInlineBox.cpp: Added.
        * rendering/RootInlineBox.h: Added.
        (WebCore::RootInlineBox::RootInlineBox):
        * rendering/render_line.h: Removed.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@14343 268f45cc-cd09-0410-ab3c-d52691b4dbfc

17 files changed:
WebCore/ChangeLog
WebCore/WebCore.xcodeproj/project.pbxproj
WebCore/dom/ContainerNode.cpp
WebCore/rendering/EllipsisBox.cpp [new file with mode: 0644]
WebCore/rendering/EllipsisBox.h [new file with mode: 0644]
WebCore/rendering/InlineBox.cpp [new file with mode: 0644]
WebCore/rendering/InlineBox.h [new file with mode: 0644]
WebCore/rendering/InlineFlowBox.cpp [new file with mode: 0644]
WebCore/rendering/InlineFlowBox.h [new file with mode: 0644]
WebCore/rendering/InlineRunBox.h [new file with mode: 0644]
WebCore/rendering/InlineTextBox.h
WebCore/rendering/RenderBlock.h
WebCore/rendering/RenderFlow.h
WebCore/rendering/RenderReplaced.cpp
WebCore/rendering/RootInlineBox.cpp [new file with mode: 0644]
WebCore/rendering/RootInlineBox.h [new file with mode: 0644]
WebCore/rendering/render_line.h [deleted file]

index dadd00e..6480695 100644 (file)
@@ -1,5 +1,38 @@
 2006-05-12  Eric Seidel  <eseidel@apple.com>
 
+        Reviewed by beth.
+
+        Split out render_line.* into separate files (one per class).
+
+        * WebCore.xcodeproj/project.pbxproj:
+        * dom/ContainerNode.cpp:
+        * rendering/EllipsisBox.cpp: Added.
+        * rendering/EllipsisBox.h: Added.
+        (WebCore::EllipsisBox::EllipsisBox):
+        * rendering/InlineBox.cpp: Added.
+        * rendering/InlineBox.h: Added.
+        (WebCore::InlineBox::InlineBox):
+        (WebCore::InlineBox::~InlineBox):
+        (WebCore::InlineBox::bottomOverflow):
+        (WebCore::InlineBox::rightOverflow):
+        * rendering/InlineFlowBox.cpp: Added.
+        (WebCore::InlineFlowBox::placeBoxesHorizontally):
+        * rendering/InlineFlowBox.h: Added.
+        * rendering/InlineRunBox.h: Added.
+        (WebCore::InlineRunBox::InlineRunBox):
+        (WebCore::InlineRunBox::paintBackgroundAndBorder):
+        (WebCore::InlineRunBox::paintDecorations):
+        * rendering/InlineTextBox.h:
+        * rendering/RenderBlock.h:
+        * rendering/RenderFlow.h:
+        * rendering/RenderReplaced.cpp:
+        * rendering/RootInlineBox.cpp: Added.
+        * rendering/RootInlineBox.h: Added.
+        (WebCore::RootInlineBox::RootInlineBox):
+        * rendering/render_line.h: Removed.
+
+2006-05-12  Eric Seidel  <eseidel@apple.com>
+
         Reviewed by hyatt.
 
         Split out table_layout.* into separate files (one per class).
index 9569dfc..56839e6 100644 (file)
                A8CFF04F0A154F09000A4234 /* FixedTableLayout.h in Headers */ = {isa = PBXBuildFile; fileRef = A8CFF04A0A154F09000A4234 /* FixedTableLayout.h */; };
                A8CFF0500A154F09000A4234 /* AutoTableLayout.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A8CFF04B0A154F09000A4234 /* AutoTableLayout.cpp */; };
                A8CFF0510A154F09000A4234 /* TableLayout.h in Headers */ = {isa = PBXBuildFile; fileRef = A8CFF04C0A154F09000A4234 /* TableLayout.h */; };
+               A8CFF5E10A155A05000A4234 /* RootInlineBox.h in Headers */ = {isa = PBXBuildFile; fileRef = A8CFF5DA0A155A05000A4234 /* RootInlineBox.h */; };
+               A8CFF5E20A155A05000A4234 /* InlineRunBox.h in Headers */ = {isa = PBXBuildFile; fileRef = A8CFF5DB0A155A05000A4234 /* InlineRunBox.h */; };
+               A8CFF5E30A155A05000A4234 /* InlineFlowBox.h in Headers */ = {isa = PBXBuildFile; fileRef = A8CFF5DC0A155A05000A4234 /* InlineFlowBox.h */; };
+               A8CFF5E40A155A05000A4234 /* InlineFlowBox.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A8CFF5DD0A155A05000A4234 /* InlineFlowBox.cpp */; };
+               A8CFF5E50A155A05000A4234 /* InlineBox.h in Headers */ = {isa = PBXBuildFile; fileRef = A8CFF5DE0A155A05000A4234 /* InlineBox.h */; };
+               A8CFF5E60A155A05000A4234 /* InlineBox.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A8CFF5DF0A155A05000A4234 /* InlineBox.cpp */; };
+               A8CFF5E70A155A05000A4234 /* RootInlineBox.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A8CFF5E00A155A05000A4234 /* RootInlineBox.cpp */; };
+               A8CFF6BE0A156118000A4234 /* EllipsisBox.h in Headers */ = {isa = PBXBuildFile; fileRef = A8CFF6BD0A156118000A4234 /* EllipsisBox.h */; };
+               A8CFF6CB0A1561CD000A4234 /* EllipsisBox.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A8CFF6CA0A1561CD000A4234 /* EllipsisBox.cpp */; };
                A8DF3FCE097FA0FC0052981B /* HTMLFormCollection.h in Headers */ = {isa = PBXBuildFile; fileRef = A8DF3FC6097FA0FB0052981B /* HTMLFormCollection.h */; };
                A8DF3FCF097FA0FC0052981B /* HTMLFormCollection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A8DF3FC7097FA0FB0052981B /* HTMLFormCollection.cpp */; };
                A8DF3FD0097FA0FC0052981B /* HTMLCollection.h in Headers */ = {isa = PBXBuildFile; fileRef = A8DF3FC8097FA0FB0052981B /* HTMLCollection.h */; };
                BCEA4878097D93020094C9E4 /* RenderInline.h in Headers */ = {isa = PBXBuildFile; fileRef = BCEA4839097D93020094C9E4 /* RenderInline.h */; };
                BCEA4879097D93020094C9E4 /* RenderLayer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCEA483A097D93020094C9E4 /* RenderLayer.cpp */; };
                BCEA487A097D93020094C9E4 /* RenderLayer.h in Headers */ = {isa = PBXBuildFile; fileRef = BCEA483B097D93020094C9E4 /* RenderLayer.h */; };
-               BCEA487B097D93020094C9E4 /* render_line.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCEA483C097D93020094C9E4 /* render_line.cpp */; };
-               BCEA487C097D93020094C9E4 /* render_line.h in Headers */ = {isa = PBXBuildFile; fileRef = BCEA483D097D93020094C9E4 /* render_line.h */; };
                BCEA487D097D93020094C9E4 /* render_list.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCEA483E097D93020094C9E4 /* render_list.cpp */; };
                BCEA487E097D93020094C9E4 /* render_list.h in Headers */ = {isa = PBXBuildFile; fileRef = BCEA483F097D93020094C9E4 /* render_list.h */; };
                BCEA487F097D93020094C9E4 /* RenderObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCEA4840097D93020094C9E4 /* RenderObject.cpp */; };
                A8CFF04A0A154F09000A4234 /* FixedTableLayout.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = FixedTableLayout.h; sourceTree = "<group>"; };
                A8CFF04B0A154F09000A4234 /* AutoTableLayout.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = AutoTableLayout.cpp; sourceTree = "<group>"; };
                A8CFF04C0A154F09000A4234 /* TableLayout.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = TableLayout.h; sourceTree = "<group>"; };
+               A8CFF5DA0A155A05000A4234 /* RootInlineBox.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = RootInlineBox.h; sourceTree = "<group>"; };
+               A8CFF5DB0A155A05000A4234 /* InlineRunBox.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = InlineRunBox.h; sourceTree = "<group>"; };
+               A8CFF5DC0A155A05000A4234 /* InlineFlowBox.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = InlineFlowBox.h; sourceTree = "<group>"; };
+               A8CFF5DD0A155A05000A4234 /* InlineFlowBox.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = InlineFlowBox.cpp; sourceTree = "<group>"; };
+               A8CFF5DE0A155A05000A4234 /* InlineBox.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = InlineBox.h; sourceTree = "<group>"; };
+               A8CFF5DF0A155A05000A4234 /* InlineBox.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = InlineBox.cpp; sourceTree = "<group>"; };
+               A8CFF5E00A155A05000A4234 /* RootInlineBox.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = RootInlineBox.cpp; sourceTree = "<group>"; };
+               A8CFF6BD0A156118000A4234 /* EllipsisBox.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = EllipsisBox.h; sourceTree = "<group>"; };
+               A8CFF6CA0A1561CD000A4234 /* EllipsisBox.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = EllipsisBox.cpp; sourceTree = "<group>"; };
                A8DF3FC6097FA0FB0052981B /* HTMLFormCollection.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = HTMLFormCollection.h; sourceTree = "<group>"; };
                A8DF3FC7097FA0FB0052981B /* HTMLFormCollection.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = HTMLFormCollection.cpp; sourceTree = "<group>"; };
                A8DF3FC8097FA0FB0052981B /* HTMLCollection.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = HTMLCollection.h; sourceTree = "<group>"; };
                BCEA4839097D93020094C9E4 /* RenderInline.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = RenderInline.h; sourceTree = "<group>"; };
                BCEA483A097D93020094C9E4 /* RenderLayer.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = RenderLayer.cpp; sourceTree = "<group>"; };
                BCEA483B097D93020094C9E4 /* RenderLayer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = RenderLayer.h; sourceTree = "<group>"; };
-               BCEA483C097D93020094C9E4 /* render_line.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = render_line.cpp; sourceTree = "<group>"; };
-               BCEA483D097D93020094C9E4 /* render_line.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = render_line.h; sourceTree = "<group>"; };
                BCEA483E097D93020094C9E4 /* render_list.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = render_list.cpp; sourceTree = "<group>"; };
                BCEA483F097D93020094C9E4 /* render_list.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = render_list.h; sourceTree = "<group>"; };
                BCEA4840097D93020094C9E4 /* RenderObject.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = RenderObject.cpp; sourceTree = "<group>"; };
                                BCEA4815097D93020094C9E4 /* break_lines.cpp */,
                                BCEA4816097D93020094C9E4 /* break_lines.h */,
                                BCEA4817097D93020094C9E4 /* DataRef.h */,
+                               A8CFF6CA0A1561CD000A4234 /* EllipsisBox.cpp */,
+                               A8CFF6BD0A156118000A4234 /* EllipsisBox.h */,
                                A8CFF0480A154F09000A4234 /* FixedTableLayout.cpp */,
                                A8CFF04A0A154F09000A4234 /* FixedTableLayout.h */,
                                935C477409AC4D8D00A6AAB4 /* GapRects.h */,
+                               A8CFF5DF0A155A05000A4234 /* InlineBox.cpp */,
+                               A8CFF5DE0A155A05000A4234 /* InlineBox.h */,
+                               A8CFF5DD0A155A05000A4234 /* InlineFlowBox.cpp */,
+                               A8CFF5DC0A155A05000A4234 /* InlineFlowBox.h */,
+                               A8CFF5DB0A155A05000A4234 /* InlineRunBox.h */,
                                BCEA481A097D93020094C9E4 /* InlineTextBox.cpp */,
                                BCEA481B097D93020094C9E4 /* InlineTextBox.h */,
                                935C476009AC4CD100A6AAB4 /* Length.h */,
                                BCEA4832097D93020094C9E4 /* render_form.cpp */,
                                BCEA4833097D93020094C9E4 /* render_form.h */,
-                               BCEA483C097D93020094C9E4 /* render_line.cpp */,
-                               BCEA483D097D93020094C9E4 /* render_line.h */,
                                BCEA483E097D93020094C9E4 /* render_list.cpp */,
                                BCEA483F097D93020094C9E4 /* render_list.h */,
                                BCEA4844097D93020094C9E4 /* render_style.cpp */,
                                93955A4103D72932008635CE /* RenderTreeAsText.h */,
                                A871DFE10A15376B00B12A68 /* RenderWidget.cpp */,
                                A871DFE00A15376B00B12A68 /* RenderWidget.h */,
+                               A8CFF5E00A155A05000A4234 /* RootInlineBox.cpp */,
+                               A8CFF5DA0A155A05000A4234 /* RootInlineBox.h */,
                                A8CFF04C0A154F09000A4234 /* TableLayout.h */,
                        );
                        path = rendering;
                                BCEA4876097D93020094C9E4 /* RenderImage.h in Headers */,
                                BCEA4878097D93020094C9E4 /* RenderInline.h in Headers */,
                                BCEA487A097D93020094C9E4 /* RenderLayer.h in Headers */,
-                               BCEA487C097D93020094C9E4 /* render_line.h in Headers */,
                                BCEA487E097D93020094C9E4 /* render_list.h in Headers */,
                                BCEA4880097D93020094C9E4 /* RenderObject.h in Headers */,
                                BCEA4884097D93020094C9E4 /* render_style.h in Headers */,
                                A8CFF04E0A154F09000A4234 /* AutoTableLayout.h in Headers */,
                                A8CFF04F0A154F09000A4234 /* FixedTableLayout.h in Headers */,
                                A8CFF0510A154F09000A4234 /* TableLayout.h in Headers */,
+                               A8CFF5E10A155A05000A4234 /* RootInlineBox.h in Headers */,
+                               A8CFF5E20A155A05000A4234 /* InlineRunBox.h in Headers */,
+                               A8CFF5E30A155A05000A4234 /* InlineFlowBox.h in Headers */,
+                               A8CFF5E50A155A05000A4234 /* InlineBox.h in Headers */,
+                               A8CFF6BE0A156118000A4234 /* EllipsisBox.h in Headers */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                BCEA4875097D93020094C9E4 /* RenderImage.cpp in Sources */,
                                BCEA4877097D93020094C9E4 /* RenderInline.cpp in Sources */,
                                BCEA4879097D93020094C9E4 /* RenderLayer.cpp in Sources */,
-                               BCEA487B097D93020094C9E4 /* render_line.cpp in Sources */,
                                BCEA487D097D93020094C9E4 /* render_list.cpp in Sources */,
                                BCEA487F097D93020094C9E4 /* RenderObject.cpp in Sources */,
                                BCEA4883097D93020094C9E4 /* render_style.cpp in Sources */,
                                A871DFE50A15376B00B12A68 /* RenderWidget.cpp in Sources */,
                                A8CFF04D0A154F09000A4234 /* FixedTableLayout.cpp in Sources */,
                                A8CFF0500A154F09000A4234 /* AutoTableLayout.cpp in Sources */,
+                               A8CFF5E40A155A05000A4234 /* InlineFlowBox.cpp in Sources */,
+                               A8CFF5E60A155A05000A4234 /* InlineBox.cpp in Sources */,
+                               A8CFF5E70A155A05000A4234 /* RootInlineBox.cpp in Sources */,
+                               A8CFF6CB0A1561CD000A4234 /* EllipsisBox.cpp in Sources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
index 83eccc0..6bc0857 100644 (file)
@@ -33,6 +33,7 @@
 #include "SystemTime.h"
 #include "dom2_eventsimpl.h"
 #include "RenderTheme.h"
+#include "RootInlineBox.h"
 
 namespace WebCore {
 
diff --git a/WebCore/rendering/EllipsisBox.cpp b/WebCore/rendering/EllipsisBox.cpp
new file mode 100644 (file)
index 0000000..94c8198
--- /dev/null
@@ -0,0 +1,84 @@
+/**
+* This file is part of the html renderer for KDE.
+ *
+ * Copyright (C) 2003, 2006 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 "config.h"
+#include "EllipsisBox.h"
+
+#include "GraphicsContext.h"
+
+namespace WebCore {
+
+void EllipsisBox::paint(RenderObject::PaintInfo& i, int _tx, int _ty)
+{
+    GraphicsContext* p = i.p;
+    RenderStyle* _style = m_firstLine ? m_object->firstLineStyle() : m_object->style();
+    if (_style->font() != p->font())
+        p->setFont(_style->font());
+
+    Color textColor = _style->color();
+    if (textColor != p->pen().color())
+        p->setPen(textColor);
+    bool setShadow = false;
+    if (_style->textShadow()) {
+        p->setShadow(IntSize(_style->textShadow()->x, _style->textShadow()->y),
+                     _style->textShadow()->blur, _style->textShadow()->color);
+        setShadow = true;
+    }
+
+    const String& str = m_str;
+    p->drawText(TextRun(str.impl()), IntPoint(m_x + _tx, m_y + _ty + m_baseline), TextStyle(0, 0, 0, false, _style->visuallyOrdered()));
+
+    if (setShadow)
+        p->clearShadow();
+
+    if (m_markupBox) {
+        // Paint the markup box
+        _tx += m_x + m_width - m_markupBox->xPos();
+        _ty += m_y + m_baseline - (m_markupBox->yPos() + m_markupBox->baseline());
+        m_markupBox->paint(i, _tx, _ty);
+    }
+}
+
+bool EllipsisBox::nodeAtPoint(RenderObject::NodeInfo& info, int x, int y, int tx, int ty)
+{
+    tx += m_x;
+    ty += m_y;
+
+    // Hit test the markup box.
+    if (m_markupBox) {
+        int mtx = tx + m_width - m_markupBox->xPos();
+        int mty = ty + m_baseline - (m_markupBox->yPos() + m_markupBox->baseline());
+        if (m_markupBox->nodeAtPoint(info, x, y, mtx, mty)) {
+            object()->setInnerNode(info);
+            return true;
+        }
+    }
+
+    if (object()->style()->visibility() == VISIBLE && IntRect(tx, ty, m_width, m_height).contains(x, y)) {
+        object()->setInnerNode(info);
+        return true;
+    }
+
+    return false;
+}
+
+}
diff --git a/WebCore/rendering/EllipsisBox.h b/WebCore/rendering/EllipsisBox.h
new file mode 100644 (file)
index 0000000..42c8cde
--- /dev/null
@@ -0,0 +1,52 @@
+/**
+* This file is part of the html renderer for KDE.
+ *
+ * Copyright (C) 2003, 2006 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 "InlineBox.h"
+
+namespace WebCore {
+
+class EllipsisBox : public InlineBox
+{
+public:
+    EllipsisBox(RenderObject* obj, const AtomicString& ellipsisStr, InlineFlowBox* p,
+                int w, int y, int h, int b, bool firstLine, InlineBox* markupBox)
+        : InlineBox(obj)
+        , m_str(ellipsisStr)
+    {
+        m_parent = p;
+        m_width = w;
+        m_y = y;
+        m_height = h;
+        m_baseline = b;
+        m_firstLine = firstLine;
+        m_constructed = true;
+        m_markupBox = markupBox;
+    }
+    
+    virtual void paint(RenderObject::PaintInfo& i, int _tx, int _ty);
+    virtual bool nodeAtPoint(RenderObject::NodeInfo& info, int _x, int _y, int _tx, int _ty);
+
+private:
+    AtomicString m_str;
+    InlineBox* m_markupBox;
+};
+
+}
\ No newline at end of file
diff --git a/WebCore/rendering/InlineBox.cpp b/WebCore/rendering/InlineBox.cpp
new file mode 100644 (file)
index 0000000..b8f18a5
--- /dev/null
@@ -0,0 +1,239 @@
+/**
+* This file is part of the html renderer for KDE.
+ *
+ * Copyright (C) 2003, 2006 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 "config.h"
+#include "InlineBox.h"
+
+#include "InlineFlowBox.h"
+#include "RootInlineBox.h"
+#include "RenderArena.h"
+
+using namespace std;
+
+namespace WebCore {
+    
+#ifndef NDEBUG
+static bool inInlineBoxDetach;
+#endif
+
+void InlineBox::remove()
+{ 
+    if (parent())
+        parent()->removeChild(this);
+}
+
+void InlineBox::destroy(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 destroy can find it.
+    *(size_t *)ptr = sz;
+}
+
+#ifndef NDEBUG
+void InlineBox::showTreeForThis() const
+{
+    if (m_object)
+        m_object->showTreeForThis();
+}
+#endif
+
+int InlineBox::caretMinOffset() const 
+{ 
+    return 0; 
+}
+
+int InlineBox::caretMaxOffset() const 
+{ 
+    return 1; 
+}
+
+unsigned InlineBox::caretMaxRenderedOffset() const 
+{ 
+    return 1; 
+}
+
+void InlineBox::dirtyLineBoxes()
+{
+    markDirty();
+    for (InlineFlowBox* curr = parent(); curr && !curr->isDirty(); curr = curr->parent())
+        curr->markDirty();
+}
+
+void InlineBox::deleteLine(RenderArena* arena)
+{
+    if (!m_extracted)
+        m_object->setInlineBoxWrapper(0);
+    destroy(arena);
+}
+
+void InlineBox::extractLine()
+{
+    m_extracted = true;
+    m_object->setInlineBoxWrapper(0);
+}
+
+void InlineBox::attachLine()
+{
+    m_extracted = false;
+    m_object->setInlineBoxWrapper(this);
+}
+
+void InlineBox::adjustPosition(int dx, int dy)
+{
+    m_x += dx;
+    m_y += dy;
+    if (m_object->isReplaced() || m_object->isBR())
+        m_object->setPos(m_object->xPos() + dx, m_object->yPos() + dy);
+}
+
+void InlineBox::paint(RenderObject::PaintInfo& i, int tx, int ty)
+{
+    if (!object()->shouldPaintWithinRoot(i) || (i.phase != PaintPhaseForeground && i.phase != PaintPhaseSelection))
+        return;
+
+    // Paint all phases of replaced elements atomically, as though the replaced element established its
+    // own stacking context.  (See Appendix E.2, section 6.4 on inline block/table elements in the CSS2.1
+    // specification.)
+    bool paintSelectionOnly = i.phase == PaintPhaseSelection;
+    RenderObject::PaintInfo info(i);
+    info.phase = paintSelectionOnly ? i.phase : PaintPhaseBlockBackground;
+    object()->paint(info, tx, ty);
+    if (!paintSelectionOnly) {
+        info.phase = PaintPhaseChildBlockBackgrounds;
+        object()->paint(info, tx, ty);
+        info.phase = PaintPhaseFloat;
+        object()->paint(info, tx, ty);
+        info.phase = PaintPhaseForeground;
+        object()->paint(info, tx, ty);
+        info.phase = PaintPhaseOutline;
+        object()->paint(info, tx, ty);
+    }
+}
+
+bool InlineBox::nodeAtPoint(RenderObject::NodeInfo& i, int x, int y, int tx, int ty)
+{
+    // Hit test all phases of replaced elements atomically, as though the replaced element established its
+    // own stacking context.  (See Appendix E.2, section 6.4 on inline block/table elements in the CSS2.1
+    // specification.)
+    return object()->hitTest(i, x, y, tx, ty);
+}
+
+RootInlineBox* InlineBox::root()
+{ 
+    if (m_parent)
+        return m_parent->root(); 
+    return static_cast<RootInlineBox*>(this);
+}
+
+bool InlineBox::nextOnLineExists() const
+{
+    if (!parent())
+        return false;
+    
+    if (nextOnLine())
+        return true;
+    
+    return parent()->nextOnLineExists();
+}
+
+bool InlineBox::prevOnLineExists() const
+{
+    if (!parent())
+        return false;
+    
+    if (prevOnLine())
+        return true;
+    
+    return parent()->prevOnLineExists();
+}
+
+InlineBox* InlineBox::firstLeafChild()
+{
+    return this;
+}
+
+InlineBox* InlineBox::lastLeafChild()
+{
+    return this;
+}
+
+InlineBox* InlineBox::nextLeafChild()
+{
+    return parent() ? parent()->firstLeafChildAfterBox(this) : 0;
+}
+
+InlineBox* InlineBox::prevLeafChild()
+{
+    return parent() ? parent()->lastLeafChildBeforeBox(this) : 0;
+}
+
+RenderObject::SelectionState InlineBox::selectionState()
+{
+    return object()->selectionState();
+}
+
+bool InlineBox::canAccommodateEllipsis(bool ltr, int blockEdge, int ellipsisWidth)
+{
+    // Non-replaced elements can always accommodate an ellipsis.
+    if (!m_object || !m_object->isReplaced())
+        return true;
+    
+    IntRect boxRect(m_x, 0, m_width, 10);
+    IntRect ellipsisRect(ltr ? blockEdge - ellipsisWidth : blockEdge, 0, ellipsisWidth, 10);
+    return !(boxRect.intersects(ellipsisRect));
+}
+
+int InlineBox::placeEllipsisBox(bool ltr, int blockEdge, int ellipsisWidth, bool&)
+{
+    // Use -1 to mean "we didn't set the position."
+    return -1;
+}
+
+}
+
+#ifndef NDEBUG
+
+void showTree(const WebCore::InlineBox* b)
+{
+    if (b)
+        b->showTreeForThis();
+}
+
+#endif
diff --git a/WebCore/rendering/InlineBox.h b/WebCore/rendering/InlineBox.h
new file mode 100644 (file)
index 0000000..7d6a57d
--- /dev/null
@@ -0,0 +1,189 @@
+/*
+ * This file is part of the line box implementation for KDE.
+ *
+ * Copyright (C) 2003, 2006 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 InlineBox_H
+#define InlineBox_H
+
+#include "RenderObject.h" // needed for RenderObject::PaintInfo
+
+namespace WebCore {
+
+class RootInlineBox;
+
+// InlineBox represents a rectangle that occurs on a line.  It corresponds to
+// some RenderObject (i.e., it represents a portion of that RenderObject).
+class InlineBox
+{
+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_dirty(false)
+        , m_extracted(false)
+        , m_next(0)
+        , m_prev(0)
+        , m_parent(0)
+    {
+    }
+
+    virtual ~InlineBox() { }
+
+    virtual void destroy(RenderArena*);
+
+    virtual void deleteLine(RenderArena*);
+    virtual void extractLine();
+    virtual void attachLine();
+
+    virtual bool isLineBreak() const { return false; }
+
+    virtual void adjustPosition(int dx, int dy);
+
+    virtual void paint(RenderObject::PaintInfo&, int _tx, int _ty);
+    virtual bool nodeAtPoint(RenderObject::NodeInfo&, int x, int y, int tx, int ty);
+    
+    // Overloaded new operator.
+    void* operator new(size_t, RenderArena*) throw();
+
+    // Overridden to prevent the normal delete from being called.
+    void operator delete(void*, size_t);
+
+private:
+    // The normal operator new is disallowed.
+    void* operator new(size_t) throw();
+    
+public:
+#ifndef NDEBUG
+    void showTreeForThis() const;
+#endif
+    virtual bool isInlineBox() { return false; }
+    virtual bool isInlineFlowBox() { return false; }
+    virtual bool isContainer() { return false; }
+    virtual bool isInlineTextBox() { return false; }
+    virtual bool isRootInlineBox() { return false; }
+    
+    virtual bool isText() const { return false; }
+
+    bool isConstructed() { return m_constructed; }
+    virtual void setConstructed() {
+        m_constructed = true;
+        if (m_next)
+            m_next->setConstructed();
+    }
+    void setExtracted(bool b = true) { m_extracted = b; }
+    
+    void setFirstLineStyleBit(bool f) { m_firstLine = f; }
+    bool isFirstLineStyle() const { return m_firstLine; }
+
+    void remove();
+
+    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; }
+    bool nextOnLineExists() const;
+    bool prevOnLineExists() const;
+
+    virtual InlineBox* firstLeafChild();
+    virtual InlineBox* lastLeafChild();
+    InlineBox* nextLeafChild();
+    InlineBox* prevLeafChild();
+        
+    RenderObject* object() const { return m_object; }
+
+    InlineFlowBox* parent() const { return m_parent; }
+    void setParent(InlineFlowBox* par) { m_parent = par; }
+
+    RootInlineBox* root();
+    
+    void setWidth(int w) { m_width = w; }
+    int width() const { return m_width; }
+
+    void setXPos(int x) { m_x = x; }
+    int xPos() const { return m_x; }
+
+    void setYPos(int y) { m_y = y; }
+    int yPos() const { return m_y; }
+
+    void setHeight(int h) { m_height = h; }
+    int height() const { return m_height; }
+    
+    void setBaseline(int b) { m_baseline = b; }
+    int baseline() const { return m_baseline; }
+
+    virtual bool hasTextChildren() { return true; }
+
+    virtual int topOverflow() { return yPos(); }
+    virtual int bottomOverflow() { return yPos() + height(); }
+    virtual int leftOverflow() { return xPos(); }
+    virtual int rightOverflow() { return xPos() + width(); }
+
+    virtual int caretMinOffset() const;
+    virtual int caretMaxOffset() const;
+    virtual unsigned caretMaxRenderedOffset() const;
+    
+    virtual void clearTruncation() {};
+
+    bool isDirty() const { return m_dirty; }
+    void markDirty(bool dirty=true) { m_dirty = dirty; }
+
+    void dirtyLineBoxes();
+    
+    virtual RenderObject::SelectionState selectionState();
+
+    virtual bool canAccommodateEllipsis(bool ltr, int blockEdge, int ellipsisWidth);
+    virtual int placeEllipsisBox(bool ltr, int blockEdge, int ellipsisWidth, bool&);
+
+public: // FIXME: Would like to make this protected, but methods are accessing these
+        // members over in the part.
+    RenderObject* m_object;
+
+    int m_x;
+    int m_y;
+    int m_width;
+    int m_height;
+    int m_baseline;
+    
+    bool m_firstLine : 1;
+    bool m_constructed : 1;
+    bool m_dirty : 1;
+    bool m_extracted : 1;
+
+    InlineBox* m_next; // The next element on the same line as us.
+    InlineBox* m_prev; // The previous element on the same line as us.
+
+    InlineFlowBox* m_parent; // The box that contains us.
+};
+
+} //namespace
+
+#ifndef NDEBUG
+// Outside the WebCore namespace for ease of invocation from gdb.
+void showTree(const WebCore::InlineBox*);
+#endif
+
+#endif
diff --git a/WebCore/rendering/InlineFlowBox.cpp b/WebCore/rendering/InlineFlowBox.cpp
new file mode 100644 (file)
index 0000000..1370b63
--- /dev/null
@@ -0,0 +1,847 @@
+/**
+* This file is part of the html renderer for KDE.
+ *
+ * Copyright (C) 2003, 2006 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 "config.h"
+#include "InlineFlowBox.h"
+
+#include "CachedImage.h"
+#include "Document.h"
+#include "ElipseBox.h"
+#include "GraphicsContext.h"
+#include "InlineTextBox.h"
+#include "RootInlineBox.h"
+#include "RenderBlock.h"
+#include "RenderFlow.h"
+#include "render_list.h"
+#include "RenderTableCell.h"
+
+using namespace std;
+
+namespace WebCore {
+
+RenderFlow* InlineFlowBox::flowObject()
+{
+    return static_cast<RenderFlow*>(m_object);
+}
+
+int InlineFlowBox::marginLeft()
+{
+    if (!includeLeftEdge())
+        return 0;
+    
+    Length margin = object()->style()->marginLeft();
+    if (margin.isAuto())
+        return 0;
+    if (margin.isFixed())
+        return margin.value();
+    return object()->marginLeft();
+}
+
+int InlineFlowBox::marginRight()
+{
+    if (!includeRightEdge())
+        return 0;
+    
+    Length margin = object()->style()->marginRight();
+    if (margin.isAuto())
+        return 0;
+    if (margin.isFixed())
+        return margin.value();
+    return object()->marginRight();
+}
+
+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;
+}
+
+void InlineFlowBox::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->isText())
+        m_hasTextChildren = true;
+    if (child->object()->selectionState() != RenderObject::SelectionNone)
+        root()->setHasSelectedChildren(true);
+}
+
+void InlineFlowBox::removeChild(InlineBox* child)
+{
+    if (!m_dirty)
+        dirtyLineBoxes();
+
+    root()->childRemoved(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());
+    
+    child->setParent(0);
+}
+
+void InlineFlowBox::deleteLine(RenderArena* arena)
+{
+    InlineBox* child = m_firstChild;
+    InlineBox* next = 0;
+    while (child) {
+        next = child->nextOnLine();
+        child->deleteLine(arena);
+        child = next;
+    }
+    
+    static_cast<RenderFlow*>(m_object)->removeLineBox(this);
+    destroy(arena);
+}
+
+void InlineFlowBox::extractLine()
+{
+    if (!m_extracted)
+        static_cast<RenderFlow*>(m_object)->extractLineBox(this);
+    for (InlineBox* child = m_firstChild; child; child = child->nextOnLine())
+        child->extractLine();
+}
+
+void InlineFlowBox::attachLine()
+{
+    if (m_extracted)
+        static_cast<RenderFlow*>(m_object)->attachLineBox(this);
+    for (InlineBox* child = m_firstChild; child; child = child->nextOnLine())
+        child->attachLine();
+}
+
+void InlineFlowBox::adjustPosition(int dx, int dy)
+{
+    InlineRunBox::adjustPosition(dx, dy);
+    for (InlineBox* child = m_firstChild; child; child = child->nextOnLine())
+        child->adjustPosition(dx, dy);
+}
+
+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 || parent == object())
+            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, int& leftPosition, int& rightPosition, bool& needsWordSpacing)
+{
+    // Set our x position.
+    setXPos(x);
+    leftPosition = min(x, leftPosition);
+
+    int startX = x;
+    x += borderLeft() + paddingLeft();
+    
+    for (InlineBox* curr = firstChild(); curr; curr = curr->nextOnLine()) {
+        if (curr->object()->isText()) {
+            InlineTextBox* text = static_cast<InlineTextBox*>(curr);
+            RenderText* rt = static_cast<RenderText*>(text->object());
+            if (rt->length()) {
+                if (needsWordSpacing && QChar(rt->text()[text->start()]).isSpace())
+                    x += rt->font(m_firstLine)->wordSpacing();
+                needsWordSpacing = !QChar(rt->text()[text->end()]).isSpace();
+            }
+            text->setXPos(x);
+            int shadowLeft = 0;
+            int shadowRight = 0;
+            for (ShadowData* shadow = rt->style()->textShadow(); shadow; shadow = shadow->next) {
+                shadowLeft = min(shadowLeft, shadow->x - shadow->blur);
+                shadowRight = max(shadowRight, shadow->x + shadow->blur);
+            }
+            leftPosition = min(x + shadowLeft, leftPosition);
+            rightPosition = max(x + text->width() + shadowRight, rightPosition);
+            m_maxHorizontalShadow = max(max(shadowRight, -shadowLeft), m_maxHorizontalShadow);
+            x += text->width();
+        } else {
+            if (curr->object()->isPositioned()) {
+                if (curr->object()->parent()->style()->direction() == LTR)
+                    curr->setXPos(x);
+                else
+                    // Our offset that we cache needs to be from the edge of the right border box and
+                    // not the left border box.  We have to subtract |x| from the width of the block
+                    // (which can be obtained from the root line box).
+                    curr->setXPos(root()->object()->width()-x);
+                continue; // The positioned object has no effect on the width.
+            }
+            if (curr->object()->isInlineFlow()) {
+                InlineFlowBox* flow = static_cast<InlineFlowBox*>(curr);
+                if (curr->object()->isCompact()) {
+                    int ignoredX = x;
+                    flow->placeBoxesHorizontally(ignoredX, leftPosition, rightPosition, needsWordSpacing);
+                } else {
+                    x += flow->marginLeft();
+                    x = flow->placeBoxesHorizontally(x, leftPosition, rightPosition, needsWordSpacing);
+                    x += flow->marginRight();
+                }
+            } else if (!curr->object()->isCompact() && (!curr->object()->isListMarker() || static_cast<RenderListMarker*>(curr->object())->isInside())) {
+                x += curr->object()->marginLeft();
+                curr->setXPos(x);
+                leftPosition = min(x, leftPosition);
+                rightPosition = max(x + curr->width(), rightPosition);
+                x += curr->width() + curr->object()->marginRight();
+            }
+        }
+    }
+
+    x += borderRight() + paddingRight();
+    setWidth(x-startX);
+    rightPosition = max(xPos() + width(), rightPosition);
+
+    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.  Note that we can't simply use !style()->htmlHacks(),
+    // because that would match almost strict mode as well.
+    RenderObject* curr = object();
+    while (curr && !curr->element())
+        curr = curr->container();
+    bool strictMode = (curr && curr->document()->inStrictMode());
+    
+    computeLogicalBoxHeights(maxPositionTop, maxPositionBottom, maxAscent, maxDescent, strictMode);
+
+    if (maxAscent + maxDescent < max(maxPositionTop, maxPositionBottom))
+        adjustMaxAscentAndDescent(maxAscent, maxDescent, maxPositionTop, maxPositionBottom);
+
+    int maxHeight = maxAscent + maxDescent;
+    int topPosition = heightOfBlock;
+    int bottomPosition = heightOfBlock;
+    int selectionTop = heightOfBlock;
+    int selectionBottom = heightOfBlock;
+    placeBoxesVertically(heightOfBlock, maxHeight, maxAscent, strictMode, topPosition, bottomPosition, selectionTop, selectionBottom);
+
+    setVerticalOverflowPositions(topPosition, bottomPosition);
+    setVerticalSelectionPositions(selectionTop, selectionBottom);
+
+    // Shrink boxes with no text children in quirks and almost strict mode.
+    if (!strictMode)
+        shrinkBoxesWithNoTextChildren(topPosition, bottomPosition);
+    
+    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->object()->isPositioned())
+            continue; // Positioned placeholders don't affect calculations.
+        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 >= max(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 (isRootInlineBox()) {
+        // Examine our root box.
+        setHeight(object()->lineHeight(m_firstLine, true));
+        bool isTableCell = object()->isTableCell();
+        if (isTableCell) {
+            RenderTableCell* tableCell = static_cast<RenderTableCell*>(object());
+            setBaseline(tableCell->RenderBlock::baselinePosition(m_firstLine, true));
+        }
+        else
+            setBaseline(object()->baselinePosition(m_firstLine, true));
+        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()) {
+        if (curr->object()->isPositioned())
+            continue; // Positioned placeholders don't affect calculations.
+        
+        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,
+                                         int& topPosition, int& bottomPosition, int& selectionTop, int& selectionBottom)
+{
+    if (isRootInlineBox())
+        setYPos(y + maxAscent - baseline());// Place our root box.
+    
+    for (InlineBox* curr = firstChild(); curr; curr = curr->nextOnLine()) {
+        if (curr->object()->isPositioned())
+            continue; // Positioned placeholders don't affect calculations.
+        
+        // Adjust boxes to use their real box y/height and not the logical height (as dictated by
+        // line-height).
+        if (curr->isInlineFlowBox())
+            static_cast<InlineFlowBox*>(curr)->placeBoxesVertically(y, maxHeight, maxAscent, strictMode, topPosition, bottomPosition, selectionTop, selectionBottom);
+
+        bool childAffectsTopBottomPos = true;
+        if (curr->yPos() == PositionTop)
+            curr->setYPos(y);
+        else if (curr->yPos() == PositionBottom)
+            curr->setYPos(y + maxHeight - curr->height());
+        else {
+            if (!curr->hasTextChildren() && !strictMode)
+                childAffectsTopBottomPos = false;
+            curr->setYPos(curr->yPos() + y + maxAscent - curr->baseline());
+        }
+        
+        int newY = curr->yPos();
+        int newHeight = curr->height();
+        int newBaseline = curr->baseline();
+        int overflowTop = 0;
+        int overflowBottom = 0;
+        if (curr->isText() || curr->isInlineFlowBox()) {
+            const Font& font = curr->object()->font(m_firstLine);
+            newBaseline = font.ascent();
+            newY += curr->baseline() - newBaseline;
+            newHeight = newBaseline + font.descent();
+            for (ShadowData* shadow = curr->object()->style()->textShadow(); shadow; shadow = shadow->next) {
+                overflowTop = min(overflowTop, shadow->y - shadow->blur);
+                overflowBottom = max(overflowBottom, shadow->y + shadow->blur);
+            }
+            if (curr->isInlineFlowBox()) {
+                newHeight += curr->object()->borderTop() + curr->object()->paddingTop() +
+                            curr->object()->borderBottom() + curr->object()->paddingBottom();
+                newY -= curr->object()->borderTop() + curr->object()->paddingTop();
+                newBaseline += curr->object()->borderTop() + curr->object()->paddingTop();
+            }
+        }
+        else if (!curr->object()->isBR()) {
+            newY += curr->object()->marginTop();
+            newHeight = curr->height() - (curr->object()->marginTop() + curr->object()->marginBottom());
+            overflowTop = curr->object()->overflowTop(false);
+            overflowBottom = curr->object()->overflowHeight(false) - newHeight;
+        }
+
+        curr->setYPos(newY);
+        curr->setHeight(newHeight);
+        curr->setBaseline(newBaseline);
+
+        if (childAffectsTopBottomPos) {
+            selectionTop = min(selectionTop, newY);
+            selectionBottom = max(selectionBottom, newY + newHeight);
+            topPosition = min(topPosition, newY + overflowTop);
+            bottomPosition = max(bottomPosition, newY + newHeight + overflowBottom);
+        }
+    }
+
+    if (isRootInlineBox()) {
+        const Font& font = object()->font(m_firstLine);
+        setHeight(font.ascent() + font.descent());
+        setYPos(yPos() + baseline() - font.ascent());
+        setBaseline(font.ascent());
+        if (hasTextChildren() || strictMode) {
+            selectionTop = min(selectionTop, yPos());
+            selectionBottom = max(selectionBottom, yPos() + height());
+        }
+    }
+}
+
+void InlineFlowBox::shrinkBoxesWithNoTextChildren(int topPos, int bottomPos)
+{
+    // First shrink our kids.
+    for (InlineBox* curr = firstChild(); curr; curr = curr->nextOnLine()) {
+        if (curr->object()->isPositioned())
+            continue; // Positioned placeholders don't affect calculations.
+        
+        if (curr->isInlineFlowBox())
+            static_cast<InlineFlowBox*>(curr)->shrinkBoxesWithNoTextChildren(topPos, bottomPos);
+    }
+
+    // See if we have text children. If not, then we need to shrink ourselves to fit on the line.
+    if (!hasTextChildren()) {
+        if (yPos() < topPos)
+            setYPos(topPos);
+        if (yPos() + height() > bottomPos)
+            setHeight(bottomPos - yPos());
+        if (baseline() > height())
+            setBaseline(height());
+    }
+}
+
+bool InlineFlowBox::nodeAtPoint(RenderObject::NodeInfo& i, int x, int y, int tx, int ty)
+{
+    // Check children first.
+    for (InlineBox* curr = lastChild(); curr; curr = curr->prevOnLine()) {
+        if (!curr->object()->layer() && curr->nodeAtPoint(i, x, y, tx, ty)) {
+            object()->setInnerNode(i);
+            return true;
+        }
+    }
+
+    // Now check ourselves.
+    IntRect rect(tx + m_x, ty + m_y, m_width, m_height);
+    if (object()->style()->visibility() == VISIBLE && rect.contains(x, y)) {
+        object()->setInnerNode(i);
+        return true;
+    }
+    
+    return false;
+}
+
+void InlineFlowBox::paint(RenderObject::PaintInfo& i, int tx, int ty)
+{
+    int xPos = tx + m_x - object()->maximalOutlineSize(i.phase);
+    int w = width() + 2 * object()->maximalOutlineSize(i.phase);
+    bool intersectsDamageRect = xPos < i.r.right() && xPos + w > i.r.x();
+    
+    if (intersectsDamageRect && i.phase != PaintPhaseChildOutlines) {
+        if (i.phase == PaintPhaseOutline || i.phase == PaintPhaseSelfOutline) {
+            // Add ourselves to the paint info struct's list of inlines that need to paint their
+            // outlines.
+            if (object()->style()->visibility() == VISIBLE && object()->style()->outlineWidth() > 0 &&
+                !object()->isInlineContinuation() && !isRootInlineBox()) {
+                i.outlineObjects->add(flowObject());
+            }
+        }
+        else {
+            // 1. Paint our background and border.
+            paintBackgroundAndBorder(i, tx, ty);
+            
+            // 2. Paint our underline and overline.
+            paintDecorations(i, tx, ty, false);
+        }
+    }
+
+    PaintPhase paintPhase = i.phase == PaintPhaseChildOutlines ? PaintPhaseOutline : i.phase;
+    RenderObject::PaintInfo childInfo(i);
+    childInfo.phase = paintPhase;
+
+    // 3. Paint our children.
+    if (paintPhase != PaintPhaseSelfOutline) {
+        for (InlineBox* curr = firstChild(); curr; curr = curr->nextOnLine()) {
+            if (!curr->object()->layer())
+                curr->paint(childInfo, tx, ty);
+        }
+    }
+
+    // 4. Paint our strike-through
+    if (intersectsDamageRect && (i.phase == PaintPhaseForeground || i.phase == PaintPhaseSelection))
+        paintDecorations(i, tx, ty, true);
+}
+
+void InlineFlowBox::paintBackgrounds(GraphicsContext* p, const Color& c, const BackgroundLayer* bgLayer,
+                                     int my, int mh, int _tx, int _ty, int w, int h)
+{
+    if (!bgLayer)
+        return;
+    paintBackgrounds(p, c, bgLayer->next(), my, mh, _tx, _ty, w, h);
+    paintBackground(p, c, bgLayer, my, mh, _tx, _ty, w, h);
+}
+
+void InlineFlowBox::paintBackground(GraphicsContext* p, const Color& c, const BackgroundLayer* bgLayer,
+                                    int my, int mh, int _tx, int _ty, int w, int h)
+{
+    CachedImage* bg = bgLayer->backgroundImage();
+    bool hasBackgroundImage = bg && bg->canRender();
+    if (!hasBackgroundImage || (!prevLineBox() && !nextLineBox()) || !parent())
+        object()->paintBackgroundExtended(p, c, bgLayer, my, mh, _tx, _ty, w, h, 
+                                          borderLeft(), borderRight(), paddingLeft(), paddingRight());
+    else {
+        // We have a background image that spans multiple lines.
+        // We need to adjust _tx and _ty by the width of all previous lines.
+        // Think of background painting on inlines as though you had one long line, a single continuous
+        // strip.  Even though that strip has been broken up across multiple lines, you still paint it
+        // as though you had one single line.  This means each line has to pick up the background where
+        // the previous line left off.
+        // FIXME: What the heck do we do with RTL here? The math we're using is obviously not right,
+        // but it isn't even clear how this should work at all.
+        int xOffsetOnLine = 0;
+        for (InlineRunBox* curr = prevLineBox(); curr; curr = curr->prevLineBox())
+            xOffsetOnLine += curr->width();
+        int startX = _tx - xOffsetOnLine;
+        int totalWidth = xOffsetOnLine;
+        for (InlineRunBox* curr = this; curr; curr = curr->nextLineBox())
+            totalWidth += curr->width();
+        p->save();
+        p->addClip(IntRect(_tx, _ty, width(), height()));
+        object()->paintBackgroundExtended(p, c, bgLayer, my, mh, startX, _ty,
+                                          totalWidth, h, borderLeft(), borderRight(), paddingLeft(), paddingRight());
+        p->restore();
+    }
+}
+
+void InlineFlowBox::paintBackgroundAndBorder(RenderObject::PaintInfo& i, int _tx, int _ty)
+{
+    if (!object()->shouldPaintWithinRoot(i) || object()->style()->visibility() != VISIBLE ||
+        i.phase != PaintPhaseForeground)
+        return;
+
+    // Move x/y to our coordinates.
+    _tx += m_x;
+    _ty += m_y;
+    
+    int w = width();
+    int h = height();
+
+    int my = max(_ty, i.r.y());
+    int mh;
+    if (_ty < i.r.y())
+        mh = max(0, h - (i.r.y() - _ty));
+    else
+        mh = min(i.r.height(), h);
+
+    GraphicsContext* p = i.p;
+    
+    // You can use p::first-line to specify a background. If so, the root line boxes for
+    // a line may actually have to paint a background.
+    RenderStyle* styleToUse = object()->style(m_firstLine);
+    if ((!parent() && m_firstLine && styleToUse != object()->style()) || 
+        (parent() && object()->shouldPaintBackgroundOrBorder())) {
+        Color c = styleToUse->backgroundColor();
+        paintBackgrounds(p, c, styleToUse->backgroundLayers(), my, mh, _tx, _ty, w, h);
+
+        // :first-line cannot be used to put borders on a line. Always paint borders with our
+        // non-first-line style.
+        if (parent() && object()->style()->hasBorder()) {
+            CachedImage* borderImage = object()->style()->borderImage().image();
+            bool hasBorderImage = borderImage && borderImage->canRender();
+            if (hasBorderImage && !borderImage->isLoaded())
+                return; // Don't paint anything while we wait for the image to load.
+            
+            // The simple case is where we either have no border image or we are the only box for this object.  In those
+            // cases only a single call to draw is required.
+            if (!hasBorderImage || (!prevLineBox() && !nextLineBox()))
+                object()->paintBorder(p, _tx, _ty, w, h, object()->style(), includeLeftEdge(), includeRightEdge());
+            else {
+                // We have a border image that spans multiple lines.
+                // We need to adjust _tx and _ty by the width of all previous lines.
+                // Think of border image painting on inlines as though you had one long line, a single continuous
+                // strip.  Even though that strip has been broken up across multiple lines, you still paint it
+                // as though you had one single line.  This means each line has to pick up the image where
+                // the previous line left off.
+                // FIXME: What the heck do we do with RTL here? The math we're using is obviously not right,
+                // but it isn't even clear how this should work at all.
+                int xOffsetOnLine = 0;
+                for (InlineRunBox* curr = prevLineBox(); curr; curr = curr->prevLineBox())
+                    xOffsetOnLine += curr->width();
+                int startX = _tx - xOffsetOnLine;
+                int totalWidth = xOffsetOnLine;
+                for (InlineRunBox* curr = this; curr; curr = curr->nextLineBox())
+                    totalWidth += curr->width();
+                p->save();
+                p->addClip(IntRect(_tx, _ty, width(), height()));
+                object()->paintBorder(p, startX, _ty, totalWidth, h, object()->style());
+                p->restore();
+            }
+        }
+    }
+}
+
+static bool shouldDrawDecoration(RenderObject* obj)
+{
+    for (RenderObject* curr = obj->firstChild(); curr; curr = curr->nextSibling()) {
+        if (curr->isInlineFlow())
+            return true;
+        if (curr->isText() && !curr->isBR()) {
+            if (!curr->style()->collapseWhiteSpace())
+                return true;
+            Node* currElement = curr->element();
+            if (!currElement)
+                return true;
+            if (!currElement->isTextNode())
+                return true;
+            if (!static_cast<Text*>(currElement)->containsOnlyWhitespace())
+                return true;
+        }
+    }
+    return false;
+}
+
+void InlineFlowBox::paintDecorations(RenderObject::PaintInfo& i, int _tx, int _ty, bool paintedChildren)
+{
+    // Paint text decorations like underlines/overlines. We only do this if we aren't in quirks mode (i.e., in
+    // almost-strict mode or strict mode).
+    if (object()->style()->htmlHacks() || !object()->shouldPaintWithinRoot(i) ||
+        object()->style()->visibility() != VISIBLE)
+        return;
+
+    GraphicsContext* p = i.p;
+    _tx += m_x;
+    _ty += m_y;
+    RenderStyle* styleToUse = object()->style(m_firstLine);
+    int deco = parent() ? styleToUse->textDecoration() : styleToUse->textDecorationsInEffect();
+    if (deco != TDNONE && 
+        ((!paintedChildren && ((deco & UNDERLINE) || (deco & OVERLINE))) || (paintedChildren && (deco & LINE_THROUGH))) &&
+        shouldDrawDecoration(object())) {
+        int x = m_x + borderLeft() + paddingLeft();
+        int w = m_width - (borderLeft() + paddingLeft() + borderRight() + paddingRight());
+        RootInlineBox* rootLine = root();
+        if (rootLine->ellipsisBox()) {
+            int ellipsisX = rootLine->ellipsisBox()->xPos();
+            int ellipsisWidth = rootLine->ellipsisBox()->width();
+            
+            // FIXME: Will need to work with RTL
+            if (rootLine == this) {
+                if (x + w >= ellipsisX + ellipsisWidth)
+                    w -= (x + w - ellipsisX - ellipsisWidth);
+            }
+            else {
+                if (x >= ellipsisX)
+                    return;
+                if (x + w >= ellipsisX)
+                    w -= (x + w - ellipsisX);
+            }
+        }
+            
+        // Set up the appropriate text-shadow effect for the decoration.
+        // FIXME: Support multiple shadow effects.  Need more from the CG API before we can do this.
+        bool setShadow = false;
+        if (styleToUse->textShadow()) {
+            p->setShadow(IntSize(styleToUse->textShadow()->x, styleToUse->textShadow()->y),
+                         styleToUse->textShadow()->blur, styleToUse->textShadow()->color);
+            setShadow = true;
+        }
+        
+        // We must have child boxes and have decorations defined.
+        _tx += borderLeft() + paddingLeft();
+        
+        Color underline, overline, linethrough;
+        underline = overline = linethrough = styleToUse->color();
+        if (!parent())
+            object()->getTextDecorationColors(deco, underline, overline, linethrough);
+
+        if (styleToUse->font() != p->font())
+            p->setFont(styleToUse->font());
+
+        bool isPrinting = object()->document()->printing();
+        if (deco & UNDERLINE && !paintedChildren) {
+            p->setPen(underline);
+            p->drawLineForText(IntPoint(_tx, _ty), m_baseline, w, isPrinting);
+        }
+        if (deco & OVERLINE && !paintedChildren) {
+            p->setPen(overline);
+            p->drawLineForText(IntPoint(_tx, _ty), 0, w, isPrinting);
+        }
+        if (deco & LINE_THROUGH && paintedChildren) {
+            p->setPen(linethrough);
+            p->drawLineForText(IntPoint(_tx, _ty), 2*m_baseline/3, w, isPrinting);
+        }
+
+        if (setShadow)
+            p->clearShadow();
+    }
+}
+
+InlineBox* InlineFlowBox::firstLeafChild()
+{
+    return firstLeafChildAfterBox();
+}
+
+InlineBox* InlineFlowBox::lastLeafChild()
+{
+    return lastLeafChildBeforeBox();
+}
+
+InlineBox* InlineFlowBox::firstLeafChildAfterBox(InlineBox* start)
+{
+    InlineBox* leaf = 0;
+    for (InlineBox* box = start ? start->nextOnLine() : firstChild(); box && !leaf; box = box->nextOnLine())
+        leaf = box->firstLeafChild();
+    if (start && !leaf && parent())
+        return parent()->firstLeafChildAfterBox(this);
+    return leaf;
+}
+
+InlineBox* InlineFlowBox::lastLeafChildBeforeBox(InlineBox* start)
+{
+    InlineBox* leaf = 0;
+    for (InlineBox* box = start ? start->prevOnLine() : lastChild(); box && !leaf; box = box->prevOnLine())
+        leaf = box->lastLeafChild();
+    if (start && !leaf && parent())
+        return parent()->lastLeafChildBeforeBox(this);
+    return leaf;
+}
+
+RenderObject::SelectionState InlineFlowBox::selectionState()
+{
+    return RenderObject::SelectionNone;
+}
+
+bool InlineFlowBox::canAccommodateEllipsis(bool ltr, int blockEdge, int ellipsisWidth)
+{
+    for (InlineBox *box = firstChild(); box; box = box->nextOnLine()) {
+        if (!box->canAccommodateEllipsis(ltr, blockEdge, ellipsisWidth))
+            return false;
+    }
+    return true;
+}
+
+int InlineFlowBox::placeEllipsisBox(bool ltr, int blockEdge, int ellipsisWidth, bool& foundBox)
+{
+    int result = -1;
+    for (InlineBox *box = firstChild(); box; box = box->nextOnLine()) {
+        int currResult = box->placeEllipsisBox(ltr, blockEdge, ellipsisWidth, foundBox);
+        if (currResult != -1 && result == -1)
+            result = currResult;
+    }
+    return result;
+}
+
+void InlineFlowBox::clearTruncation()
+{
+    for (InlineBox *box = firstChild(); box; box = box->nextOnLine())
+        box->clearTruncation();
+}
+
+} // namespace
diff --git a/WebCore/rendering/InlineFlowBox.h b/WebCore/rendering/InlineFlowBox.h
new file mode 100644 (file)
index 0000000..db61b6a
--- /dev/null
@@ -0,0 +1,139 @@
+/*
+ * This file is part of the line box implementation for KDE.
+ *
+ * Copyright (C) 2003, 2006 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 InlineFlowBox_H
+#define InlineFlowBox_H
+
+#include "InlineRunBox.h"
+
+namespace WebCore {
+
+class InlineFlowBox : public InlineRunBox
+{
+public:
+    InlineFlowBox(RenderObject* obj)
+    :InlineRunBox(obj)
+    {
+        m_firstChild = 0;
+        m_lastChild = 0;
+        m_includeLeftEdge = m_includeRightEdge = false;
+        m_hasTextChildren = false;
+        m_maxHorizontalShadow = 0;
+    }
+
+    RenderFlow* flowObject();
+
+    virtual bool isInlineFlowBox() { return true; }
+
+    InlineFlowBox* prevFlowBox() const { return static_cast<InlineFlowBox*>(m_prevLine); }
+    InlineFlowBox* nextFlowBox() const { return static_cast<InlineFlowBox*>(m_nextLine); }
+    
+    InlineBox* firstChild() { return m_firstChild; }
+    InlineBox* lastChild() { return m_lastChild; }
+
+    virtual InlineBox* firstLeafChild();
+    virtual InlineBox* lastLeafChild();
+    InlineBox* firstLeafChildAfterBox(InlineBox* start=0);
+    InlineBox* lastLeafChildBeforeBox(InlineBox* start=0);
+        
+    virtual void setConstructed() {
+        InlineBox::setConstructed();
+        if (m_firstChild)
+            m_firstChild->setConstructed();
+    }
+    void addToLine(InlineBox* child);
+
+    virtual void deleteLine(RenderArena* arena);
+    virtual void extractLine();
+    virtual void attachLine();
+    virtual void adjustPosition(int dx, int dy);
+
+    virtual void clearTruncation();
+    
+    virtual void paintBackgroundAndBorder(RenderObject::PaintInfo& i, int _tx, int _ty);
+    void paintBackgrounds(GraphicsContext* p, const Color& c, const BackgroundLayer* bgLayer,
+                          int my, int mh, int _tx, int _ty, int w, int h);
+    void paintBackground(GraphicsContext* p, const Color& c, const BackgroundLayer* bgLayer,
+                         int my, int mh, int _tx, int _ty, int w, int h);
+    virtual void paintDecorations(RenderObject::PaintInfo& i, int _tx, int _ty, bool paintedChildren = false);
+    virtual void paint(RenderObject::PaintInfo& i, int _tx, int _ty);
+    virtual bool nodeAtPoint(RenderObject::NodeInfo& i, int x, int y, int tx, int ty);
+
+    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 onEndChain(RenderObject* endObject);
+    int placeBoxesHorizontally(int x, int& leftPosition, int& rightPosition, bool& needsWordSpacing);
+    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,
+                              int& topPosition, int& bottomPosition, int& selectionTop, int& selectionBottom);
+    void shrinkBoxesWithNoTextChildren(int topPosition, int bottomPosition);
+    
+    virtual void setVerticalOverflowPositions(int top, int bottom) {}
+    virtual void setVerticalSelectionPositions(int top, int bottom) {}
+    int maxHorizontalShadow() const { return m_maxHorizontalShadow; }
+
+    void removeChild(InlineBox* child);
+    
+    virtual RenderObject::SelectionState selectionState();
+
+    virtual bool canAccommodateEllipsis(bool ltr, int blockEdge, int ellipsisWidth);
+    virtual int placeEllipsisBox(bool ltr, int blockEdge, int ellipsisWidth, bool&);
+
+protected:
+    InlineBox* m_firstChild;
+    InlineBox* m_lastChild;
+    int m_maxHorizontalShadow;
+    bool m_includeLeftEdge : 1;
+    bool m_includeRightEdge : 1;
+    bool m_hasTextChildren : 1;
+};
+
+} //namespace
+
+#ifndef NDEBUG
+// Outside the WebCore namespace for ease of invocation from gdb.
+void showTree(const WebCore::InlineBox*);
+#endif
+
+#endif
diff --git a/WebCore/rendering/InlineRunBox.h b/WebCore/rendering/InlineRunBox.h
new file mode 100644 (file)
index 0000000..ea75859
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * This file is part of the line box implementation for KDE.
+ *
+ * Copyright (C) 2003, 2006 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 InlineRunBox_H
+#define InlineRunBox_H
+
+#include "InlineBox.h"
+
+namespace WebCore {
+
+class InlineRunBox : public InlineBox
+{
+public:
+    InlineRunBox(RenderObject* obj)
+        : InlineBox(obj)
+        , m_prevLine(0)
+        , m_nextLine(0)
+    {
+    }
+
+    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; }
+
+    virtual void paintBackgroundAndBorder(RenderObject::PaintInfo&, int _tx, int _ty) {};
+    virtual void paintDecorations(RenderObject::PaintInfo&, int _tx, int _ty, bool paintedChildren = false) {};
+    
+protected:
+    InlineRunBox* m_prevLine;  // The previous box that also uses our RenderObject
+    InlineRunBox* m_nextLine;  // The next box that also uses our RenderObject
+};
+
+} //namespace
+
+#endif
index af3bf35..ee86ce7 100644 (file)
@@ -27,7 +27,7 @@
 
 #include "DocumentMarker.h"
 #include "RenderText.h"
-#include "render_line.h"
+#include "InlineRunBox.h"
 
 namespace WebCore {
 
index 4914c9b..cac6a2a 100644 (file)
 
 #include "GapRects.h"
 #include "RenderFlow.h"
+#include "RootInlineBox.h"
 
 namespace WebCore {
 
 class Position;
+class RootInlineBox;
 
 enum CaretType {
     CursorCaret,
@@ -102,13 +104,13 @@ public:
     }
 
     virtual void addChildToFlow(RenderObject* newChild, RenderObject* beforeChild);
-    virtual void removeChild(RenderObject *oldChild);
+    virtual void removeChild(RenderObject*);
 
     virtual void repaintObjectsBeforeLayout();
     virtual void repaintFloatingDescendants();
     virtual void getAbsoluteRepaintRectIncludingFloats(IntRect& bounds, IntRect& fullBounds);
 
-    virtual void setStyle(RenderStyle* _style);
+    virtual void setStyle(RenderStyle*);
 
     virtual void layout();
     virtual void layoutBlock(bool relayoutChildren);
@@ -125,16 +127,16 @@ public:
     virtual RenderObject* layoutLegend(bool relayoutChildren) { return 0; };
     
     // the implementation of the following functions is in bidi.cpp
-    void bidiReorderLine(const BidiIterator &start, const BidiIterator &end, BidiState &bidi );
-    RootInlineBox* determineStartPosition(bool fullLayout, BidiIterator &start, BidiState &bidi);
+    void bidiReorderLine(const BidiIterator& start, const BidiIterator& end, BidiState &bidi );
+    RootInlineBox* determineStartPosition(bool fullLayout, BidiIteratorstart, BidiState &bidi);
     RootInlineBox* determineEndPosition(RootInlineBox* startBox, BidiIterator& cleanLineStart,
                                         BidiStatus& cleanLineBidiStatus, BidiContext*& cleanLineBidiContext,
                                         int& yPos);
     bool matchedEndLine(const BidiIterator& start, const BidiStatus& status, BidiContext* context,
                         const BidiIterator& endLineStart, const BidiStatus& endLineStatus,
                         BidiContext* endLineContext, RootInlineBox*& endLine, int& endYPos);
-    int skipWhitespace(BidiIterator &, BidiState &);
-    BidiIterator findNextLineBreak(BidiIterator &start, BidiState &info );
+    int skipWhitespace(BidiIterator, BidiState &);
+    BidiIterator findNextLineBreak(BidiIteratorstart, BidiState &info );
     RootInlineBox* constructLine(const BidiIterator& start, const BidiIterator& end);
     InlineFlowBox* createLineBoxes(RenderObject* obj);
     int tabWidth(bool isWhitespacePre);
index 047da3f..93975e8 100644 (file)
@@ -26,7 +26,6 @@
 #define RENDER_FLOW_H
 
 #include "RenderContainer.h"
-#include "render_line.h"
 
 namespace WebCore {
 
index 3411be8..68d771b 100644 (file)
@@ -24,7 +24,6 @@
 #include "config.h"
 #include "RenderReplaced.h"
 
-#include "render_line.h"
 #include "RenderBlock.h"
 
 using namespace std;
diff --git a/WebCore/rendering/RootInlineBox.cpp b/WebCore/rendering/RootInlineBox.cpp
new file mode 100644 (file)
index 0000000..bf75122
--- /dev/null
@@ -0,0 +1,285 @@
+/**
+* This file is part of the html renderer for KDE.
+ *
+ * Copyright (C) 2003, 2006 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 "config.h"
+#include "RootInlineBox.h"
+
+#include "ElipseBox.h"
+#include "RenderBlock.h"
+
+using namespace std;
+
+namespace WebCore {
+
+void RootInlineBox::destroy(RenderArena* arena)
+{
+    detachEllipsisBox(arena);
+    InlineFlowBox::destroy(arena);
+}
+
+void RootInlineBox::detachEllipsisBox(RenderArena* arena)
+{
+    if (m_ellipsisBox) {
+        m_ellipsisBox->destroy(arena);
+        m_ellipsisBox = 0;
+    }
+}
+
+void RootInlineBox::clearTruncation()
+{
+    if (m_ellipsisBox) {
+        detachEllipsisBox(m_object->renderArena());
+        InlineFlowBox::clearTruncation();
+    }
+}
+
+bool RootInlineBox::canAccommodateEllipsis(bool ltr, int blockEdge, int lineBoxEdge, int ellipsisWidth)
+{
+    // First sanity-check the unoverflowed width of the whole line to see if there is sufficient room.
+    int delta = ltr ? lineBoxEdge - blockEdge : blockEdge - lineBoxEdge;
+    if (width() - delta < ellipsisWidth)
+        return false;
+
+    // Next iterate over all the line boxes on the line.  If we find a replaced element that intersects
+    // then we refuse to accommodate the ellipsis.  Otherwise we're ok.
+    return InlineFlowBox::canAccommodateEllipsis(ltr, blockEdge, ellipsisWidth);
+}
+
+void RootInlineBox::placeEllipsis(const AtomicString& ellipsisStr,  bool ltr, int blockEdge, int ellipsisWidth,
+                                  InlineBox* markupBox)
+{
+    // Create an ellipsis box.
+    m_ellipsisBox = new (m_object->renderArena()) EllipsisBox(m_object, ellipsisStr, this, 
+                                                              ellipsisWidth - (markupBox ? markupBox->width() : 0),
+                                                              yPos(), height(), baseline(), !prevRootBox(),
+                                                              markupBox);
+
+    if (ltr && (xPos() + width() + ellipsisWidth) <= blockEdge) {
+        m_ellipsisBox->m_x = xPos() + width();
+        return;
+    }
+
+    // Now attempt to find the nearest glyph horizontally and place just to the right (or left in RTL)
+    // of that glyph.  Mark all of the objects that intersect the ellipsis box as not painting (as being
+    // truncated).
+    bool foundBox = false;
+    m_ellipsisBox->m_x = placeEllipsisBox(ltr, blockEdge, ellipsisWidth, foundBox);
+}
+
+int RootInlineBox::placeEllipsisBox(bool ltr, int blockEdge, int ellipsisWidth, bool& foundBox)
+{
+    int result = InlineFlowBox::placeEllipsisBox(ltr, blockEdge, ellipsisWidth, foundBox);
+    if (result == -1)
+        result = ltr ? blockEdge - ellipsisWidth : blockEdge;
+    return result;
+}
+
+void RootInlineBox::paintEllipsisBox(RenderObject::PaintInfo& i, int _tx, int _ty) const
+{
+    if (m_ellipsisBox && object()->shouldPaintWithinRoot(i) && object()->style()->visibility() == VISIBLE &&
+        i.phase == PaintPhaseForeground)
+        m_ellipsisBox->paint(i, _tx, _ty);
+}
+
+void RootInlineBox::paint(RenderObject::PaintInfo& i, int tx, int ty)
+{
+    InlineFlowBox::paint(i, tx, ty);
+    paintEllipsisBox(i, tx, ty);
+}
+
+bool RootInlineBox::nodeAtPoint(RenderObject::NodeInfo& i, int x, int y, int tx, int ty)
+{
+    if (m_ellipsisBox && object()->style()->visibility() == VISIBLE) {
+        if (m_ellipsisBox->nodeAtPoint(i, x, y, tx, ty)) {
+            object()->setInnerNode(i);
+            return true;
+        }
+    }
+    return InlineFlowBox::nodeAtPoint(i, x, y, tx, ty);
+}
+
+void RootInlineBox::adjustPosition(int dx, int dy)
+{
+    InlineFlowBox::adjustPosition(dx, dy);
+    m_topOverflow += dy;
+    m_bottomOverflow += dy;
+    m_blockHeight += dy;
+}
+
+void RootInlineBox::childRemoved(InlineBox* box)
+{
+    if (box->object() == m_lineBreakObj)
+        setLineBreakInfo(0, 0, 0, 0);
+
+    RootInlineBox* prev = prevRootBox();
+    if (prev && prev->lineBreakObj() == box->object()) {
+        prev->setLineBreakInfo(0, 0, 0, 0);
+        prev->markDirty();
+    }
+}
+
+GapRects RootInlineBox::fillLineSelectionGap(int selTop, int selHeight, RenderBlock* rootBlock, int blockX, int blockY, int tx, int ty, 
+                                             const RenderObject::PaintInfo* i)
+{
+    GapRects result;
+    RenderObject::SelectionState lineState = selectionState();
+
+    bool leftGap, rightGap;
+    block()->getHorizontalSelectionGapInfo(lineState, leftGap, rightGap);
+
+    InlineBox* firstBox = firstSelectedBox();
+    InlineBox* lastBox = lastSelectedBox();
+    if (leftGap)
+        result.uniteLeft(block()->fillLeftSelectionGap(firstBox->parent()->object(), 
+                                                       firstBox->xPos(), selTop, selHeight, 
+                                                       rootBlock, blockX, blockY, tx, ty, i));
+    if (rightGap)
+        result.uniteRight(block()->fillRightSelectionGap(lastBox->parent()->object(), 
+                                                         lastBox->xPos() + lastBox->width(), selTop, selHeight, 
+                                                         rootBlock, blockX, blockY, tx, ty, i));
+
+    if (firstBox && firstBox != lastBox) {
+        // Now fill in any gaps on the line that occurred between two selected elements.
+        int lastX = firstBox->xPos() + firstBox->width();
+        for (InlineBox* box = firstBox->nextLeafChild(); box; box = box->nextLeafChild()) {
+            if (box->selectionState() != RenderObject::SelectionNone) {
+                result.uniteCenter(block()->fillHorizontalSelectionGap(box->parent()->object(),
+                                                                       lastX + tx, selTop + ty,
+                                                                       box->xPos() - lastX, selHeight, i));
+                lastX = box->xPos() + box->width();
+            }
+            if (box == lastBox)
+                break;
+        }
+    }
+      
+    return result;
+}
+
+void RootInlineBox::setHasSelectedChildren(bool b)
+{
+    if (m_hasSelectedChildren == b)
+        return;
+    m_hasSelectedChildren = b;
+}
+
+RenderObject::SelectionState RootInlineBox::selectionState()
+{
+    // Walk over all of the selected boxes.
+    RenderObject::SelectionState state = RenderObject::SelectionNone;
+    for (InlineBox* box = firstLeafChild(); box; box = box->nextLeafChild()) {
+        RenderObject::SelectionState boxState = box->selectionState();
+        if ((boxState == RenderObject::SelectionStart && state == RenderObject::SelectionEnd) ||
+            (boxState == RenderObject::SelectionEnd && state == RenderObject::SelectionStart))
+            state = RenderObject::SelectionBoth;
+        else if (state == RenderObject::SelectionNone ||
+                 ((boxState == RenderObject::SelectionStart || boxState == RenderObject::SelectionEnd) &&
+                  (state == RenderObject::SelectionNone || state == RenderObject::SelectionInside)))
+            state = boxState;
+        if (state == RenderObject::SelectionBoth)
+            break;
+    }
+    
+    return state;
+}
+
+InlineBox* RootInlineBox::firstSelectedBox()
+{
+    for (InlineBox* box = firstLeafChild(); box; box = box->nextLeafChild())
+        if (box->selectionState() != RenderObject::SelectionNone)
+            return box;
+    return 0;
+}
+
+InlineBox* RootInlineBox::lastSelectedBox()
+{
+    for (InlineBox* box = lastLeafChild(); box; box = box->prevLeafChild())
+        if (box->selectionState() != RenderObject::SelectionNone)
+            return box;
+    return 0;
+}
+
+int RootInlineBox::selectionTop()
+{
+    if (!prevRootBox())
+        return m_selectionTop;
+    
+    int prevBottom = prevRootBox()->selectionBottom();
+    if (prevBottom < m_selectionTop && block()->containsFloats()) {
+        // This line has actually been moved further down, probably from a large line-height, but possibly because the
+        // line was forced to clear floats.  If so, let's check the offsets, and only be willing to use the previous
+        // line's bottom overflow if the offsets are greater on both sides.
+        int prevLeft = block()->leftOffset(prevBottom);
+        int prevRight = block()->rightOffset(prevBottom);
+        int newLeft = block()->leftOffset(m_selectionTop);
+        int newRight = block()->rightOffset(m_selectionTop);
+        if (prevLeft > newLeft || prevRight < newRight)
+            return m_selectionTop;
+    }
+    
+    return prevBottom;
+}
+
+RenderBlock* RootInlineBox::block() const
+{
+    return static_cast<RenderBlock*>(m_object);
+}
+
+InlineBox* RootInlineBox::closestLeafChildForXPos(int _x, int _tx)
+{
+    InlineBox *firstLeaf = firstLeafChildAfterBox();
+    InlineBox *lastLeaf = lastLeafChildBeforeBox();
+    if (firstLeaf == lastLeaf)
+        return firstLeaf;
+    
+    // Avoid returning a list marker when possible.
+    if (_x <= _tx + firstLeaf->m_x && !firstLeaf->object()->isListMarker())
+        // The x coordinate is less or equal to left edge of the firstLeaf.
+        // Return it.
+        return firstLeaf;
+    
+    if (_x >= _tx + lastLeaf->m_x + lastLeaf->m_width && !lastLeaf->object()->isListMarker())
+        // The x coordinate is greater or equal to right edge of the lastLeaf.
+        // Return it.
+        return lastLeaf;
+
+    for (InlineBox *leaf = firstLeaf; leaf && leaf != lastLeaf; leaf = leaf->nextLeafChild()) {
+        if (!leaf->object()->isListMarker()) {
+            int leafX = _tx + leaf->m_x;
+            if (_x < leafX + leaf->m_width)
+                // The x coordinate is less than the right edge of the box.
+                // Return it.
+                return leaf;
+        }
+    }
+
+    return lastLeaf;
+}
+
+void RootInlineBox::setLineBreakInfo(RenderObject* obj, unsigned breakPos, BidiStatus* status, BidiContext* context)
+{
+    m_lineBreakObj = obj;
+    m_lineBreakPos = breakPos;
+    m_lineBreakContext = context;
+    if (status)
+        m_lineBreakBidiStatus = *status;
+}
+
+}
diff --git a/WebCore/rendering/RootInlineBox.h b/WebCore/rendering/RootInlineBox.h
new file mode 100644 (file)
index 0000000..901487f
--- /dev/null
@@ -0,0 +1,152 @@
+/*
+ * This file is part of the line box implementation for KDE.
+ *
+ * Copyright (C) 2003, 2006 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 RootInlineBox_H
+#define RootInlineBox_H
+
+#include "bidi.h"
+#include "InlineFlowBox.h"
+
+namespace WebCore {
+
+class EllipsisBox;
+struct GapRects;
+
+class RootInlineBox : public InlineFlowBox
+{
+public:
+    RootInlineBox(RenderObject* obj)
+        : InlineFlowBox(obj)
+        , m_topOverflow(0)
+        , m_bottomOverflow(0)
+        , m_leftOverflow(0)
+        , m_rightOverflow(0)
+        , m_lineBreakObj(0)
+        , m_lineBreakPos(0)
+        , m_lineBreakContext(0)
+        , m_blockHeight(0)
+        , m_endsWithBreak(false)
+        , m_hasSelectedChildren(false)
+        , m_ellipsisBox(0)
+    {
+    }
+        
+    virtual void destroy(RenderArena* renderArena);
+    void detachEllipsisBox(RenderArena* renderArena);
+
+    RootInlineBox* nextRootBox() { return static_cast<RootInlineBox*>(m_nextLine); }
+    RootInlineBox* prevRootBox() { return static_cast<RootInlineBox*>(m_prevLine); }
+
+    virtual void adjustPosition(int dx, int dy);
+    
+    virtual bool isRootInlineBox() { return true; }
+    virtual int topOverflow() { return m_topOverflow; }
+    virtual int bottomOverflow() { return m_bottomOverflow; }
+    virtual int leftOverflow() { return m_leftOverflow; }
+    virtual int rightOverflow() { return m_rightOverflow; }
+    virtual void setVerticalOverflowPositions(int top, int bottom) { m_topOverflow = top; m_bottomOverflow = bottom; }
+    virtual void setVerticalSelectionPositions(int top, int bottom) { m_selectionTop = top; m_selectionBottom = bottom; }
+    void setHorizontalOverflowPositions(int left, int right) { m_leftOverflow = left; m_rightOverflow = right; }
+    void setLineBreakInfo(RenderObject* obj, unsigned breakPos, BidiStatus* status, BidiContext* context);
+    void setLineBreakPos(int p) { m_lineBreakPos = p; }
+
+    void setBlockHeight(int h) { m_blockHeight = h; }
+    void setEndsWithBreak(bool b) { m_endsWithBreak = b; }
+    
+    int blockHeight() const { return m_blockHeight; }
+    bool endsWithBreak() const { return m_endsWithBreak; }
+    RenderObject* lineBreakObj() const { return m_lineBreakObj; }
+    unsigned lineBreakPos() const { return m_lineBreakPos; }
+    BidiStatus lineBreakBidiStatus() const { return m_lineBreakBidiStatus; }
+    BidiContext* lineBreakBidiContext() const { return m_lineBreakContext.get(); }
+
+    void childRemoved(InlineBox* box);
+
+    bool canAccommodateEllipsis(bool ltr, int blockEdge, int lineBoxEdge, int ellipsisWidth);
+    void placeEllipsis(const AtomicString& ellipsisStr, bool ltr, int blockEdge, int ellipsisWidth, InlineBox* markupBox = 0);
+    virtual int placeEllipsisBox(bool ltr, int blockEdge, int ellipsisWidth, bool&);
+
+    EllipsisBox* ellipsisBox() const { return m_ellipsisBox; }
+    void paintEllipsisBox(RenderObject::PaintInfo& i, int _tx, int _ty) const;
+    bool hitTestEllipsisBox(RenderObject::NodeInfo& info, int _x, int _y, int _tx, int _ty,
+                            HitTestAction hitTestAction, bool inBox);
+    
+    virtual void clearTruncation();
+
+    virtual void paint(RenderObject::PaintInfo& i, int _tx, int _ty);
+    virtual bool nodeAtPoint(RenderObject::NodeInfo& i, int x, int y, int tx, int ty);
+
+    bool hasSelectedChildren() const { return m_hasSelectedChildren; }
+    void setHasSelectedChildren(bool b);
+    
+    virtual RenderObject::SelectionState selectionState();
+    InlineBox* firstSelectedBox();
+    InlineBox* lastSelectedBox();
+    
+    GapRects fillLineSelectionGap(int selTop, int selHeight, RenderBlock* rootBlock, int blockX, int blockY, 
+                                  int tx, int ty, const RenderObject::PaintInfo* i);
+    
+    RenderBlock* block() const;
+
+    int selectionTop();
+    int selectionBottom() { return m_selectionBottom; }
+    int selectionHeight() { return max(0, selectionBottom() - selectionTop()); }
+    InlineBox* closestLeafChildForXPos(int _x, int _tx);
+
+protected:
+    // Normally we are only as tall as the style on our block dictates, but we might have content
+    // that spills out above the height of our font (e.g, a tall image), or something that extends further
+    // below our line (e.g., a child whose font has a huge descent).
+    int m_topOverflow;
+    int m_bottomOverflow;
+    int m_leftOverflow;
+    int m_rightOverflow;
+
+    int m_selectionTop;
+    int m_selectionBottom;
+
+    // Where this line ended.  The exact object and the position within that object are stored so that
+    // we can create a BidiIterator beginning just after the end of this line.
+    RenderObject* m_lineBreakObj;
+    unsigned m_lineBreakPos;
+    
+    BidiStatus m_lineBreakBidiStatus;
+    RefPtr<BidiContext> m_lineBreakContext;
+    
+    // The height of the block at the end of this line.  This is where the next line starts.
+    int m_blockHeight;
+    
+    // Whether the line ends with a <br>.
+    bool m_endsWithBreak : 1;
+    
+    // Whether we have any children selected (this bit will also be set if the <br> that terminates our
+    // line is selected).
+    bool m_hasSelectedChildren : 1;
+
+    // An inline text box that represents our text truncation string.
+    EllipsisBox* m_ellipsisBox;
+};
+
+} //namespace
+
+#endif
diff --git a/WebCore/rendering/render_line.h b/WebCore/rendering/render_line.h
deleted file mode 100644 (file)
index bc690db..0000000
+++ /dev/null
@@ -1,420 +0,0 @@
-/*
- * This file is part of the line box implementation for KDE.
- *
- * Copyright (C) 2003, 2006 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
-
-#include "bidi.h"
-#include "RenderObject.h"
-
-namespace WebCore {
-
-class AtomicString;
-class EllipsisBox;
-class InlineFlowBox;
-class RootInlineBox;
-class RenderBlock;
-class RenderFlow;
-
-struct GapRects;
-
-// 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_dirty(false), m_extracted(false)
-    {
-        m_next = 0;
-        m_prev = 0;
-        m_parent = 0;
-    }
-
-    virtual ~InlineBox() {};
-
-    virtual void destroy(RenderArena* renderArena);
-
-    virtual void deleteLine(RenderArena* arena);
-    virtual void extractLine();
-    virtual void attachLine();
-
-    virtual bool isLineBreak() const { return false; }
-
-    virtual void adjustPosition(int dx, int dy);
-
-    virtual void paint(RenderObject::PaintInfo& i, int _tx, int _ty);
-    virtual bool nodeAtPoint(RenderObject::NodeInfo& i, int x, int y, int tx, int ty);
-    
-    // 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:
-#ifndef NDEBUG
-    void showTreeForThis() const;
-#endif
-    virtual bool isInlineBox() { return false; }
-    virtual bool isInlineFlowBox() { return false; }
-    virtual bool isContainer() { return false; }
-    virtual bool isInlineTextBox() { return false; }
-    virtual bool isRootInlineBox() { return false; }
-    
-    virtual bool isText() const { return false; }
-
-    bool isConstructed() { return m_constructed; }
-    virtual void setConstructed() {
-        m_constructed = true;
-        if (m_next)
-            m_next->setConstructed();
-    }
-    void setExtracted(bool b = true) { m_extracted = b; }
-    
-    void setFirstLineStyleBit(bool f) { m_firstLine = f; }
-    bool isFirstLineStyle() const { return m_firstLine; }
-
-    void remove();
-
-    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; }
-    bool nextOnLineExists() const;
-    bool prevOnLineExists() const;
-
-    virtual InlineBox* firstLeafChild();
-    virtual InlineBox* lastLeafChild();
-    InlineBox* nextLeafChild();
-    InlineBox* prevLeafChild();
-        
-    RenderObject* object() const { return m_object; }
-
-    InlineFlowBox* parent() const { return m_parent; }
-    void setParent(InlineFlowBox* par) { m_parent = par; }
-
-    RootInlineBox* root();
-    
-    void setWidth(int w) { m_width = w; }
-    int width() const { return m_width; }
-
-    void setXPos(int x) { m_x = x; }
-    int xPos() const { return m_x; }
-
-    void setYPos(int y) { m_y = y; }
-    int yPos() const { return m_y; }
-
-    void setHeight(int h) { m_height = h; }
-    int height() const { return m_height; }
-    
-    void setBaseline(int b) { m_baseline = b; }
-    int baseline() const { return m_baseline; }
-
-    virtual bool hasTextChildren() { return true; }
-
-    virtual int topOverflow() { return yPos(); }
-    virtual int bottomOverflow() { return yPos()+height(); }
-    virtual int leftOverflow() { return xPos(); }
-    virtual int rightOverflow() { return xPos()+width(); }
-
-    virtual int caretMinOffset() const;
-    virtual int caretMaxOffset() const;
-    virtual unsigned caretMaxRenderedOffset() const;
-    
-    virtual void clearTruncation() {};
-
-    bool isDirty() const { return m_dirty; }
-    void markDirty(bool dirty=true) { m_dirty = dirty; }
-
-    void dirtyLineBoxes();
-    
-    virtual RenderObject::SelectionState selectionState();
-
-    virtual bool canAccommodateEllipsis(bool ltr, int blockEdge, int ellipsisWidth);
-    virtual int placeEllipsisBox(bool ltr, int blockEdge, int ellipsisWidth, bool&);
-
-public: // FIXME: Would like to make this protected, but methods are accessing these
-        // members over in the part.
-    RenderObject* m_object;
-
-    int m_x;
-    int m_y;
-    int m_width;
-    int m_height;
-    int m_baseline;
-    
-    bool m_firstLine : 1;
-    bool m_constructed : 1;
-    bool m_dirty : 1;
-    bool m_extracted : 1;
-
-    InlineBox* m_next; // The next element on the same line as us.
-    InlineBox* m_prev; // The previous element on the same line as us.
-
-    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() const { return m_prevLine; }
-    InlineRunBox* nextLineBox() const { return m_nextLine; }
-    void setNextLineBox(InlineRunBox* n) { m_nextLine = n; }
-    void setPreviousLineBox(InlineRunBox* p) { m_prevLine = p; }
-
-    virtual void paintBackgroundAndBorder(RenderObject::PaintInfo& i, int _tx, int _ty) {};
-    virtual void paintDecorations(RenderObject::PaintInfo& i, int _tx, int _ty, bool paintedChildren = false) {};
-    
-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;
-        m_maxHorizontalShadow = 0;
-    }
-
-    RenderFlow* flowObject();
-
-    virtual bool isInlineFlowBox() { return true; }
-
-    InlineFlowBox* prevFlowBox() const { return static_cast<InlineFlowBox*>(m_prevLine); }
-    InlineFlowBox* nextFlowBox() const { return static_cast<InlineFlowBox*>(m_nextLine); }
-    
-    InlineBox* firstChild() { return m_firstChild; }
-    InlineBox* lastChild() { return m_lastChild; }
-
-    virtual InlineBox* firstLeafChild();
-    virtual InlineBox* lastLeafChild();
-    InlineBox* firstLeafChildAfterBox(InlineBox* start=0);
-    InlineBox* lastLeafChildBeforeBox(InlineBox* start=0);
-        
-    virtual void setConstructed() {
-        InlineBox::setConstructed();
-        if (m_firstChild)
-            m_firstChild->setConstructed();
-    }
-    void addToLine(InlineBox* child);
-
-    virtual void deleteLine(RenderArena* arena);
-    virtual void extractLine();
-    virtual void attachLine();
-    virtual void adjustPosition(int dx, int dy);
-
-    virtual void clearTruncation();
-    
-    virtual void paintBackgroundAndBorder(RenderObject::PaintInfo& i, int _tx, int _ty);
-    void paintBackgrounds(GraphicsContext* p, const Color& c, const BackgroundLayer* bgLayer,
-                          int my, int mh, int _tx, int _ty, int w, int h);
-    void paintBackground(GraphicsContext* p, const Color& c, const BackgroundLayer* bgLayer,
-                         int my, int mh, int _tx, int _ty, int w, int h);
-    virtual void paintDecorations(RenderObject::PaintInfo& i, int _tx, int _ty, bool paintedChildren = false);
-    virtual void paint(RenderObject::PaintInfo& i, int _tx, int _ty);
-    virtual bool nodeAtPoint(RenderObject::NodeInfo& i, int x, int y, int tx, int ty);
-
-    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 onEndChain(RenderObject* endObject);
-    int placeBoxesHorizontally(int x, int& leftPosition, int& rightPosition, bool& needsWordSpacing);
-    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,
-                              int& topPosition, int& bottomPosition, int& selectionTop, int& selectionBottom);
-    void shrinkBoxesWithNoTextChildren(int topPosition, int bottomPosition);
-    
-    virtual void setVerticalOverflowPositions(int top, int bottom) {}
-    virtual void setVerticalSelectionPositions(int top, int bottom) {}
-    int maxHorizontalShadow() const { return m_maxHorizontalShadow; }
-
-    void removeChild(InlineBox* child);
-    
-    virtual RenderObject::SelectionState selectionState();
-
-    virtual bool canAccommodateEllipsis(bool ltr, int blockEdge, int ellipsisWidth);
-    virtual int placeEllipsisBox(bool ltr, int blockEdge, int ellipsisWidth, bool&);
-
-protected:
-    InlineBox* m_firstChild;
-    InlineBox* m_lastChild;
-    int m_maxHorizontalShadow;
-    bool m_includeLeftEdge : 1;
-    bool m_includeRightEdge : 1;
-    bool m_hasTextChildren : 1;
-};
-
-class RootInlineBox : public InlineFlowBox
-{
-public:
-    RootInlineBox(RenderObject* obj)
-    : InlineFlowBox(obj), m_topOverflow(0), m_bottomOverflow(0), m_leftOverflow(0), m_rightOverflow(0),
-      m_lineBreakObj(0), m_lineBreakPos(0), m_lineBreakContext(0),
-      m_blockHeight(0), m_endsWithBreak(false), m_hasSelectedChildren(false), m_ellipsisBox(0)
-    {}
-        
-    virtual void destroy(RenderArena* renderArena);
-    void detachEllipsisBox(RenderArena* renderArena);
-
-    RootInlineBox* nextRootBox() { return static_cast<RootInlineBox*>(m_nextLine); }
-    RootInlineBox* prevRootBox() { return static_cast<RootInlineBox*>(m_prevLine); }
-
-    virtual void adjustPosition(int dx, int dy);
-    
-    virtual bool isRootInlineBox() { return true; }
-    virtual int topOverflow() { return m_topOverflow; }
-    virtual int bottomOverflow() { return m_bottomOverflow; }
-    virtual int leftOverflow() { return m_leftOverflow; }
-    virtual int rightOverflow() { return m_rightOverflow; }
-    virtual void setVerticalOverflowPositions(int top, int bottom) { m_topOverflow = top; m_bottomOverflow = bottom; }
-    virtual void setVerticalSelectionPositions(int top, int bottom) { m_selectionTop = top; m_selectionBottom = bottom; }
-    void setHorizontalOverflowPositions(int left, int right) { m_leftOverflow = left; m_rightOverflow = right; }
-    void setLineBreakInfo(RenderObject* obj, unsigned breakPos, BidiStatus* status, BidiContext* context);
-    void setLineBreakPos(int p) { m_lineBreakPos = p; }
-
-    void setBlockHeight(int h) { m_blockHeight = h; }
-    void setEndsWithBreak(bool b) { m_endsWithBreak = b; }
-    
-    int blockHeight() const { return m_blockHeight; }
-    bool endsWithBreak() const { return m_endsWithBreak; }
-    RenderObject* lineBreakObj() const { return m_lineBreakObj; }
-    unsigned lineBreakPos() const { return m_lineBreakPos; }
-    BidiStatus lineBreakBidiStatus() const { return m_lineBreakBidiStatus; }
-    BidiContext* lineBreakBidiContext() const { return m_lineBreakContext.get(); }
-
-    void childRemoved(InlineBox* box);
-
-    bool canAccommodateEllipsis(bool ltr, int blockEdge, int lineBoxEdge, int ellipsisWidth);
-    void placeEllipsis(const AtomicString& ellipsisStr, bool ltr, int blockEdge, int ellipsisWidth, InlineBox* markupBox = 0);
-    virtual int placeEllipsisBox(bool ltr, int blockEdge, int ellipsisWidth, bool&);
-
-    EllipsisBox* ellipsisBox() const { return m_ellipsisBox; }
-    void paintEllipsisBox(RenderObject::PaintInfo& i, int _tx, int _ty) const;
-    bool hitTestEllipsisBox(RenderObject::NodeInfo& info, int _x, int _y, int _tx, int _ty,
-                            HitTestAction hitTestAction, bool inBox);
-    
-    virtual void clearTruncation();
-
-    virtual void paint(RenderObject::PaintInfo& i, int _tx, int _ty);
-    virtual bool nodeAtPoint(RenderObject::NodeInfo& i, int x, int y, int tx, int ty);
-
-    bool hasSelectedChildren() const { return m_hasSelectedChildren; }
-    void setHasSelectedChildren(bool b);
-    
-    virtual RenderObject::SelectionState selectionState();
-    InlineBox* firstSelectedBox();
-    InlineBox* lastSelectedBox();
-    
-    GapRects fillLineSelectionGap(int selTop, int selHeight, RenderBlock* rootBlock, int blockX, int blockY, 
-                                  int tx, int ty, const RenderObject::PaintInfo* i);
-    
-    RenderBlock* block() const;
-
-    int selectionTop();
-    int selectionBottom() { return m_selectionBottom; }
-    int selectionHeight() { return max(0, selectionBottom() - selectionTop()); }
-    InlineBox* closestLeafChildForXPos(int _x, int _tx);
-
-protected:
-    // Normally we are only as tall as the style on our block dictates, but we might have content
-    // that spills out above the height of our font (e.g, a tall image), or something that extends further
-    // below our line (e.g., a child whose font has a huge descent).
-    int m_topOverflow;
-    int m_bottomOverflow;
-    int m_leftOverflow;
-    int m_rightOverflow;
-
-    int m_selectionTop;
-    int m_selectionBottom;
-
-    // Where this line ended.  The exact object and the position within that object are stored so that
-    // we can create a BidiIterator beginning just after the end of this line.
-    RenderObject* m_lineBreakObj;
-    unsigned m_lineBreakPos;
-    
-    BidiStatus m_lineBreakBidiStatus;
-    RefPtr<BidiContext> m_lineBreakContext;
-    
-    // The height of the block at the end of this line.  This is where the next line starts.
-    int m_blockHeight;
-    
-    // Whether the line ends with a <br>.
-    bool m_endsWithBreak : 1;
-    
-    // Whether we have any children selected (this bit will also be set if the <br> that terminates our
-    // line is selected).
-    bool m_hasSelectedChildren : 1;
-
-    // An inline text box that represents our text truncation string.
-    EllipsisBox* m_ellipsisBox;
-};
-
-} //namespace
-
-#ifndef NDEBUG
-// Outside the WebCore namespace for ease of invocation from gdb.
-void showTree(const WebCore::InlineBox*);
-#endif
-
-#endif