Changeset 149007 in webkit
- Timestamp:
- Apr 23, 2013 5:18:27 PM (11 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 1 added
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r149005 r149007 1 2013-04-22 Ryosuke Niwa <rniwa@webkit.org> 2 3 logicalLeftSelectionGap and logicalRightSelectionGap call availableLogicalWidth() multiple times 4 https://bugs.webkit.org/show_bug.cgi?id=113479 5 6 Reviewed by David Hyatt. 7 8 Introduced LogicalSelectionOffsetCaches to cache the containing blocks and their logical left and right 9 selection offsets in computing selection gaps. An instance of this class stores the containing block for 10 each position type and caches their logical selection offsets when none of their block ancestors up until 11 its nearest selection root do no have any floating objects or regions and exclusions. 12 13 When blockSelectionGaps recurses to another level, it creates a new cache instance by "inheriting" 14 (like RenderStyle) from the old cache, overriding those containing blocks that are replaced by "this". 15 16 This eliminates the need to traverse containing block ancestors in RenderBlock::logicalLeftSelectionOffset 17 and RenderBlock::logicalRightSelectionOffset, and improves WebKit's performance by roughly 20%. 18 19 Performance Tests: Interactive/SelectAll.html 20 21 * GNUmakefile.list.am: 22 * Target.pri: 23 * WebCore.xcodeproj/project.pbxproj: 24 25 * rendering/LogicalSelectionOffsetCaches.h: Added. 26 (WebCore::isContainingBlockCandidateForAbsolutelyPositionedObject): Moved from RenderObject.h. 27 (WebCore::isNonRenderBlockInline): Ditto. 28 (WebCore::containingBlockForFixedPosition): Extracted from RenderObject::containingBlock. 29 (WebCore::containingBlockForAbsolutePosition): Ditto. 30 (WebCore::containingBlockForObjectInFlow): Ditto. 31 32 (WebCore::LogicalSelectionOffsetCaches): Added. 33 (WebCore::LogicalSelectionOffsetCaches::ContainingBlockInfo::ContainingBlockInfo): Added. 34 (WebCore::LogicalSelectionOffsetCaches::ContainingBlockInfo::setBlock): Added. m_hasFloatsOrRegions is 35 or'ed with itself when ContainingBlockInfo is copy constructed since m_hasFloatsOrRegions needs be true 36 for a block when any of its containing block ancestors have floats or regions. 37 (WebCore::LogicalSelectionOffsetCaches::ContainingBlockInfo::block): Added. 38 (WebCore::LogicalSelectionOffsetCaches::ContainingBlockInfo::cache): Added. 39 (WebCore::LogicalSelectionOffsetCaches::ContainingBlockInfo::logicalLeftSelectionOffset): Added. Caches 40 the logical selection offset if it hasn't. 41 (WebCore::LogicalSelectionOffsetCaches::ContainingBlockInfo::logicalRightSelectionOffset): Ditto. 42 43 (WebCore::LogicalSelectionOffsetCaches::LogicalSelectionOffsetCaches): The first constructor is used 44 for a selection root. The second one is used for inheriting from another cache. In the latter case, 45 copy all containing block information except ones that need to be overridden by this block. 46 (WebCore::LogicalSelectionOffsetCaches::containingBlockInfo): Returns a ContainingBlockInfo based on 47 object's position value. 48 49 * rendering/RenderBlock.cpp: 50 (WebCore::RenderBlock::selectionGapRectsForRepaint): 51 (WebCore::RenderBlock::paintSelection): 52 (WebCore::RenderBlock::selectionGaps): 53 (WebCore::RenderBlock::inlineSelectionGaps): 54 (WebCore::RenderBlock::blockSelectionGaps): Exit before instantiating a new LogicalSelectionOffsetCaches 55 if there is no child to recurse. 56 (WebCore::RenderBlock::blockSelectionGap): 57 (WebCore::RenderBlock::logicalLeftSelectionGap): 58 (WebCore::RenderBlock::logicalRightSelectionGap): 59 (WebCore::RenderBlock::logicalLeftSelectionOffset): Use LogicalSelectionOffsetCaches to get its containing 60 block and its logical selection offset. 61 (WebCore::RenderBlock::logicalRightSelectionOffset): Ditto. 62 63 * rendering/RenderBlock.h: 64 (WebCore::RenderBlock): 65 66 * rendering/RenderObject.cpp: 67 (WebCore::RenderObject::containingBlock): Extracted code into LogicalSelectionOffsetCaches.h. 68 69 * rendering/RootInlineBox.cpp: 70 (WebCore::RootInlineBox::lineSelectionGap): 71 72 * rendering/RootInlineBox.h: 73 (WebCore::RootInlineBox): 74 1 75 2013-04-23 Eric Carlson <eric.carlson@apple.com> 2 76 -
trunk/Source/WebCore/GNUmakefile.list.am
r148921 r149007 4441 4441 Source/WebCore/rendering/LayoutState.cpp \ 4442 4442 Source/WebCore/rendering/LayoutState.h \ 4443 Source/WebCore/rendering/LogicalSelectionOffsetCaches.h \ 4443 4444 Source/WebCore/rendering/LayoutRepainter.h \ 4444 4445 Source/WebCore/rendering/LayoutRepainter.cpp \ -
trunk/Source/WebCore/Target.pri
r148921 r149007 2449 2449 rendering/InlineFlowBox.h \ 2450 2450 rendering/InlineTextBox.h \ 2451 rendering/LayoutRepainter.h \ 2451 2452 rendering/LayoutState.h \ 2452 rendering/L ayoutRepainter.h \2453 rendering/LogicalSelectionOffsetCaches.h \ 2453 2454 rendering/mathml/RenderMathMLBlock.h \ 2454 2455 rendering/mathml/RenderMathMLFenced.h \ -
trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj
r148921 r149007 3309 3309 9B7E78BD16F16CC600126914 /* HTMLTreeBuilderSimulator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9B7E78BA16F16CAE00126914 /* HTMLTreeBuilderSimulator.cpp */; }; 3310 3310 9B7E78BE16F16CC800126914 /* HTMLTreeBuilderSimulator.h in Headers */ = {isa = PBXBuildFile; fileRef = 9B7E78BB16F16CAE00126914 /* HTMLTreeBuilderSimulator.h */; }; 3311 9BA273F4172206BB0097CE47 /* LogicalSelectionOffsetCaches.h in Headers */ = {isa = PBXBuildFile; fileRef = 9BA273F3172206BB0097CE47 /* LogicalSelectionOffsetCaches.h */; }; 3311 3312 9BAB6C6C12550631001626D4 /* EditingStyle.h in Headers */ = {isa = PBXBuildFile; fileRef = 9BAB6C6A12550631001626D4 /* EditingStyle.h */; settings = {ATTRIBUTES = (Private, ); }; }; 3312 3313 9BAB6C6D12550631001626D4 /* EditingStyle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9BAB6C6B12550631001626D4 /* EditingStyle.cpp */; }; … … 9785 9786 9B7E78BA16F16CAE00126914 /* HTMLTreeBuilderSimulator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = HTMLTreeBuilderSimulator.cpp; path = parser/HTMLTreeBuilderSimulator.cpp; sourceTree = "<group>"; }; 9786 9787 9B7E78BB16F16CAE00126914 /* HTMLTreeBuilderSimulator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = HTMLTreeBuilderSimulator.h; path = parser/HTMLTreeBuilderSimulator.h; sourceTree = "<group>"; }; 9788 9BA273F3172206BB0097CE47 /* LogicalSelectionOffsetCaches.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LogicalSelectionOffsetCaches.h; sourceTree = "<group>"; }; 9787 9789 9BAB6C6A12550631001626D4 /* EditingStyle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EditingStyle.h; sourceTree = "<group>"; }; 9788 9790 9BAB6C6B12550631001626D4 /* EditingStyle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = EditingStyle.cpp; sourceTree = "<group>"; }; … … 12602 12604 FABE72FB1059C21100D999DD /* MathMLElementFactory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MathMLElementFactory.cpp; sourceTree = "<group>"; }; 12603 12605 FABE72FC1059C21100D999DD /* MathMLNames.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MathMLNames.cpp; sourceTree = "<group>"; }; 12604 FB1A66D917225A6600BAA7AF /* CustomFilterColorParameter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CustomFilterColorParameter.h; path = filters/CustomFilterColorParameter.h; sourceTree = "<group>"; };12605 12606 FB0B75EE1723428500F05D2A /* WebKitCSSMatFunctionValue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebKitCSSMatFunctionValue.cpp; sourceTree = "<group>"; }; 12606 12607 FB0B75EF1723428500F05D2A /* WebKitCSSMatFunctionValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebKitCSSMatFunctionValue.h; sourceTree = "<group>"; }; 12608 FB1A66D917225A6600BAA7AF /* CustomFilterColorParameter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CustomFilterColorParameter.h; path = filters/CustomFilterColorParameter.h; sourceTree = "<group>"; }; 12607 12609 FB2C15C2165D64900039C9F8 /* CachedSVGDocumentReference.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CachedSVGDocumentReference.h; sourceTree = "<group>"; }; 12608 12610 FB3056C1169E5DAC0096A232 /* CSSGroupingRule.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSSGroupingRule.h; sourceTree = "<group>"; }; … … 20023 20025 2D9066040BE141D400956998 /* LayoutState.cpp */, 20024 20026 2D9066050BE141D400956998 /* LayoutState.h */, 20027 9BA273F3172206BB0097CE47 /* LogicalSelectionOffsetCaches.h */, 20025 20028 3774ABA30FA21EB400AD7DE9 /* OverlapTestRequestClient.h */, 20026 20029 9377AB9F15DEFEEF0031FD04 /* Pagination.h */, … … 22884 22887 BCE1C41B0D982980003B02F2 /* Location.h in Headers */, 22885 22888 A8239E0109B3CF8A00B60641 /* Logging.h in Headers */, 22889 9BA273F4172206BB0097CE47 /* LogicalSelectionOffsetCaches.h in Headers */, 22886 22890 E187056316E54A0D00585E97 /* MainThreadTask.h in Headers */, 22887 22891 1A8F6BC60DB55CDC001DB794 /* ManifestParser.h in Headers */, -
trunk/Source/WebCore/rendering/RenderBlock.cpp
r148921 r149007 42 42 #include "InlineTextBox.h" 43 43 #include "LayoutRepainter.h" 44 #include "LogicalSelectionOffsetCaches.h" 44 45 #include "OverflowEvent.h" 45 46 #include "PODFreeListArena.h" … … 3398 3399 offsetFromRepaintContainer -= scrolledContentOffset(); 3399 3400 3401 LogicalSelectionOffsetCaches cache(this); 3400 3402 LayoutUnit lastTop = 0; 3401 LayoutUnit lastLeft = logicalLeftSelectionOffset(this, lastTop );3402 LayoutUnit lastRight = logicalRightSelectionOffset(this, lastTop );3403 3404 return selectionGaps(this, offsetFromRepaintContainer, IntSize(), lastTop, lastLeft, lastRight );3403 LayoutUnit lastLeft = logicalLeftSelectionOffset(this, lastTop, cache); 3404 LayoutUnit lastRight = logicalRightSelectionOffset(this, lastTop, cache); 3405 3406 return selectionGaps(this, offsetFromRepaintContainer, IntSize(), lastTop, lastLeft, lastRight, cache); 3405 3407 } 3406 3408 … … 3408 3410 { 3409 3411 if (shouldPaintSelectionGaps() && paintInfo.phase == PaintPhaseForeground) { 3412 LogicalSelectionOffsetCaches cache(this); 3410 3413 LayoutUnit lastTop = 0; 3411 LayoutUnit lastLeft = logicalLeftSelectionOffset(this, lastTop );3412 LayoutUnit lastRight = logicalRightSelectionOffset(this, lastTop );3414 LayoutUnit lastLeft = logicalLeftSelectionOffset(this, lastTop, cache); 3415 LayoutUnit lastRight = logicalRightSelectionOffset(this, lastTop, cache); 3413 3416 GraphicsContextStateSaver stateSaver(*paintInfo.context); 3414 3417 3415 LayoutRect gapRectsBounds = selectionGaps(this, paintOffset, LayoutSize(), lastTop, lastLeft, lastRight, &paintInfo);3418 LayoutRect gapRectsBounds = selectionGaps(this, paintOffset, LayoutSize(), lastTop, lastLeft, lastRight, cache, &paintInfo); 3416 3419 if (!gapRectsBounds.isEmpty()) { 3417 3420 if (RenderLayer* layer = enclosingLayer()) { … … 3465 3468 3466 3469 GapRects RenderBlock::selectionGaps(RenderBlock* rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock, 3467 LayoutUnit& lastLogicalTop, LayoutUnit& lastLogicalLeft, LayoutUnit& lastLogicalRight, const PaintInfo* paintInfo)3470 LayoutUnit& lastLogicalTop, LayoutUnit& lastLogicalLeft, LayoutUnit& lastLogicalRight, const LogicalSelectionOffsetCaches& cache, const PaintInfo* paintInfo) 3468 3471 { 3469 3472 // IMPORTANT: Callers of this method that intend for painting to happen need to do a save/restore. … … 3502 3505 // FIXME: We should learn how to gap fill multiple columns and transforms eventually. 3503 3506 lastLogicalTop = blockDirectionOffset(rootBlock, offsetFromRootBlock) + logicalHeight(); 3504 lastLogicalLeft = logicalLeftSelectionOffset(rootBlock, logicalHeight() );3505 lastLogicalRight = logicalRightSelectionOffset(rootBlock, logicalHeight() );3507 lastLogicalLeft = logicalLeftSelectionOffset(rootBlock, logicalHeight(), cache); 3508 lastLogicalRight = logicalRightSelectionOffset(rootBlock, logicalHeight(), cache); 3506 3509 return result; 3507 3510 } 3508 3511 3509 3512 if (childrenInline()) 3510 result = inlineSelectionGaps(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, lastLogicalTop, lastLogicalLeft, lastLogicalRight, paintInfo);3513 result = inlineSelectionGaps(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, lastLogicalTop, lastLogicalLeft, lastLogicalRight, cache, paintInfo); 3511 3514 else 3512 result = blockSelectionGaps(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, lastLogicalTop, lastLogicalLeft, lastLogicalRight, paintInfo);3515 result = blockSelectionGaps(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, lastLogicalTop, lastLogicalLeft, lastLogicalRight, cache, paintInfo); 3513 3516 3514 3517 // Go ahead and fill the vertical gap all the way to the bottom of our block if the selection extends past our block. 3515 if (rootBlock == this && (selectionState() != SelectionBoth && selectionState() != SelectionEnd)) 3516 result.uniteCenter(blockSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, lastLogicalTop, lastLogicalLeft, lastLogicalRight, 3517 logicalHeight(), paintInfo)); 3518 if (rootBlock == this && (selectionState() != SelectionBoth && selectionState() != SelectionEnd)) { 3519 result.uniteCenter(blockSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, 3520 lastLogicalTop, lastLogicalLeft, lastLogicalRight, logicalHeight(), cache, paintInfo)); 3521 } 3522 3518 3523 return result; 3519 3524 } 3520 3525 3521 3526 GapRects RenderBlock::inlineSelectionGaps(RenderBlock* rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock, 3522 LayoutUnit& lastLogicalTop, LayoutUnit& lastLogicalLeft, LayoutUnit& lastLogicalRight, const PaintInfo* paintInfo)3527 LayoutUnit& lastLogicalTop, LayoutUnit& lastLogicalLeft, LayoutUnit& lastLogicalRight, const LogicalSelectionOffsetCaches& cache, const PaintInfo* paintInfo) 3523 3528 { 3524 3529 GapRects result; … … 3531 3536 // case. 3532 3537 lastLogicalTop = blockDirectionOffset(rootBlock, offsetFromRootBlock) + logicalHeight(); 3533 lastLogicalLeft = logicalLeftSelectionOffset(rootBlock, logicalHeight() );3534 lastLogicalRight = logicalRightSelectionOffset(rootBlock, logicalHeight() );3538 lastLogicalLeft = logicalLeftSelectionOffset(rootBlock, logicalHeight(), cache); 3539 lastLogicalRight = logicalRightSelectionOffset(rootBlock, logicalHeight(), cache); 3535 3540 } 3536 3541 return result; … … 3548 3553 if (!containsStart && !lastSelectedLine && 3549 3554 selectionState() != SelectionStart && selectionState() != SelectionBoth) 3550 result.uniteCenter(blockSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, lastLogicalTop, lastLogicalLeft, lastLogicalRight, 3551 selTop, paintInfo)); 3555 result.uniteCenter(blockSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, lastLogicalTop, lastLogicalLeft, lastLogicalRight, selTop, cache, paintInfo)); 3552 3556 3553 3557 LayoutRect logicalRect(curr->logicalLeft(), selTop, curr->logicalWidth(), selTop + selHeight); … … 3556 3560 if (!paintInfo || (isHorizontalWritingMode() && physicalRect.y() < paintInfo->rect.maxY() && physicalRect.maxY() > paintInfo->rect.y()) 3557 3561 || (!isHorizontalWritingMode() && physicalRect.x() < paintInfo->rect.maxX() && physicalRect.maxX() > paintInfo->rect.x())) 3558 result.unite(curr->lineSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, selTop, selHeight, paintInfo));3562 result.unite(curr->lineSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, selTop, selHeight, cache, paintInfo)); 3559 3563 3560 3564 lastSelectedLine = curr; … … 3568 3572 // Go ahead and update our lastY to be the bottom of the last selected line. 3569 3573 lastLogicalTop = blockDirectionOffset(rootBlock, offsetFromRootBlock) + lastSelectedLine->selectionBottom(); 3570 lastLogicalLeft = logicalLeftSelectionOffset(rootBlock, lastSelectedLine->selectionBottom() );3571 lastLogicalRight = logicalRightSelectionOffset(rootBlock, lastSelectedLine->selectionBottom() );3574 lastLogicalLeft = logicalLeftSelectionOffset(rootBlock, lastSelectedLine->selectionBottom(), cache); 3575 lastLogicalRight = logicalRightSelectionOffset(rootBlock, lastSelectedLine->selectionBottom(), cache); 3572 3576 } 3573 3577 return result; … … 3575 3579 3576 3580 GapRects RenderBlock::blockSelectionGaps(RenderBlock* rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock, 3577 LayoutUnit& lastLogicalTop, LayoutUnit& lastLogicalLeft, LayoutUnit& lastLogicalRight, const PaintInfo* paintInfo)3581 LayoutUnit& lastLogicalTop, LayoutUnit& lastLogicalLeft, LayoutUnit& lastLogicalRight, const LogicalSelectionOffsetCaches& cache, const PaintInfo* paintInfo) 3578 3582 { 3579 3583 GapRects result; … … 3582 3586 RenderBox* curr; 3583 3587 for (curr = firstChildBox(); curr && curr->selectionState() == SelectionNone; curr = curr->nextSiblingBox()) { } 3588 3589 if (!curr) 3590 return result; 3591 3592 LogicalSelectionOffsetCaches childCache(this, cache); 3584 3593 3585 3594 for (bool sawSelectionEnd = false; curr && !sawSelectionEnd; curr = curr->nextSiblingBox()) { … … 3603 3612 if (fillBlockGaps) { 3604 3613 // We need to fill the vertical gap above this object. 3605 if (childState == SelectionEnd || childState == SelectionInside) 3614 if (childState == SelectionEnd || childState == SelectionInside) { 3606 3615 // Fill the gap above the object. 3607 result.uniteCenter(blockSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, lastLogicalTop, lastLogicalLeft, lastLogicalRight, 3608 curr->logicalTop(), paintInfo)); 3616 result.uniteCenter(blockSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, 3617 lastLogicalTop, lastLogicalLeft, lastLogicalRight, curr->logicalTop(), cache, paintInfo)); 3618 } 3609 3619 3610 3620 // Only fill side gaps for objects that paint their own selection if we know for sure the selection is going to extend all the way *past* … … 3618 3628 3619 3629 if (leftGap) 3620 result.uniteLeft(logicalLeftSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, this, curr->logicalLeft(), curr->logicalTop(), curr->logicalHeight(), paintInfo));3630 result.uniteLeft(logicalLeftSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, this, curr->logicalLeft(), curr->logicalTop(), curr->logicalHeight(), cache, paintInfo)); 3621 3631 if (rightGap) 3622 result.uniteRight(logicalRightSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, this, curr->logicalRight(), curr->logicalTop(), curr->logicalHeight(), paintInfo));3632 result.uniteRight(logicalRightSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, this, curr->logicalRight(), curr->logicalTop(), curr->logicalHeight(), cache, paintInfo)); 3623 3633 3624 3634 // Update lastLogicalTop to be just underneath the object. lastLogicalLeft and lastLogicalRight extend as far as … … 3626 3636 // to the border of the root selection block. 3627 3637 lastLogicalTop = blockDirectionOffset(rootBlock, offsetFromRootBlock) + curr->logicalBottom(); 3628 lastLogicalLeft = logicalLeftSelectionOffset(rootBlock, curr->logicalBottom() );3629 lastLogicalRight = logicalRightSelectionOffset(rootBlock, curr->logicalBottom() );3630 } else if (childState != SelectionNone) 3638 lastLogicalLeft = logicalLeftSelectionOffset(rootBlock, curr->logicalBottom(), cache); 3639 lastLogicalRight = logicalRightSelectionOffset(rootBlock, curr->logicalBottom(), cache); 3640 } else if (childState != SelectionNone) { 3631 3641 // We must be a block that has some selected object inside it. Go ahead and recur. 3632 3642 result.unite(toRenderBlock(curr)->selectionGaps(rootBlock, rootBlockPhysicalPosition, LayoutSize(offsetFromRootBlock.width() + curr->x(), offsetFromRootBlock.height() + curr->y()), 3633 lastLogicalTop, lastLogicalLeft, lastLogicalRight, paintInfo)); 3643 lastLogicalTop, lastLogicalLeft, lastLogicalRight, childCache, paintInfo)); 3644 } 3634 3645 } 3635 3646 return result; … … 3637 3648 3638 3649 LayoutRect RenderBlock::blockSelectionGap(RenderBlock* rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock, 3639 LayoutUnit lastLogicalTop, LayoutUnit lastLogicalLeft, LayoutUnit lastLogicalRight, LayoutUnit logicalBottom, const PaintInfo* paintInfo)3650 LayoutUnit lastLogicalTop, LayoutUnit lastLogicalLeft, LayoutUnit lastLogicalRight, LayoutUnit logicalBottom, const LogicalSelectionOffsetCaches& cache, const PaintInfo* paintInfo) 3640 3651 { 3641 3652 LayoutUnit logicalTop = lastLogicalTop; … … 3645 3656 3646 3657 // Get the selection offsets for the bottom of the gap 3647 LayoutUnit logicalLeft = max(lastLogicalLeft, logicalLeftSelectionOffset(rootBlock, logicalBottom ));3648 LayoutUnit logicalRight = min(lastLogicalRight, logicalRightSelectionOffset(rootBlock, logicalBottom ));3658 LayoutUnit logicalLeft = max(lastLogicalLeft, logicalLeftSelectionOffset(rootBlock, logicalBottom, cache)); 3659 LayoutUnit logicalRight = min(lastLogicalRight, logicalRightSelectionOffset(rootBlock, logicalBottom, cache)); 3649 3660 LayoutUnit logicalWidth = logicalRight - logicalLeft; 3650 3661 if (logicalWidth <= 0) … … 3658 3669 3659 3670 LayoutRect RenderBlock::logicalLeftSelectionGap(RenderBlock* rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock, 3660 RenderObject* selObj, LayoutUnit logicalLeft, LayoutUnit logicalTop, LayoutUnit logicalHeight, const PaintInfo* paintInfo)3671 RenderObject* selObj, LayoutUnit logicalLeft, LayoutUnit logicalTop, LayoutUnit logicalHeight, const LogicalSelectionOffsetCaches& cache, const PaintInfo* paintInfo) 3661 3672 { 3662 3673 LayoutUnit rootBlockLogicalTop = blockDirectionOffset(rootBlock, offsetFromRootBlock) + logicalTop; 3663 LayoutUnit rootBlockLogicalLeft = max(logicalLeftSelectionOffset(rootBlock, logicalTop), logicalLeftSelectionOffset(rootBlock, logicalTop + logicalHeight)); 3664 LayoutUnit rootBlockLogicalRight = min(inlineDirectionOffset(rootBlock, offsetFromRootBlock) + floorToInt(logicalLeft), min(logicalRightSelectionOffset(rootBlock, logicalTop), logicalRightSelectionOffset(rootBlock, logicalTop + logicalHeight))); 3674 LayoutUnit rootBlockLogicalLeft = max(logicalLeftSelectionOffset(rootBlock, logicalTop, cache), logicalLeftSelectionOffset(rootBlock, logicalTop + logicalHeight, cache)); 3675 LayoutUnit rootBlockLogicalRight = min(inlineDirectionOffset(rootBlock, offsetFromRootBlock) + floorToInt(logicalLeft), 3676 min(logicalRightSelectionOffset(rootBlock, logicalTop, cache), logicalRightSelectionOffset(rootBlock, logicalTop + logicalHeight, cache))); 3665 3677 LayoutUnit rootBlockLogicalWidth = rootBlockLogicalRight - rootBlockLogicalLeft; 3666 3678 if (rootBlockLogicalWidth <= 0) … … 3674 3686 3675 3687 LayoutRect RenderBlock::logicalRightSelectionGap(RenderBlock* rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock, 3676 RenderObject* selObj, LayoutUnit logicalRight, LayoutUnit logicalTop, LayoutUnit logicalHeight, const PaintInfo* paintInfo)3688 RenderObject* selObj, LayoutUnit logicalRight, LayoutUnit logicalTop, LayoutUnit logicalHeight, const LogicalSelectionOffsetCaches& cache, const PaintInfo* paintInfo) 3677 3689 { 3678 3690 LayoutUnit rootBlockLogicalTop = blockDirectionOffset(rootBlock, offsetFromRootBlock) + logicalTop; 3679 LayoutUnit rootBlockLogicalLeft = max(inlineDirectionOffset(rootBlock, offsetFromRootBlock) + floorToInt(logicalRight), max(logicalLeftSelectionOffset(rootBlock, logicalTop), logicalLeftSelectionOffset(rootBlock, logicalTop + logicalHeight))); 3680 LayoutUnit rootBlockLogicalRight = min(logicalRightSelectionOffset(rootBlock, logicalTop), logicalRightSelectionOffset(rootBlock, logicalTop + logicalHeight)); 3691 LayoutUnit rootBlockLogicalLeft = max(inlineDirectionOffset(rootBlock, offsetFromRootBlock) + floorToInt(logicalRight), 3692 max(logicalLeftSelectionOffset(rootBlock, logicalTop, cache), logicalLeftSelectionOffset(rootBlock, logicalTop + logicalHeight, cache))); 3693 LayoutUnit rootBlockLogicalRight = min(logicalRightSelectionOffset(rootBlock, logicalTop, cache), logicalRightSelectionOffset(rootBlock, logicalTop + logicalHeight, cache)); 3681 3694 LayoutUnit rootBlockLogicalWidth = rootBlockLogicalRight - rootBlockLogicalLeft; 3682 3695 if (rootBlockLogicalWidth <= 0) … … 3700 3713 } 3701 3714 3702 LayoutUnit RenderBlock::logicalLeftSelectionOffset(RenderBlock* rootBlock, LayoutUnit position )3715 LayoutUnit RenderBlock::logicalLeftSelectionOffset(RenderBlock* rootBlock, LayoutUnit position, const LogicalSelectionOffsetCaches& cache) 3703 3716 { 3704 3717 LayoutUnit logicalLeft = logicalLeftOffsetForLine(position, false); 3705 3718 if (logicalLeft == logicalLeftOffsetForContent()) { 3706 if (rootBlock != this) 3707 // The border can potentially be further extended by our containingBlock(). 3708 return containingBlock()->logicalLeftSelectionOffset(rootBlock, position + logicalTop()); 3719 if (rootBlock != this) // The border can potentially be further extended by our containingBlock(). 3720 return cache.containingBlockInfo(this).logicalLeftSelectionOffset(rootBlock, position + logicalTop()); 3709 3721 return logicalLeft; 3710 3722 } else { 3711 3723 RenderBlock* cb = this; 3724 const LogicalSelectionOffsetCaches* currentCache = &cache; 3712 3725 while (cb != rootBlock) { 3713 3726 logicalLeft += cb->logicalLeft(); 3714 cb = cb->containingBlock(); 3727 3728 ASSERT(currentCache); 3729 const LogicalSelectionOffsetCaches::ContainingBlockInfo& info = currentCache->containingBlockInfo(cb); 3730 cb = info.block(); 3731 currentCache = info.cache(); 3715 3732 } 3716 3733 } … … 3718 3735 } 3719 3736 3720 LayoutUnit RenderBlock::logicalRightSelectionOffset(RenderBlock* rootBlock, LayoutUnit position )3737 LayoutUnit RenderBlock::logicalRightSelectionOffset(RenderBlock* rootBlock, LayoutUnit position, const LogicalSelectionOffsetCaches& cache) 3721 3738 { 3722 3739 LayoutUnit logicalRight = logicalRightOffsetForLine(position, false); 3723 3740 if (logicalRight == logicalRightOffsetForContent()) { 3724 if (rootBlock != this) 3725 // The border can potentially be further extended by our containingBlock(). 3726 return containingBlock()->logicalRightSelectionOffset(rootBlock, position + logicalTop()); 3741 if (rootBlock != this) // The border can potentially be further extended by our containingBlock(). 3742 return cache.containingBlockInfo(this).logicalRightSelectionOffset(rootBlock, position + logicalTop()); 3727 3743 return logicalRight; 3728 3744 } else { 3729 3745 RenderBlock* cb = this; 3746 const LogicalSelectionOffsetCaches* currentCache = &cache; 3730 3747 while (cb != rootBlock) { 3731 3748 logicalRight += cb->logicalLeft(); 3732 cb = cb->containingBlock(); 3749 3750 ASSERT(currentCache); 3751 const LogicalSelectionOffsetCaches::ContainingBlockInfo& info = currentCache->containingBlockInfo(cb); 3752 cb = info.block(); 3753 currentCache = info.cache(); 3733 3754 } 3734 3755 } -
trunk/Source/WebCore/rendering/RenderBlock.h
r148921 r149007 47 47 class LineLayoutState; 48 48 class LineWidth; 49 class LogicalSelectionOffsetCaches; 49 50 class RenderInline; 50 51 class RenderText; … … 244 245 GapRects selectionGapRectsForRepaint(const RenderLayerModelObject* repaintContainer); 245 246 LayoutRect logicalLeftSelectionGap(RenderBlock* rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock, 246 RenderObject* selObj, LayoutUnit logicalLeft, LayoutUnit logicalTop, LayoutUnit logicalHeight, const PaintInfo*);247 RenderObject* selObj, LayoutUnit logicalLeft, LayoutUnit logicalTop, LayoutUnit logicalHeight, const LogicalSelectionOffsetCaches&, const PaintInfo*); 247 248 LayoutRect logicalRightSelectionGap(RenderBlock* rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock, 248 RenderObject* selObj, LayoutUnit logicalRight, LayoutUnit logicalTop, LayoutUnit logicalHeight, const PaintInfo*);249 RenderObject* selObj, LayoutUnit logicalRight, LayoutUnit logicalTop, LayoutUnit logicalHeight, const LogicalSelectionOffsetCaches&, const PaintInfo*); 249 250 void getSelectionGapInfo(SelectionState, bool& leftGap, bool& rightGap); 250 251 RenderBlock* blockBeforeWithinSelectionRoot(LayoutSize& offset) const; … … 926 927 bool isSelectionRoot() const; 927 928 GapRects selectionGaps(RenderBlock* rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock, 928 LayoutUnit& lastLogicalTop, LayoutUnit& lastLogicalLeft, LayoutUnit& lastLogicalRight, const PaintInfo* = 0);929 LayoutUnit& lastLogicalTop, LayoutUnit& lastLogicalLeft, LayoutUnit& lastLogicalRight, const LogicalSelectionOffsetCaches&, const PaintInfo* = 0); 929 930 GapRects inlineSelectionGaps(RenderBlock* rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock, 930 LayoutUnit& lastLogicalTop, LayoutUnit& lastLogicalLeft, LayoutUnit& lastLogicalRight, const PaintInfo*);931 LayoutUnit& lastLogicalTop, LayoutUnit& lastLogicalLeft, LayoutUnit& lastLogicalRight, const LogicalSelectionOffsetCaches&, const PaintInfo*); 931 932 GapRects blockSelectionGaps(RenderBlock* rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock, 932 LayoutUnit& lastLogicalTop, LayoutUnit& lastLogicalLeft, LayoutUnit& lastLogicalRight, const PaintInfo*);933 LayoutUnit& lastLogicalTop, LayoutUnit& lastLogicalLeft, LayoutUnit& lastLogicalRight, const LogicalSelectionOffsetCaches&, const PaintInfo*); 933 934 LayoutRect blockSelectionGap(RenderBlock* rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock, 934 LayoutUnit lastLogicalTop, LayoutUnit lastLogicalLeft, LayoutUnit lastLogicalRight, LayoutUnit logicalBottom, const PaintInfo*); 935 LayoutUnit logicalLeftSelectionOffset(RenderBlock* rootBlock, LayoutUnit position); 936 LayoutUnit logicalRightSelectionOffset(RenderBlock* rootBlock, LayoutUnit position); 935 LayoutUnit lastLogicalTop, LayoutUnit lastLogicalLeft, LayoutUnit lastLogicalRight, LayoutUnit logicalBottom, const LogicalSelectionOffsetCaches&, const PaintInfo*); 936 LayoutUnit logicalLeftSelectionOffset(RenderBlock* rootBlock, LayoutUnit position, const LogicalSelectionOffsetCaches&); 937 LayoutUnit logicalRightSelectionOffset(RenderBlock* rootBlock, LayoutUnit position, const LogicalSelectionOffsetCaches&); 938 939 friend class LogicalSelectionOffsetCaches; 937 940 938 941 virtual void absoluteRects(Vector<IntRect>&, const LayoutPoint& accumulatedOffset) const; -
trunk/Source/WebCore/rendering/RenderObject.cpp
r148921 r149007 45 45 #include "HTMLNames.h" 46 46 #include "HitTestResult.h" 47 #include "LogicalSelectionOffsetCaches.h" 47 48 #include "Page.h" 48 49 #include "RenderArena.h" … … 768 769 } 769 770 770 static inline bool isContainingBlockCandidateForAbsolutelyPositionedObject(RenderObject* object)771 {772 return object->style()->position() != StaticPosition773 || (object->hasTransform() && object->isRenderBlock())774 #if ENABLE(SVG)775 || object->isSVGForeignObject()776 #endif777 || object->isRenderView();778 }779 780 static inline bool isNonRenderBlockInline(RenderObject* object)781 {782 return (object->isInline() && !object->isReplaced()) || !object->isRenderBlock();783 }784 785 771 RenderBlock* RenderObject::containingBlock() const 786 772 { … … 789 775 o = toRenderScrollbarPart(this)->rendererOwningScrollbar(); 790 776 791 if (!isText() && m_style->position() == FixedPosition) { 792 while (o && !o->canContainFixedPositionObjects()) 793 o = o->parent(); 794 ASSERT(!o || !o->isAnonymousBlock()); 795 } else if (!isText() && m_style->position() == AbsolutePosition) { 796 while (o && !isContainingBlockCandidateForAbsolutelyPositionedObject(o)) 797 o = o->parent(); 798 799 // For a relatively positioned inline, return its nearest non-anonymous containing block, 800 // not the inline itself, to avoid having a positioned objects list in all RenderInlines 801 // and use RenderBlock* as this function's return type. 802 // Use RenderBlock::container() to obtain the inline. 803 if (o && o->isRenderInline()) 804 o = o->containingBlock(); 805 806 while (o && o->isAnonymousBlock()) 807 o = o->containingBlock(); 808 } else { 809 while (o && isNonRenderBlockInline(o)) 810 o = o->parent(); 811 } 777 if (!isText() && m_style->position() == FixedPosition) 778 o = containingBlockForFixedPosition(o); 779 else if (!isText() && m_style->position() == AbsolutePosition) 780 o = containingBlockForAbsolutePosition(o); 781 else 782 o = containingBlockForObjectInFlow(o); 812 783 813 784 if (!o || !o->isRenderBlock()) -
trunk/Source/WebCore/rendering/RootInlineBox.cpp
r146104 r149007 30 30 #include "HitTestResult.h" 31 31 #include "InlineTextBox.h" 32 #include "LogicalSelectionOffsetCaches.h" 32 33 #include "Page.h" 33 34 #include "PaintInfo.h" … … 467 468 } 468 469 469 GapRects RootInlineBox::lineSelectionGap(RenderBlock* rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock, 470 LayoutUnit selTop, LayoutUnit selHeight, const PaintInfo* paintInfo)470 GapRects RootInlineBox::lineSelectionGap(RenderBlock* rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock, 471 LayoutUnit selTop, LayoutUnit selHeight, const LogicalSelectionOffsetCaches& cache, const PaintInfo* paintInfo) 471 472 { 472 473 RenderObject::SelectionState lineState = selectionState(); … … 479 480 InlineBox* firstBox = firstSelectedBox(); 480 481 InlineBox* lastBox = lastSelectedBox(); 481 if (leftGap) 482 result.uniteLeft(block()->logicalLeftSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, 483 firstBox->parent()->renderer(), firstBox->logicalLeft(), selTop, selHeight, paintInfo)); 484 if (rightGap) 485 result.uniteRight(block()->logicalRightSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, 486 lastBox->parent()->renderer(), lastBox->logicalRight(), selTop, selHeight, paintInfo)); 482 if (leftGap) { 483 result.uniteLeft(block()->logicalLeftSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, firstBox->parent()->renderer(), firstBox->logicalLeft(), 484 selTop, selHeight, cache, paintInfo)); 485 } 486 if (rightGap) { 487 result.uniteRight(block()->logicalRightSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, lastBox->parent()->renderer(), lastBox->logicalRight(), 488 selTop, selHeight, cache, paintInfo)); 489 } 487 490 488 491 // When dealing with bidi text, a non-contiguous selection region is possible. -
trunk/Source/WebCore/rendering/RootInlineBox.h
r146104 r149007 29 29 class EllipsisBox; 30 30 class HitTestResult; 31 class LogicalSelectionOffsetCaches; 31 32 class RenderRegion; 32 33 … … 132 133 InlineBox* lastSelectedBox(); 133 134 134 GapRects lineSelectionGap(RenderBlock* rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock, LayoutUnit selTop, LayoutUnit selHeight, const PaintInfo*); 135 GapRects lineSelectionGap(RenderBlock* rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock, 136 LayoutUnit selTop, LayoutUnit selHeight, const LogicalSelectionOffsetCaches&, const PaintInfo*); 135 137 136 138 RenderBlock* block() const;
Note: See TracChangeset
for help on using the changeset viewer.