| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) | 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) |
| 3 * (C) 1999 Antti Koivisto (koivisto@kde.org) | 3 * (C) 1999 Antti Koivisto (koivisto@kde.org) |
| 4 * (C) 2007 David Smith (catfish.man@gmail.com) | 4 * (C) 2007 David Smith (catfish.man@gmail.com) |
| 5 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc.
All rights reserved. | 5 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc.
All rights reserved. |
| 6 * Copyright (C) Research In Motion Limited 2010. All rights reserved. | 6 * Copyright (C) Research In Motion Limited 2010. All rights reserved. |
| 7 * | 7 * |
| 8 * This library is free software; you can redistribute it and/or | 8 * This library is free software; you can redistribute it and/or |
| 9 * modify it under the terms of the GNU Library General Public | 9 * modify it under the terms of the GNU Library General Public |
| 10 * License as published by the Free Software Foundation; either | 10 * License as published by the Free Software Foundation; either |
| (...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 235 | 235 |
| 236 void RenderBlock::destroy() | 236 void RenderBlock::destroy() |
| 237 { | 237 { |
| 238 RenderBox::destroy(); | 238 RenderBox::destroy(); |
| 239 #if ENABLE(OILPAN) | 239 #if ENABLE(OILPAN) |
| 240 // RenderObject::removeChild called in destory() depends on gColumnInfoMap. | 240 // RenderObject::removeChild called in destory() depends on gColumnInfoMap. |
| 241 removeFromGlobalMaps(); | 241 removeFromGlobalMaps(); |
| 242 #endif | 242 #endif |
| 243 } | 243 } |
| 244 | 244 |
| 245 LayoutRect RenderBlock::selectionRectForPaintInvalidation(const RenderLayerModel
Object* paintInvalidationContainer) const | |
| 246 { | |
| 247 LayoutRect rect = selectionGapRectsForPaintInvalidation(paintInvalidationCon
tainer); | |
| 248 // FIXME: groupedMapping() leaks the squashing abstraction. | |
| 249 if (paintInvalidationContainer->layer()->groupedMapping()) | |
| 250 RenderLayer::mapRectToPaintBackingCoordinates(paintInvalidationContainer
, rect); | |
| 251 return rect; | |
| 252 } | |
| 253 void RenderBlock::willBeDestroyed() | 245 void RenderBlock::willBeDestroyed() |
| 254 { | 246 { |
| 255 // Mark as being destroyed to avoid trouble with merges in removeChild(). | 247 // Mark as being destroyed to avoid trouble with merges in removeChild(). |
| 256 m_beingDestroyed = true; | 248 m_beingDestroyed = true; |
| 257 | 249 |
| 258 // Make sure to destroy anonymous children first while they are still connec
ted to the rest of the tree, so that they will | 250 // Make sure to destroy anonymous children first while they are still connec
ted to the rest of the tree, so that they will |
| 259 // properly dirty line boxes that they are removed from. Effects that do :be
fore/:after only on hover could crash otherwise. | 251 // properly dirty line boxes that they are removed from. Effects that do :be
fore/:after only on hover could crash otherwise. |
| 260 children()->destroyLeftoverChildren(); | 252 children()->destroyLeftoverChildren(); |
| 261 | 253 |
| 262 // Destroy our continuation before anything other than anonymous children. | 254 // Destroy our continuation before anything other than anonymous children. |
| (...skipping 1570 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1833 ContinuationOutlineTableMap* table = continuationOutlineTable(); | 1825 ContinuationOutlineTableMap* table = continuationOutlineTable(); |
| 1834 ListHashSet<RenderInline*>* continuations = table->get(this); | 1826 ListHashSet<RenderInline*>* continuations = table->get(this); |
| 1835 if (!continuations) { | 1827 if (!continuations) { |
| 1836 continuations = new ListHashSet<RenderInline*>; | 1828 continuations = new ListHashSet<RenderInline*>; |
| 1837 table->set(this, adoptPtr(continuations)); | 1829 table->set(this, adoptPtr(continuations)); |
| 1838 } | 1830 } |
| 1839 | 1831 |
| 1840 continuations->add(flow); | 1832 continuations->add(flow); |
| 1841 } | 1833 } |
| 1842 | 1834 |
| 1843 bool RenderBlock::shouldPaintSelectionGaps() const | |
| 1844 { | |
| 1845 return selectionState() != SelectionNone && style()->visibility() == VISIBLE
&& isSelectionRoot(); | |
| 1846 } | |
| 1847 | |
| 1848 bool RenderBlock::isSelectionRoot() const | 1835 bool RenderBlock::isSelectionRoot() const |
| 1849 { | 1836 { |
| 1850 if (isPseudoElement()) | 1837 if (isPseudoElement()) |
| 1851 return false; | 1838 return false; |
| 1852 ASSERT(node() || isAnonymous()); | 1839 ASSERT(node() || isAnonymous()); |
| 1853 | 1840 |
| 1854 // FIXME: Eventually tables should have to learn how to fill gaps between ce
lls, at least in simple non-spanning cases. | 1841 // FIXME: Eventually tables should have to learn how to fill gaps between ce
lls, at least in simple non-spanning cases. |
| 1855 if (isTable()) | 1842 if (isTable()) |
| 1856 return false; | 1843 return false; |
| 1857 | 1844 |
| 1858 if (isBody() || isDocumentElement() || hasOverflowClip() | 1845 if (isBody() || isDocumentElement() || hasOverflowClip() |
| 1859 || isPositioned() || isFloating() | 1846 || isPositioned() || isFloating() |
| 1860 || isTableCell() || isInlineBlockOrInlineTable() | 1847 || isTableCell() || isInlineBlockOrInlineTable() |
| 1861 || hasTransformRelatedProperty() || hasReflection() || hasMask() || isWr
itingModeRoot() | 1848 || hasTransformRelatedProperty() || hasReflection() || hasMask() || isWr
itingModeRoot() |
| 1862 || isRenderFlowThread() || isFlexItemIncludingDeprecated()) | 1849 || isRenderFlowThread() || isFlexItemIncludingDeprecated()) |
| 1863 return true; | 1850 return true; |
| 1864 | 1851 |
| 1865 if (view() && view()->selectionStart()) { | 1852 if (view() && view()->selectionStart()) { |
| 1866 Node* startElement = view()->selectionStart()->node(); | 1853 Node* startElement = view()->selectionStart()->node(); |
| 1867 if (startElement && startElement->rootEditableElement() == node()) | 1854 if (startElement && startElement->rootEditableElement() == node()) |
| 1868 return true; | 1855 return true; |
| 1869 } | 1856 } |
| 1870 | 1857 |
| 1871 return false; | 1858 return false; |
| 1872 } | 1859 } |
| 1873 | 1860 |
| 1874 GapRects RenderBlock::selectionGapRectsForPaintInvalidation(const RenderLayerMod
elObject* paintInvalidationContainer) const | |
| 1875 { | |
| 1876 ASSERT(!needsLayout()); | |
| 1877 | |
| 1878 if (!shouldPaintSelectionGaps()) | |
| 1879 return GapRects(); | |
| 1880 | |
| 1881 TransformState transformState(TransformState::ApplyTransformDirection, Float
Point()); | |
| 1882 mapLocalToContainer(paintInvalidationContainer, transformState, ApplyContain
erFlip | UseTransforms); | |
| 1883 LayoutPoint offsetFromPaintInvalidationContainer = roundedLayoutPoint(transf
ormState.mappedPoint()); | |
| 1884 | |
| 1885 if (hasOverflowClip()) | |
| 1886 offsetFromPaintInvalidationContainer -= scrolledContentOffset(); | |
| 1887 | |
| 1888 LayoutUnit lastTop = 0; | |
| 1889 LayoutUnit lastLeft = logicalLeftSelectionOffset(this, lastTop); | |
| 1890 LayoutUnit lastRight = logicalRightSelectionOffset(this, lastTop); | |
| 1891 | |
| 1892 return selectionGaps(this, offsetFromPaintInvalidationContainer, IntSize(),
lastTop, lastLeft, lastRight); | |
| 1893 } | |
| 1894 | |
| 1895 static void clipOutPositionedObjects(const PaintInfo* paintInfo, const LayoutPoi
nt& offset, TrackedRendererListHashSet* positionedObjects) | |
| 1896 { | |
| 1897 if (!positionedObjects) | |
| 1898 return; | |
| 1899 | |
| 1900 TrackedRendererListHashSet::const_iterator end = positionedObjects->end(); | |
| 1901 for (TrackedRendererListHashSet::const_iterator it = positionedObjects->begi
n(); it != end; ++it) { | |
| 1902 RenderBox* r = *it; | |
| 1903 paintInfo->context->clipOut(IntRect(offset.x() + r->x(), offset.y() + r-
>y(), r->width(), r->height())); | |
| 1904 } | |
| 1905 } | |
| 1906 | |
| 1907 LayoutUnit RenderBlock::blockDirectionOffset(const LayoutSize& offsetFromBlock)
const | 1861 LayoutUnit RenderBlock::blockDirectionOffset(const LayoutSize& offsetFromBlock)
const |
| 1908 { | 1862 { |
| 1909 return isHorizontalWritingMode() ? offsetFromBlock.height() : offsetFromBloc
k.width(); | 1863 return isHorizontalWritingMode() ? offsetFromBlock.height() : offsetFromBloc
k.width(); |
| 1910 } | 1864 } |
| 1911 | 1865 |
| 1912 LayoutUnit RenderBlock::inlineDirectionOffset(const LayoutSize& offsetFromBlock)
const | 1866 LayoutUnit RenderBlock::inlineDirectionOffset(const LayoutSize& offsetFromBlock)
const |
| 1913 { | 1867 { |
| 1914 return isHorizontalWritingMode() ? offsetFromBlock.width() : offsetFromBlock
.height(); | 1868 return isHorizontalWritingMode() ? offsetFromBlock.width() : offsetFromBlock
.height(); |
| 1915 } | 1869 } |
| 1916 | 1870 |
| 1917 LayoutRect RenderBlock::logicalRectToPhysicalRect(const LayoutPoint& rootBlockPh
ysicalPosition, const LayoutRect& logicalRect) const | 1871 LayoutRect RenderBlock::logicalRectToPhysicalRect(const LayoutPoint& rootBlockPh
ysicalPosition, const LayoutRect& logicalRect) const |
| 1918 { | 1872 { |
| 1919 LayoutRect result; | 1873 LayoutRect result; |
| 1920 if (isHorizontalWritingMode()) | 1874 if (isHorizontalWritingMode()) |
| 1921 result = logicalRect; | 1875 result = logicalRect; |
| 1922 else | 1876 else |
| 1923 result = LayoutRect(logicalRect.y(), logicalRect.x(), logicalRect.height
(), logicalRect.width()); | 1877 result = LayoutRect(logicalRect.y(), logicalRect.x(), logicalRect.height
(), logicalRect.width()); |
| 1924 flipForWritingMode(result); | 1878 flipForWritingMode(result); |
| 1925 result.moveBy(rootBlockPhysicalPosition); | 1879 result.moveBy(rootBlockPhysicalPosition); |
| 1926 return result; | 1880 return result; |
| 1927 } | 1881 } |
| 1928 | 1882 |
| 1929 GapRects RenderBlock::selectionGaps(const RenderBlock* rootBlock, const LayoutPo
int& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock, | |
| 1930 LayoutUnit& lastLogicalTop, LayoutUnit& last
LogicalLeft, LayoutUnit& lastLogicalRight, const PaintInfo* paintInfo) const | |
| 1931 { | |
| 1932 // IMPORTANT: Callers of this method that intend for painting to happen need
to do a save/restore. | |
| 1933 // Clip out floating and positioned objects when painting selection gaps. | |
| 1934 if (paintInfo) { | |
| 1935 // Note that we don't clip out overflow for positioned objects. We just
stick to the border box. | |
| 1936 LayoutRect flippedBlockRect(offsetFromRootBlock.width(), offsetFromRootB
lock.height(), width(), height()); | |
| 1937 rootBlock->flipForWritingMode(flippedBlockRect); | |
| 1938 flippedBlockRect.moveBy(rootBlockPhysicalPosition); | |
| 1939 clipOutPositionedObjects(paintInfo, flippedBlockRect.location(), positio
nedObjects()); | |
| 1940 if (isBody() || isDocumentElement()) // The <body> must make sure to exa
mine its containingBlock's positioned objects. | |
| 1941 for (RenderBlock* cb = containingBlock(); cb && !cb->isRenderView();
cb = cb->containingBlock()) | |
| 1942 clipOutPositionedObjects(paintInfo, LayoutPoint(cb->x(), cb->y()
), cb->positionedObjects()); // FIXME: Not right for flipped writing modes. | |
| 1943 clipOutFloatingObjects(rootBlock, paintInfo, rootBlockPhysicalPosition,
offsetFromRootBlock); | |
| 1944 } | |
| 1945 | |
| 1946 // FIXME: overflow: auto/scroll regions need more math here, since painting
in the border box is different from painting in the padding box (one is scrolled
, the other is | |
| 1947 // fixed). | |
| 1948 GapRects result; | |
| 1949 if (!isRenderBlockFlow()) // FIXME: Make multi-column selection gap filling
work someday. | |
| 1950 return result; | |
| 1951 | |
| 1952 if (hasColumns() || hasTransformRelatedProperty() || style()->columnSpan())
{ | |
| 1953 // FIXME: We should learn how to gap fill multiple columns and transform
s eventually. | |
| 1954 lastLogicalTop = rootBlock->blockDirectionOffset(offsetFromRootBlock) +
logicalHeight(); | |
| 1955 lastLogicalLeft = logicalLeftSelectionOffset(rootBlock, logicalHeight())
; | |
| 1956 lastLogicalRight = logicalRightSelectionOffset(rootBlock, logicalHeight(
)); | |
| 1957 return result; | |
| 1958 } | |
| 1959 | |
| 1960 if (childrenInline()) | |
| 1961 result = toRenderBlockFlow(this)->inlineSelectionGaps(rootBlock, rootBlo
ckPhysicalPosition, offsetFromRootBlock, lastLogicalTop, lastLogicalLeft, lastLo
gicalRight, paintInfo); | |
| 1962 else | |
| 1963 result = blockSelectionGaps(rootBlock, rootBlockPhysicalPosition, offset
FromRootBlock, lastLogicalTop, lastLogicalLeft, lastLogicalRight, paintInfo); | |
| 1964 | |
| 1965 // Go ahead and fill the vertical gap all the way to the bottom of our block
if the selection extends past our block. | |
| 1966 if (rootBlock == this && (selectionState() != SelectionBoth && selectionStat
e() != SelectionEnd)) | |
| 1967 result.uniteCenter(blockSelectionGap(rootBlock, rootBlockPhysicalPositio
n, offsetFromRootBlock, lastLogicalTop, lastLogicalLeft, lastLogicalRight, | |
| 1968 logicalHeight(), paintInfo)); | |
| 1969 return result; | |
| 1970 } | |
| 1971 | |
| 1972 GapRects RenderBlock::blockSelectionGaps(const RenderBlock* rootBlock, const Lay
outPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock, | |
| 1973 LayoutUnit& lastLogicalTop, LayoutUnit&
lastLogicalLeft, LayoutUnit& lastLogicalRight, const PaintInfo* paintInfo) cons
t | |
| 1974 { | |
| 1975 GapRects result; | |
| 1976 | |
| 1977 // Go ahead and jump right to the first block child that contains some selec
ted objects. | |
| 1978 RenderBox* curr; | |
| 1979 for (curr = firstChildBox(); curr && curr->selectionState() == SelectionNone
; curr = curr->nextSiblingBox()) { } | |
| 1980 | |
| 1981 for (bool sawSelectionEnd = false; curr && !sawSelectionEnd; curr = curr->ne
xtSiblingBox()) { | |
| 1982 SelectionState childState = curr->selectionState(); | |
| 1983 if (childState == SelectionBoth || childState == SelectionEnd) | |
| 1984 sawSelectionEnd = true; | |
| 1985 | |
| 1986 if (curr->isFloatingOrOutOfFlowPositioned()) | |
| 1987 continue; // We must be a normal flow object in order to even be con
sidered. | |
| 1988 | |
| 1989 if (curr->isRelPositioned() && curr->hasLayer()) { | |
| 1990 // If the relposition offset is anything other than 0, then treat th
is just like an absolute positioned element. | |
| 1991 // Just disregard it completely. | |
| 1992 LayoutSize relOffset = curr->layer()->offsetForInFlowPosition(); | |
| 1993 if (relOffset.width() || relOffset.height()) | |
| 1994 continue; | |
| 1995 } | |
| 1996 | |
| 1997 bool paintsOwnSelection = curr->shouldPaintSelectionGaps() || curr->isTa
ble(); // FIXME: Eventually we won't special-case table like this. | |
| 1998 bool fillBlockGaps = paintsOwnSelection || (curr->canBeSelectionLeaf() &
& childState != SelectionNone); | |
| 1999 if (fillBlockGaps) { | |
| 2000 // We need to fill the vertical gap above this object. | |
| 2001 if (childState == SelectionEnd || childState == SelectionInside) | |
| 2002 // Fill the gap above the object. | |
| 2003 result.uniteCenter(blockSelectionGap(rootBlock, rootBlockPhysica
lPosition, offsetFromRootBlock, lastLogicalTop, lastLogicalLeft, lastLogicalRigh
t, | |
| 2004 curr->logicalTop(), paintIn
fo)); | |
| 2005 | |
| 2006 // 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* | |
| 2007 // our object. We know this if the selection did not end inside our
object. | |
| 2008 if (paintsOwnSelection && (childState == SelectionStart || sawSelect
ionEnd)) | |
| 2009 childState = SelectionNone; | |
| 2010 | |
| 2011 // Fill side gaps on this object based off its state. | |
| 2012 bool leftGap, rightGap; | |
| 2013 getSelectionGapInfo(childState, leftGap, rightGap); | |
| 2014 | |
| 2015 if (leftGap) | |
| 2016 result.uniteLeft(logicalLeftSelectionGap(rootBlock, rootBlockPhy
sicalPosition, offsetFromRootBlock, this, curr->logicalLeft(), curr->logicalTop(
), curr->logicalHeight(), paintInfo)); | |
| 2017 if (rightGap) | |
| 2018 result.uniteRight(logicalRightSelectionGap(rootBlock, rootBlockP
hysicalPosition, offsetFromRootBlock, this, curr->logicalRight(), curr->logicalT
op(), curr->logicalHeight(), paintInfo)); | |
| 2019 | |
| 2020 // Update lastLogicalTop to be just underneath the object. lastLogi
calLeft and lastLogicalRight extend as far as | |
| 2021 // they can without bumping into floating or positioned objects. Id
eally they will go right up | |
| 2022 // to the border of the root selection block. | |
| 2023 lastLogicalTop = rootBlock->blockDirectionOffset(offsetFromRootBlock
) + curr->logicalBottom(); | |
| 2024 lastLogicalLeft = logicalLeftSelectionOffset(rootBlock, curr->logica
lBottom()); | |
| 2025 lastLogicalRight = logicalRightSelectionOffset(rootBlock, curr->logi
calBottom()); | |
| 2026 } else if (childState != SelectionNone) | |
| 2027 // We must be a block that has some selected object inside it. Go a
head and recur. | |
| 2028 result.unite(toRenderBlock(curr)->selectionGaps(rootBlock, rootBlock
PhysicalPosition, LayoutSize(offsetFromRootBlock.width() + curr->x(), offsetFrom
RootBlock.height() + curr->y()), | |
| 2029 lastLogicalTop, last
LogicalLeft, lastLogicalRight, paintInfo)); | |
| 2030 } | |
| 2031 return result; | |
| 2032 } | |
| 2033 | |
| 2034 IntRect alignSelectionRectToDevicePixels(LayoutRect& rect) | |
| 2035 { | |
| 2036 LayoutUnit roundedX = rect.x().round(); | |
| 2037 return IntRect(roundedX, rect.y().round(), | |
| 2038 (rect.maxX() - roundedX).round(), | |
| 2039 snapSizeToPixel(rect.height(), rect.y())); | |
| 2040 } | |
| 2041 | |
| 2042 LayoutRect RenderBlock::blockSelectionGap(const RenderBlock* rootBlock, const La
youtPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock, | |
| 2043 LayoutUnit lastLogicalTop, LayoutUnit
lastLogicalLeft, LayoutUnit lastLogicalRight, LayoutUnit logicalBottom, const Pa
intInfo* paintInfo) const | |
| 2044 { | |
| 2045 LayoutUnit logicalTop = lastLogicalTop; | |
| 2046 LayoutUnit logicalHeight = rootBlock->blockDirectionOffset(offsetFromRootBlo
ck) + logicalBottom - logicalTop; | |
| 2047 if (logicalHeight <= 0) | |
| 2048 return LayoutRect(); | |
| 2049 | |
| 2050 // Get the selection offsets for the bottom of the gap | |
| 2051 LayoutUnit logicalLeft = std::max(lastLogicalLeft, logicalLeftSelectionOffse
t(rootBlock, logicalBottom)); | |
| 2052 LayoutUnit logicalRight = std::min(lastLogicalRight, logicalRightSelectionOf
fset(rootBlock, logicalBottom)); | |
| 2053 LayoutUnit logicalWidth = logicalRight - logicalLeft; | |
| 2054 if (logicalWidth <= 0) | |
| 2055 return LayoutRect(); | |
| 2056 | |
| 2057 LayoutRect gapRect = rootBlock->logicalRectToPhysicalRect(rootBlockPhysicalP
osition, LayoutRect(logicalLeft, logicalTop, logicalWidth, logicalHeight)); | |
| 2058 if (paintInfo) { | |
| 2059 IntRect selectionGapRect = alignSelectionRectToDevicePixels(gapRect); | |
| 2060 DrawingRecorder recorder(paintInfo->context, this, paintInfo->phase, sel
ectionGapRect); | |
| 2061 paintInfo->context->fillRect(selectionGapRect, selectionBackgroundColor(
)); | |
| 2062 } | |
| 2063 return gapRect; | |
| 2064 } | |
| 2065 | |
| 2066 LayoutRect RenderBlock::logicalLeftSelectionGap(const RenderBlock* rootBlock, co
nst LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBloc
k, | |
| 2067 const RenderObject* selObj, Layo
utUnit logicalLeft, LayoutUnit logicalTop, LayoutUnit logicalHeight, const Paint
Info* paintInfo) const | |
| 2068 { | |
| 2069 LayoutUnit rootBlockLogicalTop = rootBlock->blockDirectionOffset(offsetFromR
ootBlock) + logicalTop; | |
| 2070 LayoutUnit rootBlockLogicalLeft = std::max(logicalLeftSelectionOffset(rootBl
ock, logicalTop), logicalLeftSelectionOffset(rootBlock, logicalTop + logicalHeig
ht)); | |
| 2071 LayoutUnit rootBlockLogicalRight = std::min(rootBlock->inlineDirectionOffset
(offsetFromRootBlock) + logicalLeft, std::min(logicalRightSelectionOffset(rootBl
ock, logicalTop), logicalRightSelectionOffset(rootBlock, logicalTop + logicalHei
ght))); | |
| 2072 LayoutUnit rootBlockLogicalWidth = rootBlockLogicalRight - rootBlockLogicalL
eft; | |
| 2073 if (rootBlockLogicalWidth <= 0) | |
| 2074 return LayoutRect(); | |
| 2075 | |
| 2076 LayoutRect gapRect = rootBlock->logicalRectToPhysicalRect(rootBlockPhysicalP
osition, LayoutRect(rootBlockLogicalLeft, rootBlockLogicalTop, rootBlockLogicalW
idth, logicalHeight)); | |
| 2077 if (paintInfo) { | |
| 2078 IntRect selectionGapRect = alignSelectionRectToDevicePixels(gapRect); | |
| 2079 DrawingRecorder recorder(paintInfo->context, this, paintInfo->phase, sel
ectionGapRect); | |
| 2080 paintInfo->context->fillRect(selectionGapRect, selObj->selectionBackgrou
ndColor()); | |
| 2081 } | |
| 2082 return gapRect; | |
| 2083 } | |
| 2084 | |
| 2085 LayoutRect RenderBlock::logicalRightSelectionGap(const RenderBlock* rootBlock, c
onst LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlo
ck, | |
| 2086 const RenderObject* selObj, Lay
outUnit logicalRight, LayoutUnit logicalTop, LayoutUnit logicalHeight, const Pai
ntInfo* paintInfo) const | |
| 2087 { | |
| 2088 LayoutUnit rootBlockLogicalTop = rootBlock->blockDirectionOffset(offsetFromR
ootBlock) + logicalTop; | |
| 2089 LayoutUnit rootBlockLogicalLeft = std::max(rootBlock->inlineDirectionOffset(
offsetFromRootBlock) + logicalRight, max(logicalLeftSelectionOffset(rootBlock, l
ogicalTop), logicalLeftSelectionOffset(rootBlock, logicalTop + logicalHeight))); | |
| 2090 LayoutUnit rootBlockLogicalRight = std::min(logicalRightSelectionOffset(root
Block, logicalTop), logicalRightSelectionOffset(rootBlock, logicalTop + logicalH
eight)); | |
| 2091 LayoutUnit rootBlockLogicalWidth = rootBlockLogicalRight - rootBlockLogicalL
eft; | |
| 2092 if (rootBlockLogicalWidth <= 0) | |
| 2093 return LayoutRect(); | |
| 2094 | |
| 2095 LayoutRect gapRect = rootBlock->logicalRectToPhysicalRect(rootBlockPhysicalP
osition, LayoutRect(rootBlockLogicalLeft, rootBlockLogicalTop, rootBlockLogicalW
idth, logicalHeight)); | |
| 2096 if (paintInfo) { | |
| 2097 IntRect selectionGapRect = alignSelectionRectToDevicePixels(gapRect); | |
| 2098 DrawingRecorder recorder(paintInfo->context, this, paintInfo->phase, sel
ectionGapRect); | |
| 2099 paintInfo->context->fillRect(selectionGapRect, selObj->selectionBackgrou
ndColor()); | |
| 2100 } | |
| 2101 return gapRect; | |
| 2102 } | |
| 2103 | |
| 2104 void RenderBlock::getSelectionGapInfo(SelectionState state, bool& leftGap, bool&
rightGap) const | |
| 2105 { | |
| 2106 bool ltr = style()->isLeftToRightDirection(); | |
| 2107 leftGap = (state == RenderObject::SelectionInside) || | |
| 2108 (state == RenderObject::SelectionEnd && ltr) || | |
| 2109 (state == RenderObject::SelectionStart && !ltr); | |
| 2110 rightGap = (state == RenderObject::SelectionInside) || | |
| 2111 (state == RenderObject::SelectionStart && ltr) || | |
| 2112 (state == RenderObject::SelectionEnd && !ltr); | |
| 2113 } | |
| 2114 | |
| 2115 LayoutUnit RenderBlock::logicalLeftSelectionOffset(const RenderBlock* rootBlock,
LayoutUnit position) const | 1883 LayoutUnit RenderBlock::logicalLeftSelectionOffset(const RenderBlock* rootBlock,
LayoutUnit position) const |
| 2116 { | 1884 { |
| 2117 // The border can potentially be further extended by our containingBlock(). | 1885 // The border can potentially be further extended by our containingBlock(). |
| 2118 if (rootBlock != this) | 1886 if (rootBlock != this) |
| 2119 return containingBlock()->logicalLeftSelectionOffset(rootBlock, position
+ logicalTop()); | 1887 return containingBlock()->logicalLeftSelectionOffset(rootBlock, position
+ logicalTop()); |
| 2120 return logicalLeftOffsetForContent(); | 1888 return logicalLeftOffsetForContent(); |
| 2121 } | 1889 } |
| 2122 | 1890 |
| 2123 LayoutUnit RenderBlock::logicalRightSelectionOffset(const RenderBlock* rootBlock
, LayoutUnit position) const | 1891 LayoutUnit RenderBlock::logicalRightSelectionOffset(const RenderBlock* rootBlock
, LayoutUnit position) const |
| 2124 { | 1892 { |
| (...skipping 2293 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4418 void RenderBlock::showLineTreeAndMark(const InlineBox* markedBox1, const char* m
arkedLabel1, const InlineBox* markedBox2, const char* markedLabel2, const Render
Object* obj) const | 4186 void RenderBlock::showLineTreeAndMark(const InlineBox* markedBox1, const char* m
arkedLabel1, const InlineBox* markedBox2, const char* markedLabel2, const Render
Object* obj) const |
| 4419 { | 4187 { |
| 4420 showRenderObject(); | 4188 showRenderObject(); |
| 4421 for (const RootInlineBox* root = firstRootBox(); root; root = root->nextRoot
Box()) | 4189 for (const RootInlineBox* root = firstRootBox(); root; root = root->nextRoot
Box()) |
| 4422 root->showLineTreeAndMark(markedBox1, markedLabel1, markedBox2, markedLa
bel2, obj, 1); | 4190 root->showLineTreeAndMark(markedBox1, markedLabel1, markedBox2, markedLa
bel2, obj, 1); |
| 4423 } | 4191 } |
| 4424 | 4192 |
| 4425 #endif | 4193 #endif |
| 4426 | 4194 |
| 4427 } // namespace blink | 4195 } // namespace blink |
| OLD | NEW |