Changeset 70356 in webkit
- Timestamp:
- Oct 22, 2010 3:36:42 PM (14 years ago)
- Location:
- trunk/WebCore
- Files:
-
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/WebCore/ChangeLog
r70355 r70356 1 2010-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 1 38 2010-10-22 Dan Bernstein <mitz@apple.com> 2 39 -
trunk/WebCore/page/EventHandler.cpp
r69467 r70356 1057 1057 Cursor EventHandler::selectCursor(const MouseEventWithHitTestResults& event, Scrollbar* scrollbar) 1058 1058 { 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 1059 1066 // During selection, use an I-beam no matter what we're over. 1060 1067 // If you're capturing mouse events for a particular node, don't treat this as a selection. 1061 1068 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; 1067 1070 1068 1071 if (renderer && renderer->isFrameSet()) { … … 1134 1137 } 1135 1138 if ((editable || (renderer && renderer->isText() && node->canStartSelection())) && !inResizer && !scrollbar) 1136 return iBeam Cursor();1139 return iBeam; 1137 1140 return pointerCursor(); 1138 1141 } -
trunk/WebCore/rendering/InlineBox.h
r70330 r70356 217 217 int y() const { return m_y; } 218 218 219 int width() const { return m_isVertical ? logicalHeight() : logicalWidth(); } 220 int height() const { return m_isVertical ? logicalWidth() : logicalHeight(); } 221 219 222 // The logicalLeft position is the left edge of the line box in a horizontal line and the top edge in a vertical line. 220 223 int logicalLeft() const { return !m_isVertical ? m_x : m_y; } -
trunk/WebCore/rendering/InlineFlowBox.cpp
r70330 r70356 300 300 int textShadowLogicalRight; 301 301 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); 304 304 logicalLeftVisualOverflow = min(logicalLeft + childOverflowLogicalLeft, logicalLeftVisualOverflow); 305 305 logicalRightVisualOverflow = max(logicalLeft + text->logicalWidth() + childOverflowLogicalRight, logicalRightVisualOverflow); … … 613 613 curr->renderer()->style(m_firstLine)->getTextShadowBlockDirectionExtent(textShadowTop, textShadowBottom); 614 614 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); 617 617 618 618 topVisualOverflow = min(curr->logicalTop() + childOverflowTop, topVisualOverflow); … … 621 621 InlineFlowBox* flow = static_cast<InlineFlowBox*>(curr); 622 622 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()); 627 627 } else if (!curr->boxModelObject()->hasSelfPaintingLayer()){ 628 628 // Only include overflow from replaced inlines if they do not paint themselves. … … 634 634 635 635 RenderBox* box = toRenderBox(curr->renderer()); 636 box->blockDirectionOverflow(isVertical(), isFlippedLine,childTopLayoutOverflow, childBottomLayoutOverflow,636 box->blockDirectionOverflow(isVertical(), childTopLayoutOverflow, childBottomLayoutOverflow, 637 637 childTopVisualOverflow, childBottomVisualOverflow); 638 638 639 if (box->hasOverflowClip()) { 640 childTopLayoutOverflow = 0; 641 childBottomLayoutOverflow = curr->logicalHeight(); 642 } 643 639 644 topLayoutOverflow = min(boxLogicalTop + childTopLayoutOverflow, topLayoutOverflow); 640 645 bottomLayoutOverflow = max(boxLogicalTop + childBottomLayoutOverflow, bottomLayoutOverflow); … … 663 668 664 669 // 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()); 666 671 if (visibleToHitTesting() && rect.intersects(result.rectForPoint(x, y))) { 667 672 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 175 175 void setHasBadChildList(); 176 176 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. 177 181 int topVisibleOverflow() const { return std::min(topLayoutOverflow(), topVisualOverflow()); } 178 182 int bottomVisibleOverflow() const { return std::max(bottomLayoutOverflow(), bottomVisualOverflow()); } 179 183 int leftVisibleOverflow() const { return std::min(leftLayoutOverflow(), leftVisualOverflow()); } 180 184 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()); } 182 189 183 190 int topLayoutOverflow() const { return m_overflow ? m_overflow->topLayoutOverflow() : m_y; } … … 185 192 int leftLayoutOverflow() const { return m_overflow ? m_overflow->leftLayoutOverflow() : m_x; } 186 193 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()); } 188 195 int logicalLeftLayoutOverflow() const { return renderer()->style()->isHorizontalWritingMode() ? leftLayoutOverflow() : topLayoutOverflow(); } 189 196 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 191 200 int topVisualOverflow() const { return m_overflow ? m_overflow->topVisualOverflow() : m_y; } 192 201 int bottomVisualOverflow() const { return m_overflow ? m_overflow->bottomVisualOverflow() : m_y + logicalHeight(); } 193 202 int leftVisualOverflow() const { return m_overflow ? m_overflow->leftVisualOverflow() : m_x; } 194 203 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()); } 196 205 int logicalLeftVisualOverflow() const { return renderer()->style()->isHorizontalWritingMode() ? leftVisualOverflow() : topVisualOverflow(); } 197 206 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 199 210 void setInlineDirectionOverflowPositions(int logicalLeftLayoutOverflow, int logicalRightLayoutOverflow, 200 211 int logicalLeftVisualOverflow, int logicalRightVisualOverflow); … … 267 278 m_overflow->setBottomLayoutOverflow(logicalBottomLayoutOverflow); 268 279 m_overflow->setTopVisualOverflow(logicalTopVisualOverflow); 269 m_overflow->setBottomVisualOverflow(logicalBottomVisualOverflow); 280 m_overflow->setBottomVisualOverflow(logicalBottomVisualOverflow); 270 281 } else { 271 282 m_overflow->setLeftLayoutOverflow(logicalTopLayoutOverflow); -
trunk/WebCore/rendering/InlineTextBox.cpp
r70281 r70356 303 303 return false; 304 304 305 IntRect rect(tx + m_x, ty + m_y, m_logicalWidth, logicalHeight());305 IntRect rect(tx + m_x, ty + m_y, width(), height()); 306 306 if (m_truncation != cFullTruncation && visibleToHitTesting() && rect.intersects(result.rectForPoint(x, y))) { 307 307 renderer()->updateHitTestResult(result, IntPoint(x - tx, y - ty)); -
trunk/WebCore/rendering/RenderBox.cpp
r70330 r70356 3173 3173 } 3174 3174 3175 void RenderBox::blockDirectionOverflow(bool isLineVertical, bool isFlippedLine,int& logicalTopLayoutOverflow, int& logicalBottomLayoutOverflow,3175 void RenderBox::blockDirectionOverflow(bool isLineVertical, int& logicalTopLayoutOverflow, int& logicalBottomLayoutOverflow, 3176 3176 int& logicalTopVisualOverflow, int& logicalBottomVisualOverflow) 3177 3177 { 3178 3178 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(); 3190 3183 } 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(); 3202 3188 } 3203 3189 } -
trunk/WebCore/rendering/RenderBox.h
r70330 r70356 156 156 void clearLayoutOverflow(); 157 157 158 void blockDirectionOverflow(bool isLineVertical, bool isFlippedLine,int& logicalTopLayoutOverflow, int& logicalBottomLayoutOverflow,158 void blockDirectionOverflow(bool isLineVertical, int& logicalTopLayoutOverflow, int& logicalBottomLayoutOverflow, 159 159 int& logicalTopVisualOverflow, int& logicalBottomVisualOverflow); 160 160 -
trunk/WebCore/rendering/RenderLineBoxList.cpp
r69336 r70356 247 247 return false; 248 248 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 249 255 // We can check the first box and last box and avoid hit testing if we don't 250 256 // contain the point. This is a quick short-circuit that we can take to avoid walking any lines. 251 257 // FIXME: This check is flawed in the following extremely obscure way: 252 258 // 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()) 255 261 return false; 256 262 … … 259 265 // based off positions of our first line box or our last line box. 260 266 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()) { 263 269 bool inside = curr->nodeAtPoint(request, result, x, y, tx, ty); 264 270 if (inside) {
Note: See TracChangeset
for help on using the changeset viewer.