Changeset 70356 in webkit


Ignore:
Timestamp:
Oct 22, 2010 3:36:42 PM (14 years ago)
Author:
hyatt@apple.com
Message:

https://bugs.webkit.org/show_bug.cgi?id=48156

Reviewed by Adele Peterson.

Make vertical lines hit test properly and show a vertical i-beam cursor. Numerous bugs with overflow were discovered while getting this to work,
so these are in the patch as well. The broken layout tests are fixed by the overflow bug fixes as well (which just restore the old behavior).

  • page/EventHandler.cpp:

(WebCore::EventHandler::selectCursor):

  • rendering/InlineBox.h:

(WebCore::InlineBox::width):
(WebCore::InlineBox::height):

  • rendering/InlineFlowBox.cpp:

(WebCore::InlineFlowBox::placeBoxesInInlineDirection):
(WebCore::InlineFlowBox::computeBlockDirectionOverflow):
(WebCore::InlineFlowBox::nodeAtPoint):

  • rendering/InlineFlowBox.h:

(WebCore::InlineFlowBox::logicalTopVisibleOverflow):
(WebCore::InlineFlowBox::logicalBottomVisibleOverflow):
(WebCore::InlineFlowBox::visibleOverflowRect):
(WebCore::InlineFlowBox::layoutOverflowRect):
(WebCore::InlineFlowBox::logicalTopLayoutOverflow):
(WebCore::InlineFlowBox::logicalBottomLayoutOverflow):
(WebCore::InlineFlowBox::visualOverflowRect):
(WebCore::InlineFlowBox::logicalTopVisualOverflow):
(WebCore::InlineFlowBox::logicalBottomVisualOverflow):
(WebCore::InlineFlowBox::setBlockDirectionOverflowPositions):

  • rendering/InlineTextBox.cpp:

(WebCore::InlineTextBox::nodeAtPoint):

  • rendering/RenderBox.cpp:

(WebCore::RenderBox::blockDirectionOverflow):

  • rendering/RenderBox.h:
  • rendering/RenderLineBoxList.cpp:

(WebCore::RenderLineBoxList::hitTest):

Location:
trunk/WebCore
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/WebCore/ChangeLog

    r70355 r70356  
     12010-10-22  David Hyatt  <hyatt@apple.com>
     2
     3        Reviewed by Adele Peterson.
     4
     5        https://bugs.webkit.org/show_bug.cgi?id=48156
     6
     7        Make vertical lines hit test properly and show a vertical i-beam cursor.  Numerous bugs with overflow were discovered while getting this to work,
     8        so these are in the patch as well.  The broken layout tests are fixed by the overflow bug fixes as well (which just restore the old behavior).
     9
     10        * page/EventHandler.cpp:
     11        (WebCore::EventHandler::selectCursor):
     12        * rendering/InlineBox.h:
     13        (WebCore::InlineBox::width):
     14        (WebCore::InlineBox::height):
     15        * rendering/InlineFlowBox.cpp:
     16        (WebCore::InlineFlowBox::placeBoxesInInlineDirection):
     17        (WebCore::InlineFlowBox::computeBlockDirectionOverflow):
     18        (WebCore::InlineFlowBox::nodeAtPoint):
     19        * rendering/InlineFlowBox.h:
     20        (WebCore::InlineFlowBox::logicalTopVisibleOverflow):
     21        (WebCore::InlineFlowBox::logicalBottomVisibleOverflow):
     22        (WebCore::InlineFlowBox::visibleOverflowRect):
     23        (WebCore::InlineFlowBox::layoutOverflowRect):
     24        (WebCore::InlineFlowBox::logicalTopLayoutOverflow):
     25        (WebCore::InlineFlowBox::logicalBottomLayoutOverflow):
     26        (WebCore::InlineFlowBox::visualOverflowRect):
     27        (WebCore::InlineFlowBox::logicalTopVisualOverflow):
     28        (WebCore::InlineFlowBox::logicalBottomVisualOverflow):
     29        (WebCore::InlineFlowBox::setBlockDirectionOverflowPositions):
     30        * rendering/InlineTextBox.cpp:
     31        (WebCore::InlineTextBox::nodeAtPoint):
     32        * rendering/RenderBox.cpp:
     33        (WebCore::RenderBox::blockDirectionOverflow):
     34        * rendering/RenderBox.h:
     35        * rendering/RenderLineBoxList.cpp:
     36        (WebCore::RenderLineBoxList::hitTest):
     37
    1382010-10-22  Dan Bernstein  <mitz@apple.com>
    239
  • trunk/WebCore/page/EventHandler.cpp

    r69467 r70356  
    10571057Cursor EventHandler::selectCursor(const MouseEventWithHitTestResults& event, Scrollbar* scrollbar)
    10581058{
     1059    Node* node = event.targetNode();
     1060    RenderObject* renderer = node ? node->renderer() : 0;
     1061    RenderStyle* style = renderer ? renderer->style() : 0;
     1062
     1063    bool horizontalText = !style || style->isHorizontalWritingMode();
     1064    const Cursor& iBeam = horizontalText ? iBeamCursor() : verticalTextCursor();
     1065
    10591066    // During selection, use an I-beam no matter what we're over.
    10601067    // If you're capturing mouse events for a particular node, don't treat this as a selection.
    10611068    if (m_mousePressed && m_mouseDownMayStartSelect && m_frame->selection()->isCaretOrRange() && !m_capturingMouseEventsNode)
    1062         return iBeamCursor();
    1063 
    1064     Node* node = event.targetNode();
    1065     RenderObject* renderer = node ? node->renderer() : 0;
    1066     RenderStyle* style = renderer ? renderer->style() : 0;
     1069        return iBeam;
    10671070
    10681071    if (renderer && renderer->isFrameSet()) {
     
    11341137        }
    11351138        if ((editable || (renderer && renderer->isText() && node->canStartSelection())) && !inResizer && !scrollbar)
    1136             return iBeamCursor();
     1139            return iBeam;
    11371140        return pointerCursor();
    11381141    }
  • trunk/WebCore/rendering/InlineBox.h

    r70330 r70356  
    217217    int y() const { return m_y; }
    218218
     219    int width() const { return m_isVertical ? logicalHeight() : logicalWidth(); }
     220    int height() const { return m_isVertical ? logicalWidth() : logicalHeight(); }
     221
    219222    // The logicalLeft position is the left edge of the line box in a horizontal line and the top edge in a vertical line.
    220223    int logicalLeft() const { return !m_isVertical ? m_x : m_y; }
  • trunk/WebCore/rendering/InlineFlowBox.cpp

    r70330 r70356  
    300300            int textShadowLogicalRight;
    301301            rt->style(m_firstLine)->getTextShadowInlineDirectionExtent(textShadowLogicalLeft, textShadowLogicalRight);
    302             childOverflowLogicalLeft = min(childOverflowLogicalLeft, textShadowLogicalLeft);
    303             childOverflowLogicalRight = max(childOverflowLogicalRight, textShadowLogicalRight);
     302            childOverflowLogicalLeft = min(childOverflowLogicalLeft, textShadowLogicalLeft + logicalLeftGlyphOverflow);
     303            childOverflowLogicalRight = max(childOverflowLogicalRight, textShadowLogicalRight + logicalRightGlyphOverflow);
    304304            logicalLeftVisualOverflow = min(logicalLeft + childOverflowLogicalLeft, logicalLeftVisualOverflow);
    305305            logicalRightVisualOverflow = max(logicalLeft + text->logicalWidth() + childOverflowLogicalRight, logicalRightVisualOverflow);
     
    613613            curr->renderer()->style(m_firstLine)->getTextShadowBlockDirectionExtent(textShadowTop, textShadowBottom);
    614614       
    615             int childOverflowTop = min(textShadowTop, topGlyphOverflow);
    616             int childOverflowBottom = max(textShadowBottom, bottomGlyphOverflow);
     615            int childOverflowTop = min(textShadowTop + topGlyphOverflow, topGlyphOverflow);
     616            int childOverflowBottom = max(textShadowBottom + bottomGlyphOverflow, bottomGlyphOverflow);
    617617   
    618618            topVisualOverflow = min(curr->logicalTop() + childOverflowTop, topVisualOverflow);
     
    621621            InlineFlowBox* flow = static_cast<InlineFlowBox*>(curr);
    622622            flow->computeBlockDirectionOverflow(lineTop, lineBottom, strictMode, textBoxDataMap);
    623             topLayoutOverflow = min(topLayoutOverflow, flow->topLayoutOverflow());
    624             bottomLayoutOverflow = max(bottomLayoutOverflow, flow->bottomLayoutOverflow());
    625             topVisualOverflow = min(topVisualOverflow, flow->topVisualOverflow());
    626             bottomVisualOverflow = max(bottomVisualOverflow, flow->bottomVisualOverflow());
     623            topLayoutOverflow = min(topLayoutOverflow, flow->logicalTopLayoutOverflow());
     624            bottomLayoutOverflow = max(bottomLayoutOverflow, flow->logicalBottomLayoutOverflow());
     625            topVisualOverflow = min(topVisualOverflow, flow->logicalTopVisualOverflow());
     626            bottomVisualOverflow = max(bottomVisualOverflow, flow->logicalBottomVisualOverflow());
    627627        } else if (!curr->boxModelObject()->hasSelfPaintingLayer()){
    628628            // Only include overflow from replaced inlines if they do not paint themselves.
     
    634634           
    635635            RenderBox* box = toRenderBox(curr->renderer());
    636             box->blockDirectionOverflow(isVertical(), isFlippedLine, childTopLayoutOverflow, childBottomLayoutOverflow,
     636            box->blockDirectionOverflow(isVertical(), childTopLayoutOverflow, childBottomLayoutOverflow,
    637637                                        childTopVisualOverflow, childBottomVisualOverflow);
    638638           
     639            if (box->hasOverflowClip()) {
     640                childTopLayoutOverflow = 0;
     641                childBottomLayoutOverflow = curr->logicalHeight();
     642            }
     643
    639644            topLayoutOverflow = min(boxLogicalTop + childTopLayoutOverflow, topLayoutOverflow);
    640645            bottomLayoutOverflow = max(boxLogicalTop + childBottomLayoutOverflow, bottomLayoutOverflow);
     
    663668
    664669    // Now check ourselves.
    665     IntRect rect(tx + m_x, ty + m_y, m_logicalWidth, logicalHeight());
     670    IntRect rect(tx + m_x, ty + m_y, width(), height());
    666671    if (visibleToHitTesting() && rect.intersects(result.rectForPoint(x, y))) {
    667672        renderer()->updateHitTestResult(result, IntPoint(x - tx, y - ty)); // Don't add in m_x or m_y here, we want coords in the containing block's space.
  • trunk/WebCore/rendering/InlineFlowBox.h

    r70330 r70356  
    175175    void setHasBadChildList();
    176176
     177    // Line visual and layout overflow are in the coordinate space of the block.  This means that - unlike other unprefixed uses of the words
     178    // top/right/bottom/left in the code - these aren't purely physical directions.  For horizontal-tb and vertical-lr they will match physical
     179    // directions, but for horizontal-bt and vertical-rl, the top/bottom and left/right respectively are inverted when compared to
     180    // their physical counterparts.
    177181    int topVisibleOverflow() const { return std::min(topLayoutOverflow(), topVisualOverflow()); }
    178182    int bottomVisibleOverflow() const { return std::max(bottomLayoutOverflow(), bottomVisualOverflow()); }
    179183    int leftVisibleOverflow() const { return std::min(leftLayoutOverflow(), leftVisualOverflow()); }
    180184    int rightVisibleOverflow() const { return std::max(rightLayoutOverflow(), rightVisualOverflow()); }
    181     IntRect visibleOverflowRect() const { return m_overflow ? m_overflow->visibleOverflowRect() : IntRect(m_x, m_y, m_logicalWidth, logicalHeight());  }
     185    int logicalTopVisibleOverflow() const { return std::min(logicalTopLayoutOverflow(), logicalTopVisualOverflow()); }
     186    int logicalBottomVisibleOverflow() const { return std::max(logicalBottomLayoutOverflow(), logicalBottomVisualOverflow()); }
     187
     188    IntRect visibleOverflowRect() const { return m_overflow ? m_overflow->visibleOverflowRect() : IntRect(m_x, m_y, width(), height());  }
    182189
    183190    int topLayoutOverflow() const { return m_overflow ? m_overflow->topLayoutOverflow() : m_y; }
     
    185192    int leftLayoutOverflow() const { return m_overflow ? m_overflow->leftLayoutOverflow() : m_x; }
    186193    int rightLayoutOverflow() const { return m_overflow ? m_overflow->rightLayoutOverflow() : m_x + m_logicalWidth; }
    187     IntRect layoutOverflowRect() const { return m_overflow ? m_overflow->layoutOverflowRect() : IntRect(m_x, m_y, m_logicalWidth, logicalHeight()); }
     194    IntRect layoutOverflowRect() const { return m_overflow ? m_overflow->layoutOverflowRect() : IntRect(m_x, m_y, width(), height()); }
    188195    int logicalLeftLayoutOverflow() const { return renderer()->style()->isHorizontalWritingMode() ? leftLayoutOverflow() : topLayoutOverflow(); }
    189196    int logicalRightLayoutOverflow() const { return renderer()->style()->isHorizontalWritingMode() ? rightLayoutOverflow() : bottomLayoutOverflow(); }
    190    
     197    int logicalTopLayoutOverflow() const { return renderer()->style()->isHorizontalWritingMode() ? topVisualOverflow() : leftVisualOverflow(); }
     198    int logicalBottomLayoutOverflow() const { return renderer()->style()->isHorizontalWritingMode() ? bottomLayoutOverflow() : rightLayoutOverflow(); }
     199
    191200    int topVisualOverflow() const { return m_overflow ? m_overflow->topVisualOverflow() : m_y; }
    192201    int bottomVisualOverflow() const { return m_overflow ? m_overflow->bottomVisualOverflow() : m_y + logicalHeight(); }
    193202    int leftVisualOverflow() const { return m_overflow ? m_overflow->leftVisualOverflow() : m_x; }
    194203    int rightVisualOverflow() const { return m_overflow ? m_overflow->rightVisualOverflow() : m_x + m_logicalWidth; }
    195     IntRect visualOverflowRect() const { return m_overflow ? m_overflow->visualOverflowRect() : IntRect(m_x, m_y, m_logicalWidth, logicalHeight()); }
     204    IntRect visualOverflowRect() const { return m_overflow ? m_overflow->visualOverflowRect() : IntRect(m_x, m_y, width(), height()); }
    196205    int logicalLeftVisualOverflow() const { return renderer()->style()->isHorizontalWritingMode() ? leftVisualOverflow() : topVisualOverflow(); }
    197206    int logicalRightVisualOverflow() const { return renderer()->style()->isHorizontalWritingMode() ? rightVisualOverflow() : bottomVisualOverflow(); }
    198    
     207    int logicalTopVisualOverflow() const { return renderer()->style()->isHorizontalWritingMode() ? topVisualOverflow() : leftVisualOverflow(); }
     208    int logicalBottomVisualOverflow() const { return renderer()->style()->isHorizontalWritingMode() ? bottomVisualOverflow() : rightVisualOverflow(); }
     209
    199210    void setInlineDirectionOverflowPositions(int logicalLeftLayoutOverflow, int logicalRightLayoutOverflow,
    200211                                             int logicalLeftVisualOverflow, int logicalRightVisualOverflow);
     
    267278        m_overflow->setBottomLayoutOverflow(logicalBottomLayoutOverflow);
    268279        m_overflow->setTopVisualOverflow(logicalTopVisualOverflow);
    269         m_overflow->setBottomVisualOverflow(logicalBottomVisualOverflow); 
     280        m_overflow->setBottomVisualOverflow(logicalBottomVisualOverflow);
    270281    } else {
    271282        m_overflow->setLeftLayoutOverflow(logicalTopLayoutOverflow);
  • trunk/WebCore/rendering/InlineTextBox.cpp

    r70281 r70356  
    303303        return false;
    304304
    305     IntRect rect(tx + m_x, ty + m_y, m_logicalWidth, logicalHeight());
     305    IntRect rect(tx + m_x, ty + m_y, width(), height());
    306306    if (m_truncation != cFullTruncation && visibleToHitTesting() && rect.intersects(result.rectForPoint(x, y))) {
    307307        renderer()->updateHitTestResult(result, IntPoint(x - tx, y - ty));
  • trunk/WebCore/rendering/RenderBox.cpp

    r70330 r70356  
    31733173}
    31743174
    3175 void RenderBox::blockDirectionOverflow(bool isLineVertical, bool isFlippedLine, int& logicalTopLayoutOverflow, int& logicalBottomLayoutOverflow,
     3175void RenderBox::blockDirectionOverflow(bool isLineVertical, int& logicalTopLayoutOverflow, int& logicalBottomLayoutOverflow,
    31763176                                       int& logicalTopVisualOverflow, int& logicalBottomVisualOverflow)
    31773177{
    31783178    if (isLineVertical) {
    3179         if (isFlippedLine) {
    3180             logicalTopLayoutOverflow = leftLayoutOverflow();
    3181             logicalBottomLayoutOverflow = rightLayoutOverflow();
    3182             logicalTopVisualOverflow = leftVisualOverflow();
    3183             logicalBottomVisualOverflow = rightVisualOverflow();
    3184         } else {
    3185             logicalTopLayoutOverflow = rightLayoutOverflow();
    3186             logicalBottomLayoutOverflow = leftLayoutOverflow();
    3187             logicalTopVisualOverflow = rightVisualOverflow();
    3188             logicalBottomVisualOverflow = leftVisualOverflow();
    3189         }
     3179        logicalTopLayoutOverflow = leftLayoutOverflow();
     3180        logicalBottomLayoutOverflow = rightLayoutOverflow();
     3181        logicalTopVisualOverflow = leftVisualOverflow();
     3182        logicalBottomVisualOverflow = rightVisualOverflow();
    31903183    } else {
    3191         if (isFlippedLine) {
    3192             logicalTopLayoutOverflow = bottomLayoutOverflow();
    3193             logicalBottomLayoutOverflow = topLayoutOverflow();
    3194             logicalTopVisualOverflow = bottomVisualOverflow();
    3195             logicalBottomVisualOverflow = topVisualOverflow();
    3196         } else {
    3197             logicalTopLayoutOverflow = topLayoutOverflow();
    3198             logicalBottomLayoutOverflow = bottomLayoutOverflow();
    3199             logicalTopVisualOverflow = topVisualOverflow();
    3200             logicalBottomVisualOverflow = bottomVisualOverflow();
    3201         }
     3184        logicalTopLayoutOverflow = topLayoutOverflow();
     3185        logicalBottomLayoutOverflow = bottomLayoutOverflow();
     3186        logicalTopVisualOverflow = topVisualOverflow();
     3187        logicalBottomVisualOverflow = bottomVisualOverflow();
    32023188    }
    32033189}
  • trunk/WebCore/rendering/RenderBox.h

    r70330 r70356  
    156156    void clearLayoutOverflow();
    157157
    158     void blockDirectionOverflow(bool isLineVertical, bool isFlippedLine, int& logicalTopLayoutOverflow, int& logicalBottomLayoutOverflow,
     158    void blockDirectionOverflow(bool isLineVertical, int& logicalTopLayoutOverflow, int& logicalBottomLayoutOverflow,
    159159                                int& logicalTopVisualOverflow, int& logicalBottomVisualOverflow);
    160160
  • trunk/WebCore/rendering/RenderLineBoxList.cpp

    r69336 r70356  
    247247        return false;
    248248
     249    bool isVertical = firstLineBox()->isVertical();
     250   
     251    int logicalPointStart = isVertical ? x - result.leftPadding() : y - result.topPadding();
     252    int logicalPointEnd = isVertical ? x + result.rightPadding() : y + result.bottomPadding();
     253    int offset = isVertical ? tx : ty;
     254
    249255    // We can check the first box and last box and avoid hit testing if we don't
    250256    // contain the point.  This is a quick short-circuit that we can take to avoid walking any lines.
    251257    // FIXME: This check is flawed in the following extremely obscure way:
    252258    // if some line in the middle has a huge overflow, it might actually extend below the last line.
    253     if (y - result.topPadding() >= ty + lastLineBox()->root()->bottomVisibleOverflow()
    254      || y + result.bottomPadding() < ty + firstLineBox()->root()->topVisibleOverflow())
     259    if (logicalPointStart >= offset + lastLineBox()->root()->logicalBottomVisibleOverflow()
     260        || logicalPointEnd < offset + firstLineBox()->root()->logicalTopVisibleOverflow())
    255261        return false;
    256262
     
    259265    // based off positions of our first line box or our last line box.
    260266    for (InlineFlowBox* curr = lastLineBox(); curr; curr = curr->prevLineBox()) {
    261         if (y + result.bottomPadding() >= ty + curr->root()->topVisibleOverflow()
    262          && y - result.topPadding() < ty + curr->root()->bottomVisibleOverflow()) {
     267        if (logicalPointEnd >= offset + curr->root()->logicalTopVisibleOverflow()
     268         && logicalPointStart < offset + curr->root()->logicalBottomVisibleOverflow()) {
    263269            bool inside = curr->nodeAtPoint(request, result, x, y, tx, ty);
    264270            if (inside) {
Note: See TracChangeset for help on using the changeset viewer.