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

hyatt hyatt at 268f45cc-cd09-0410-ab3c-d52691b4dbfc
Sat Sep 26 07:28:42 UTC 2009


The following commit has been merged in the debian/unstable branch:
commit 4b38169648f190dd41e7ddbae64ec4c8b547ed9b
Author: hyatt <hyatt at 268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Mon Mar 10 21:11:59 2003 +0000

    	Fix compacts and run-ins to work a lot better than they did
    	before.  I had some huge misunderstandings with how compact
    	worked that have now been clarified.
    
            Reviewed by kocienda
    
            * khtml/rendering/bidi.cpp:
            * khtml/rendering/bidi.h:
            * khtml/rendering/render_block.cpp:
            * khtml/rendering/render_block.h:
            * khtml/rendering/render_flow.cpp:
            (RenderFlow::repaint):
            * khtml/rendering/render_line.cpp:
            (InlineFlowBox::placeBoxesHorizontally):
            * khtml/rendering/render_object.cpp:
            (RenderObject::nodeAtPoint):
            * khtml/rendering/render_object.h:
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@3791 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/WebCore/ChangeLog-2003-10-25 b/WebCore/ChangeLog-2003-10-25
index 0dc3ecc..3a711f8 100644
--- a/WebCore/ChangeLog-2003-10-25
+++ b/WebCore/ChangeLog-2003-10-25
@@ -1,3 +1,23 @@
+2003-03-09  David Hyatt  <hyatt at apple.com>
+
+	Fix compacts and run-ins to work a lot better than they did
+	before.  I had some huge misunderstandings with how compact
+	worked that have now been clarified.
+	
+        Reviewed by kocienda
+
+        * khtml/rendering/bidi.cpp:
+        * khtml/rendering/bidi.h:
+        * khtml/rendering/render_block.cpp:
+        * khtml/rendering/render_block.h:
+        * khtml/rendering/render_flow.cpp:
+        (RenderFlow::repaint):
+        * khtml/rendering/render_line.cpp:
+        (InlineFlowBox::placeBoxesHorizontally):
+        * khtml/rendering/render_object.cpp:
+        (RenderObject::nodeAtPoint):
+        * khtml/rendering/render_object.h:
+
 2003-03-08  David Hyatt  <hyatt at apple.com>
 
 	Check in the patch I actually meant to land.  Somehow what I landed
diff --git a/WebCore/ChangeLog-2005-08-23 b/WebCore/ChangeLog-2005-08-23
index 0dc3ecc..3a711f8 100644
--- a/WebCore/ChangeLog-2005-08-23
+++ b/WebCore/ChangeLog-2005-08-23
@@ -1,3 +1,23 @@
+2003-03-09  David Hyatt  <hyatt at apple.com>
+
+	Fix compacts and run-ins to work a lot better than they did
+	before.  I had some huge misunderstandings with how compact
+	worked that have now been clarified.
+	
+        Reviewed by kocienda
+
+        * khtml/rendering/bidi.cpp:
+        * khtml/rendering/bidi.h:
+        * khtml/rendering/render_block.cpp:
+        * khtml/rendering/render_block.h:
+        * khtml/rendering/render_flow.cpp:
+        (RenderFlow::repaint):
+        * khtml/rendering/render_line.cpp:
+        (InlineFlowBox::placeBoxesHorizontally):
+        * khtml/rendering/render_object.cpp:
+        (RenderObject::nodeAtPoint):
+        * khtml/rendering/render_object.h:
+
 2003-03-08  David Hyatt  <hyatt at apple.com>
 
 	Check in the patch I actually meant to land.  Somehow what I landed
diff --git a/WebCore/khtml/rendering/bidi.cpp b/WebCore/khtml/rendering/bidi.cpp
index 69a1bbb..31d1b10 100644
--- a/WebCore/khtml/rendering/bidi.cpp
+++ b/WebCore/khtml/rendering/bidi.cpp
@@ -47,6 +47,10 @@ static BidiStatus status;
 static BidiRun* sFirstBidiRun = 0;
 static BidiRun* sLastBidiRun = 0;
 static int sBidiRunCount = 0;
+static BidiRun* sCompactFirstBidiRun = 0;
+static BidiRun* sCompactLastBidiRun = 0;
+static int sCompactBidiRunCount = 0;
+static bool sBuildingCompactRuns = false;
 
 // Midpoint globals.  The goal is not to do any allocation when dealing with
 // these midpoints, so we just keep an array around and never clear it.  We track
@@ -362,6 +366,7 @@ static void addRun(BidiRun* bidiRun)
         sLastBidiRun = bidiRun;
     }
     sBidiRunCount++;
+    bidiRun->compact = sBuildingCompactRuns;
 }
 
 static void reverseRuns(int start, int end)
@@ -650,9 +655,13 @@ void RenderBlock::computeHorizontalPositionsForLine(InlineFlowBox* lineBox, Bidi
         else if (!r->obj->isInlineFlow()) {
             r->obj->calcWidth();
             r->box->setWidth(r->obj->width());
-            totWidth += r->obj->marginLeft() + r->obj->marginRight();
+            if (!r->compact)
+                totWidth += r->obj->marginLeft() + r->obj->marginRight();
         }
-        totWidth += r->box->width();
+
+        // Compacts don't contribute to the width of the line, since they are placed in the margin.
+        if (!r->compact)
+            totWidth += r->box->width();
     }
 
     // Armed with the total width of the line (without justification),
@@ -688,7 +697,7 @@ void RenderBlock::computeHorizontalPositionsForLine(InlineFlowBox* lineBox, Bidi
 
     for (r = sFirstBidiRun; r; r = r->nextRun) {
         int spaceAdd = 0;
-        if (numSpaces > 0 && r->obj->isText()) {
+        if (numSpaces > 0 && r->obj->isText() && !r->compact) {
             // get the number of spaces in the run
             int spaces = 0;
             for ( int i = r->start; i < r->stop; i++ )
@@ -1102,7 +1111,6 @@ void RenderBlock::bidiReorderLine(const BidiIterator &start, const BidiIterator
 	    appendRun();
     }
 
-    BidiContext *endEmbed = context;
     // both commands below together give a noop...
     //endEmbed->ref();
     //context->deref();
@@ -1168,21 +1176,42 @@ void RenderBlock::bidiReorderLine(const BidiIterator &start, const BidiIterator
     for (BidiRun* curr = sFirstRun; curr; curr = curr->nextRun)
         kdDebug(6041) << "    " << curr << endl;
 #endif
+}
 
-    // Now that the runs have been ordered, we create the line boxes.
-    // At the same time we figure out where border/padding/margin should be applied for
-    // inline flow boxes.
-    InlineFlowBox* lineBox = constructLine(start, end);
-    if (!lineBox)
-        return;
-
-    // Now we position all of our text runs horizontally.
-    computeHorizontalPositionsForLine(lineBox, endEmbed);
-
-    // Now position our text runs vertically.
-    computeVerticalPositionsForLine(lineBox);
+static void buildCompactRuns(RenderObject* compactObj)
+{
+    sBuildingCompactRuns = true;
+    if (!compactObj->isRenderBlock()) {
+        // Just append a run for our object.
+        isLineEmpty = false;
+        addRun(new (compactObj->renderArena()) BidiRun(0, compactObj->length(), compactObj, context, dir));
+    }
+    else {
+        // Format the compact like it is its own single line.  We build up all the runs for
+        // the little compact and then reorder them for bidi.
+        RenderBlock* compactBlock = static_cast<RenderBlock*>(compactObj);
+        adjustEmbeddding = true;
+        BidiIterator start(compactBlock);
+        adjustEmbeddding = false;
+        BidiIterator end(compactBlock);
+    
+        betweenMidpoints = false;
+        isLineEmpty = true;
+    
+        end = compactBlock->findNextLineBreak(start);
+        if (!isLineEmpty)
+            compactBlock->bidiReorderLine(start, end);
+    }
+    
+    
+    sCompactFirstBidiRun = sFirstBidiRun;
+    sCompactLastBidiRun = sLastBidiRun;
+    sCompactBidiRunCount = sBidiRunCount;
     
-    deleteBidiRuns(renderArena());
+    sNumMidpoints = 0;
+    sCurrMidpoint = 0;
+    betweenMidpoints = false;
+    sBuildingCompactRuns = false;
 }
 
 void RenderBlock::layoutInlineChildren(bool relayoutChildren)
@@ -1252,16 +1281,46 @@ void RenderBlock::layoutInlineChildren(bool relayoutChildren)
 
         sNumMidpoints = 0;
         sCurrMidpoint = 0;
-        
+        sCompactFirstBidiRun = sCompactLastBidiRun = 0;
+        sCompactBidiRunCount = 0;
+
         while( !end.atEnd() ) {
             start = end;
             betweenMidpoints = false;
             isLineEmpty = true;
+            if (m_firstLine && firstChild() && firstChild()->isCompact()) {
+                buildCompactRuns(firstChild());
+                start.obj = firstChild()->nextSibling();
+                end = start;
+            }
             end = findNextLineBreak(start);
             if( start.atEnd() ) break;
             if (!isLineEmpty) {
                 bidiReorderLine(start, end);
-    
+
+                // Now that the runs have been ordered, we create the line boxes.
+                // At the same time we figure out where border/padding/margin should be applied for
+                // inline flow boxes.
+                if (sCompactFirstBidiRun) {
+                    // We have a compact line sharing this line.  Link the compact runs
+                    // to our runs to create a single line of runs.
+                    sCompactLastBidiRun->nextRun = sFirstBidiRun;
+                    sFirstBidiRun = sCompactFirstBidiRun;
+                    sBidiRunCount += sCompactBidiRunCount;
+                }
+                
+                InlineFlowBox* lineBox = constructLine(start, end);
+                if (!lineBox)
+                    return;
+
+                // Now we position all of our text runs horizontally.
+                computeHorizontalPositionsForLine(lineBox, context);
+
+                // Now position our text runs vertically.
+                computeVerticalPositionsForLine(lineBox);
+
+                deleteBidiRuns(renderArena());
+                
                 if( end == start || (end.obj && end.obj->isBR() && !start.obj->isBR() ) ) {
                     adjustEmbeddding = true;
                     ++end;
@@ -1278,6 +1337,8 @@ void RenderBlock::layoutInlineChildren(bool relayoutChildren)
 
             sNumMidpoints = 0;
             sCurrMidpoint = 0;
+            sCompactFirstBidiRun = sCompactLastBidiRun = 0;
+            sCompactBidiRunCount = 0;
         }
         startEmbed->deref();
         //embed->deref();
@@ -1318,9 +1379,9 @@ BidiIterator RenderBlock::findNextLineBreak(BidiIterator &start)
     // be skipped.
     while(!start.atEnd() && (start.obj->isInlineFlow() || (start.obj->style()->whiteSpace() != PRE &&
 #ifndef QT_NO_UNICODETABLES
-          ( start.direction() == QChar::DirWS || start.obj->isSpecial() )
+          ( start.direction() == QChar::DirWS || start.obj->isSpecial())
 #else
-          ( start.current() == ' ' || start.obj->isSpecial() )
+          ( start.current() == ' ' || start.obj->isSpecial())
 #endif
           ))) {
         if( start.obj->isSpecial() ) {
@@ -1339,7 +1400,7 @@ BidiIterator RenderBlock::findNextLineBreak(BidiIterator &start)
                 o->containingBlock()->insertSpecialObject(o);
             }
         }
-
+        
         adjustEmbeddding = true;
         ++start;
         adjustEmbeddding = false;
diff --git a/WebCore/khtml/rendering/bidi.h b/WebCore/khtml/rendering/bidi.h
index d9b17d7..6595cda 100644
--- a/WebCore/khtml/rendering/bidi.h
+++ b/WebCore/khtml/rendering/bidi.h
@@ -94,6 +94,8 @@ public:
 	// explicit + implicit levels here
 	uchar level;
 
+        bool compact : 1;
+        
         BidiRun* nextRun;
     };
 
diff --git a/WebCore/khtml/rendering/render_block.cpp b/WebCore/khtml/rendering/render_block.cpp
index 13e317d..88bac7c 100644
--- a/WebCore/khtml/rendering/render_block.cpp
+++ b/WebCore/khtml/rendering/render_block.cpp
@@ -649,13 +649,14 @@ void RenderBlock::layoutBlockChildren( bool relayoutChildren )
         // FIXME: We only deal with one compact at a time.  It is unclear what should be
         // done if multiple contiguous compacts are encountered.  For now we assume that
         // compact A followed by another compact B should simply be treated as block A.
-        if (child->isCompact() && !compactChild) {
+        if (child->isCompact() && !compactChild && (child->childrenInline() || child->isReplaced())) {
             // Get the next non-positioned/non-floating RenderBlock.
             RenderObject* next = child->nextSibling();
             RenderObject* curr = next;
             while (curr && curr->isSpecial())
                 curr = curr->nextSibling();
-            if (curr && !curr->isCompact() && !curr->isRunIn()) {
+            if (curr && curr->isRenderBlock() && !curr->isAnonymousBox() &&
+                !curr->isCompact() && !curr->isRunIn()) {
                 curr->calcWidth(); // So that horizontal margins are correct.
                 // Need to compute margins for the child as though it is a block.
                 child->style()->setDisplay(BLOCK);
@@ -672,7 +673,18 @@ void RenderBlock::layoutBlockChildren( bool relayoutChildren )
                 else {
                     blockForCompactChild = curr;
                     compactChild = child;
-                    child = child->nextSibling();
+                    child->setInline(true);
+                    child->setPos(0,0); // This position will be updated to reflect the compact's
+                                        // desired position and the line box for the compact will
+                                        // pick that position up.
+
+                    // Remove the child.
+                    RenderObject* next = child->nextSibling();
+                    removeChildNode(child);
+
+                    // Now insert the child under |curr|.
+                    curr->insertChildNode(child, curr->firstChild());
+                    child = next;
                     continue;
                 }
             }
@@ -686,7 +698,7 @@ void RenderBlock::layoutBlockChildren( bool relayoutChildren )
             RenderObject* curr = child->nextSibling();
             while (curr && curr->isSpecial())
                 curr = curr->nextSibling();
-            if (curr && (curr->isRenderBlock() && curr->childrenInline() &&
+            if (curr && (curr->isRenderBlock() && !curr->isAnonymousBox() && curr->childrenInline() &&
                          !curr->isCompact() && !curr->isRunIn())) {
                 // The block acts like an inline, so just null out its
                 // position.
@@ -922,24 +934,14 @@ void RenderBlock::layoutBlockChildren( bool relayoutChildren )
             blockForCompactChild = 0;
             if (compactChild) {
                 // We have a compact child to squeeze in.
-                // FIXME: Align the compact box vertically such that the baseline of its
-                // first line box and the baseline of the block child's first line box are aligned.
                 int compactXPos = xPos+compactChild->marginLeft();
                 if (style()->direction() == RTL) {
                     compactChild->calcWidth(); // have to do this because of the capped maxwidth
                     compactXPos = width() - borderRight() - paddingRight() - marginRight() -
                         compactChild->width() - compactChild->marginRight();
                 }
-                compactChild->setPos(compactXPos, child->yPos());
-                if (!compactChild->layouted())
-                    compactChild->layout();
-
-                // FIXME: Is this right? Do we grow the block to accommodate the compact child?
-                // It seems like we could be smart and keep looking for blocks that leave space
-                // for us.  For now just grow the block.
-                if (compactChild->yPos() + compactChild->height() > m_height)
-                    m_height = compactChild->yPos() + compactChild->height();
-                
+                compactXPos -= child->xPos(); // Put compactXPos into the child's coordinate space.
+                compactChild->setPos(compactXPos, compactChild->yPos()); // Set the x position.
                 compactChild = 0;
             }
         }
@@ -1028,7 +1030,7 @@ void RenderBlock::paint(QPainter* p, int _x, int _y, int _w, int _h, int _tx, in
     _ty += m_y;
 
     // check if we need to do anything at all...
-    if (!overhangingContents() && !isRelPositioned() && !isPositioned() )
+    if (!isInlineFlow() && !overhangingContents() && !isRelPositioned() && !isPositioned() )
     {
         int h = m_overflowHeight;
         int yPos = _ty;
@@ -1057,10 +1059,10 @@ void RenderBlock::paintObject(QPainter *p, int _x, int _y,
 #endif
 
     // If we're a repositioned run-in, don't paint background/borders.
-    bool inlineRunIn = (isRunIn() && isInline());
+    bool inlineFlow = isInlineFlow();
     
     // 1. paint background, borders etc
-    if (!inlineRunIn && paintAction == PaintActionBackground &&
+    if (!inlineFlow && paintAction == PaintActionBackground &&
         shouldPaintBackgroundOrBorder() && style()->visibility() == VISIBLE )
         paintBoxDecorations(p, _x, _y, _w, _h, _tx, _ty);
 
@@ -1076,10 +1078,10 @@ void RenderBlock::paintObject(QPainter *p, int _x, int _y,
     paintLineBoxDecorations(p, _x, _y, _w, _h, _tx, _ty, paintAction);
     
     // 3. paint floats.
-    if (!inlineRunIn && (paintAction == PaintActionFloat || paintAction == PaintActionSelection))
+    if (!inlineFlow && (paintAction == PaintActionFloat || paintAction == PaintActionSelection))
         paintFloats(p, _x, _y, _w, _h, _tx, _ty, paintAction == PaintActionSelection);
 
-    if (!inlineRunIn && paintAction == PaintActionBackground &&
+    if (!inlineFlow && paintAction == PaintActionBackground &&
         !childrenInline() && style()->outlineWidth())
         paintOutline(p, _tx, _ty, width(), height(), style());
 
@@ -2140,6 +2142,40 @@ void RenderBlock::close()
     RenderFlow::close();
 }
 
+int RenderBlock::getBaselineOfFirstLineBox()
+{
+    if (m_firstLineBox)
+        return m_firstLineBox->yPos() + m_firstLineBox->baseline();
+
+    if (isInline())
+        return -1; // We're inline and had no line box, so we have no baseline we can return.
+
+    for (RenderObject* curr = firstChild(); curr; curr = curr->nextSibling()) {
+        int result = curr->getBaselineOfFirstLineBox();
+        if (result != -1)
+            return curr->yPos() + result; // Translate to our coordinate space.
+    }
+
+    return -1;
+}
+
+InlineFlowBox* RenderBlock::getFirstLineBox()
+{
+    if (m_firstLineBox)
+        return m_firstLineBox;
+
+    if (isInline())
+        return 0; // We're inline and had no line box, so we have no baseline we can return.
+
+    for (RenderObject* curr = firstChild(); curr; curr = curr->nextSibling()) {
+        InlineFlowBox* result = curr->getFirstLineBox();
+        if (result)
+            return result;
+    }
+
+    return 0;    
+}
+
 const char *RenderBlock::renderName() const
 {
     if (isFloating())
@@ -2150,6 +2186,10 @@ const char *RenderBlock::renderName() const
         return "RenderBlock (anonymous)";
     if (isRelPositioned())
         return "RenderBlock (relative positioned)";
+    if (isCompact())
+        return "RenderBlock (compact)";
+    if (isRunIn())
+        return "RenderBlock (run-in)";
     return "RenderBlock";
 }
 
diff --git a/WebCore/khtml/rendering/render_block.h b/WebCore/khtml/rendering/render_block.h
index 592a987..3b3d156 100644
--- a/WebCore/khtml/rendering/render_block.h
+++ b/WebCore/khtml/rendering/render_block.h
@@ -142,6 +142,9 @@ public:
 
     virtual void close();
 
+    virtual int getBaselineOfFirstLineBox();
+    virtual InlineFlowBox* getFirstLineBox();
+    
     // overrides RenderObject
     virtual bool requiresLayer() { return !isTableCell() &&
         (isPositioned() || isRelPositioned() || style()->overflow()==OHIDDEN); }
diff --git a/WebCore/khtml/rendering/render_flow.cpp b/WebCore/khtml/rendering/render_flow.cpp
index b9e8e93..d8779bb 100644
--- a/WebCore/khtml/rendering/render_flow.cpp
+++ b/WebCore/khtml/rendering/render_flow.cpp
@@ -248,6 +248,8 @@ void RenderFlow::repaint(bool immediate)
 
         // Now invalidate a rectangle.
         int ow = style() ? style()->outlineWidth() : 0;
+        if (isCompact())
+            left -= m_x;
         containingBlock()->repaintRectangle(-ow+left, -ow+top,
                                             width()+ow*2, height()+ow*2, immediate);
     }
diff --git a/WebCore/khtml/rendering/render_line.cpp b/WebCore/khtml/rendering/render_line.cpp
index a5a0337..7f12417 100644
--- a/WebCore/khtml/rendering/render_line.cpp
+++ b/WebCore/khtml/rendering/render_line.cpp
@@ -236,11 +236,17 @@ int InlineFlowBox::placeBoxesHorizontally(int x)
         else {
             if (curr->object()->isInlineFlow()) {
                 InlineFlowBox* flow = static_cast<InlineFlowBox*>(curr);
-                x += flow->marginLeft();
-                x = flow->placeBoxesHorizontally(x);
-                x += flow->marginRight();
+                if (curr->object()->isCompact()) {
+                    int ignoredX = x;
+                    flow->placeBoxesHorizontally(ignoredX);
+                }
+                else {
+                    x += flow->marginLeft();
+                    x = flow->placeBoxesHorizontally(x);
+                    x += flow->marginRight();
+                }
             }
-            else {
+            else if (!curr->object()->isCompact()) {
                 x += curr->object()->marginLeft();
                 curr->setXPos(x);
                 x += curr->width() + curr->object()->marginRight();
diff --git a/WebCore/khtml/rendering/render_object.cpp b/WebCore/khtml/rendering/render_object.cpp
index e151689..07d6f8b 100644
--- a/WebCore/khtml/rendering/render_object.cpp
+++ b/WebCore/khtml/rendering/render_object.cpp
@@ -1201,7 +1201,7 @@ bool RenderObject::nodeAtPoint(NodeInfo& info, int _x, int _y, int _tx, int _ty,
                   (_x >= tx) && (_x < tx + overflowWidth()))) || isBody() || isHtml();
     
     // ### table should have its own, more performant method
-    if (overhangingContents() || isInline() || isRoot() || isTableRow() || isTableSection() || inside || mouseInside() ) {
+    if (overhangingContents() || isInline() || isRoot() || isTableRow() || isTableSection() || inside || mouseInside() || (childrenInline() && firstChild() && firstChild()->isCompact())) {
         for (RenderObject* child = lastChild(); child; child = child->previousSibling())
             if (!child->layer() && child->nodeAtPoint(info, _x, _y, _tx+xPos(), _ty+yPos()))
                 inside = true;
diff --git a/WebCore/khtml/rendering/render_object.h b/WebCore/khtml/rendering/render_object.h
index 3af8665..1693c21 100644
--- a/WebCore/khtml/rendering/render_object.h
+++ b/WebCore/khtml/rendering/render_object.h
@@ -87,6 +87,7 @@ namespace khtml {
     class RenderFrameSet;
     class RenderLayer;
     class InlineBox;
+    class InlineFlowBox;
 
 /**
  * Base Class for all rendering tree objects.
@@ -120,6 +121,9 @@ public:
     virtual QRect getClipRect(int tx, int ty) { return QRect(0,0,0,0); }
     bool hasClip() { return isPositioned() &&  style()->hasClip(); }
     bool hasOverflowClip() { return style()->overflow() == OHIDDEN; }
+
+    virtual int getBaselineOfFirstLineBox() { return -1; } // Tables and blocks implement this.
+    virtual InlineFlowBox* getFirstLineBox() { return 0; } // Tables and blocks implement this.
     
     // RenderObject tree manipulation
     //////////////////////////////////////////
@@ -168,7 +172,8 @@ public:
     // some helper functions...
     virtual bool isRenderBlock() const { return false; }
     virtual bool isRenderInline() const { return false; }
-    virtual bool isInlineFlow() const { return isRenderInline() || isRunIn(); }
+    virtual bool isInlineFlow() const { return isInline() && !isReplaced() &&
+                                               (isRenderInline() || isRenderBlock()); }
     virtual bool childrenInline() const { return false; }
     virtual void setChildrenInline(bool b) { };
     virtual RenderFlow* continuation() const { return 0; }

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list