Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(228)

Side by Side Diff: Source/core/rendering/RenderReplaced.cpp

Issue 930833003: Move and rename RenderReplaced and RenderHTMLCanvas to Layout{Replaced,HTMLCanvas}. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: No need to declare renderName() at all. Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « Source/core/rendering/RenderReplaced.h ('k') | Source/core/rendering/svg/RenderSVGRoot.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /*
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3 * Copyright (C) 2000 Dirk Mueller (mueller@kde.org)
4 * Copyright (C) 2004, 2006, 2007 Apple Inc. All rights reserved.
5 * Copyright (C) Research In Motion Limited 2011-2012. All rights reserved.
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Library General Public License for more details.
16 *
17 * You should have received a copy of the GNU Library General Public License
18 * along with this library; see the file COPYING.LIB. If not, write to
19 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 * Boston, MA 02110-1301, USA.
21 *
22 */
23
24 #include "config.h"
25 #include "core/rendering/RenderReplaced.h"
26
27 #include "core/editing/PositionWithAffinity.h"
28 #include "core/layout/Layer.h"
29 #include "core/layout/LayoutImage.h"
30 #include "core/paint/ReplacedPainter.h"
31 #include "core/rendering/RenderBlock.h"
32 #include "core/rendering/RenderView.h"
33 #include "platform/LengthFunctions.h"
34
35 namespace blink {
36
37 const int RenderReplaced::defaultWidth = 300;
38 const int RenderReplaced::defaultHeight = 150;
39
40 RenderReplaced::RenderReplaced(Element* element)
41 : RenderBox(element)
42 , m_intrinsicSize(defaultWidth, defaultHeight)
43 {
44 setReplaced(true);
45 }
46
47 RenderReplaced::RenderReplaced(Element* element, const LayoutSize& intrinsicSize )
48 : RenderBox(element)
49 , m_intrinsicSize(intrinsicSize)
50 {
51 setReplaced(true);
52 }
53
54 RenderReplaced::~RenderReplaced()
55 {
56 }
57
58 void RenderReplaced::willBeDestroyed()
59 {
60 if (!documentBeingDestroyed() && parent())
61 parent()->dirtyLinesFromChangedChild(this);
62
63 RenderBox::willBeDestroyed();
64 }
65
66 void RenderReplaced::styleDidChange(StyleDifference diff, const LayoutStyle* old Style)
67 {
68 RenderBox::styleDidChange(diff, oldStyle);
69
70 bool hadStyle = (oldStyle != 0);
71 float oldZoom = hadStyle ? oldStyle->effectiveZoom() : LayoutStyle::initialZ oom();
72 if (style() && style()->effectiveZoom() != oldZoom)
73 intrinsicSizeChanged();
74 }
75
76 void RenderReplaced::layout()
77 {
78 ASSERT(needsLayout());
79
80 LayoutRect oldContentRect = replacedContentRect();
81
82 setHeight(minimumReplacedHeight());
83
84 updateLogicalWidth();
85 updateLogicalHeight();
86
87 m_overflow.clear();
88 addVisualEffectOverflow();
89 updateLayerTransformAfterLayout();
90 invalidateBackgroundObscurationStatus();
91
92 clearNeedsLayout();
93
94 if (replacedContentRect() != oldContentRect)
95 setShouldDoFullPaintInvalidation();
96 }
97
98 void RenderReplaced::intrinsicSizeChanged()
99 {
100 int scaledWidth = static_cast<int>(defaultWidth * style()->effectiveZoom());
101 int scaledHeight = static_cast<int>(defaultHeight * style()->effectiveZoom() );
102 m_intrinsicSize = LayoutSize(scaledWidth, scaledHeight);
103 setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation();
104 }
105
106 void RenderReplaced::paint(const PaintInfo& paintInfo, const LayoutPoint& paintO ffset)
107 {
108 ReplacedPainter(*this).paint(paintInfo, paintOffset);
109 }
110
111 bool RenderReplaced::shouldPaint(const PaintInfo& paintInfo, const LayoutPoint& paintOffset) const
112 {
113 if (paintInfo.phase != PaintPhaseForeground && paintInfo.phase != PaintPhase Outline && paintInfo.phase != PaintPhaseSelfOutline
114 && paintInfo.phase != PaintPhaseSelection && paintInfo.phase != PaintPha seMask && paintInfo.phase != PaintPhaseClippingMask)
115 return false;
116
117 if (!paintInfo.shouldPaintWithinRoot(this))
118 return false;
119
120 // if we're invisible or haven't received a layout yet, then just bail.
121 if (style()->visibility() != VISIBLE)
122 return false;
123
124 LayoutPoint adjustedPaintOffset = paintOffset + location();
125
126 // Early exit if the element touches the edges.
127 LayoutUnit top = adjustedPaintOffset.y() + visualOverflowRect().y();
128 LayoutUnit bottom = adjustedPaintOffset.y() + visualOverflowRect().maxY();
129 if (isSelected() && inlineBoxWrapper()) {
130 LayoutUnit selTop = paintOffset.y() + inlineBoxWrapper()->root().selecti onTop();
131 LayoutUnit selBottom = paintOffset.y() + selTop + inlineBoxWrapper()->ro ot().selectionHeight();
132 top = std::min(selTop, top);
133 bottom = std::max(selBottom, bottom);
134 }
135
136 if (adjustedPaintOffset.x() + visualOverflowRect().x() >= paintInfo.rect.max X() || adjustedPaintOffset.x() + visualOverflowRect().maxX() <= paintInfo.rect.x ())
137 return false;
138
139 if (top >= paintInfo.rect.maxY() || bottom <= paintInfo.rect.y())
140 return false;
141
142 return true;
143 }
144
145 bool RenderReplaced::hasReplacedLogicalHeight() const
146 {
147 if (style()->logicalHeight().isAuto())
148 return false;
149
150 if (style()->logicalHeight().isSpecified()) {
151 if (hasAutoHeightOrContainingBlockWithAutoHeight())
152 return false;
153 return true;
154 }
155
156 if (style()->logicalHeight().isIntrinsic())
157 return true;
158
159 return false;
160 }
161
162 bool RenderReplaced::needsPreferredWidthsRecalculation() const
163 {
164 // If the height is a percentage and the width is auto, then the containingB locks's height changing can cause
165 // this node to change it's preferred width because it maintains aspect rati o.
166 return hasRelativeLogicalHeight() && style()->logicalWidth().isAuto() && !ha sAutoHeightOrContainingBlockWithAutoHeight();
167 }
168
169 static inline bool rendererHasAspectRatio(const LayoutObject* renderer)
170 {
171 ASSERT(renderer);
172 return renderer->isImage() || renderer->isCanvas() || renderer->isVideo();
173 }
174
175 void RenderReplaced::computeAspectRatioInformationForRenderBox(RenderBox* conten tRenderer, FloatSize& constrainedSize, double& intrinsicRatio) const
176 {
177 FloatSize intrinsicSize;
178 if (contentRenderer) {
179 contentRenderer->computeIntrinsicRatioInformation(intrinsicSize, intrins icRatio);
180
181 // Handle zoom & vertical writing modes here, as the embedded document d oesn't know about them.
182 intrinsicSize.scale(style()->effectiveZoom());
183 if (isLayoutImage())
184 intrinsicSize.scale(toLayoutImage(this)->imageDevicePixelRatio());
185
186 // Update our intrinsic size to match what the content renderer has comp uted, so that when we
187 // constrain the size below, the correct intrinsic size will be obtained for comparison against
188 // min and max widths.
189 if (intrinsicRatio && !intrinsicSize.isEmpty())
190 m_intrinsicSize = LayoutSize(intrinsicSize);
191
192 if (!isHorizontalWritingMode()) {
193 if (intrinsicRatio)
194 intrinsicRatio = 1 / intrinsicRatio;
195 intrinsicSize = intrinsicSize.transposedSize();
196 }
197 } else {
198 computeIntrinsicRatioInformation(intrinsicSize, intrinsicRatio);
199 if (intrinsicRatio && !intrinsicSize.isEmpty())
200 m_intrinsicSize = LayoutSize(isHorizontalWritingMode() ? intrinsicSi ze : intrinsicSize.transposedSize());
201 }
202
203 // Now constrain the intrinsic size along each axis according to minimum and maximum width/heights along the
204 // opposite axis. So for example a maximum width that shrinks our width will result in the height we compute here
205 // having to shrink in order to preserve the aspect ratio. Because we comput e these values independently along
206 // each axis, the final returned size may in fact not preserve the aspect ra tio.
207 // FIXME: In the long term, it might be better to just return this code more to the way it used to be before this
208 // function was added, since all it has done is make the code more unclear.
209 constrainedSize = intrinsicSize;
210 if (intrinsicRatio && !intrinsicSize.isEmpty() && style()->logicalWidth().is Auto() && style()->logicalHeight().isAuto()) {
211 // We can't multiply or divide by 'intrinsicRatio' here, it breaks tests , like fast/images/zoomed-img-size.html, which
212 // can only be fixed once subpixel precision is available for things lik e intrinsicWidth/Height - which include zoom!
213 constrainedSize.setWidth(RenderBox::computeReplacedLogicalHeight() * int rinsicSize.width() / intrinsicSize.height());
214 constrainedSize.setHeight(RenderBox::computeReplacedLogicalWidth() * int rinsicSize.height() / intrinsicSize.width());
215 }
216 }
217
218 LayoutRect RenderReplaced::replacedContentRect(const LayoutSize* overriddenIntri nsicSize) const
219 {
220 LayoutRect contentRect = contentBoxRect();
221 ObjectFit objectFit = style()->objectFit();
222
223 if (objectFit == ObjectFitFill && style()->objectPosition() == LayoutStyle:: initialObjectPosition()) {
224 return contentRect;
225 }
226
227 LayoutSize intrinsicSize = overriddenIntrinsicSize ? *overriddenIntrinsicSiz e : this->intrinsicSize();
228 if (!intrinsicSize.width() || !intrinsicSize.height())
229 return contentRect;
230
231 LayoutRect finalRect = contentRect;
232 switch (objectFit) {
233 case ObjectFitContain:
234 case ObjectFitScaleDown:
235 case ObjectFitCover:
236 finalRect.setSize(finalRect.size().fitToAspectRatio(intrinsicSize, objec tFit == ObjectFitCover ? AspectRatioFitGrow : AspectRatioFitShrink));
237 if (objectFit != ObjectFitScaleDown || finalRect.width() <= intrinsicSiz e.width())
238 break;
239 // fall through
240 case ObjectFitNone:
241 finalRect.setSize(intrinsicSize);
242 break;
243 case ObjectFitFill:
244 break;
245 default:
246 ASSERT_NOT_REACHED();
247 }
248
249 LayoutUnit xOffset = minimumValueForLength(style()->objectPosition().x(), co ntentRect.width() - finalRect.width());
250 LayoutUnit yOffset = minimumValueForLength(style()->objectPosition().y(), co ntentRect.height() - finalRect.height());
251 finalRect.move(xOffset, yOffset);
252
253 return finalRect;
254 }
255
256 void RenderReplaced::computeIntrinsicRatioInformation(FloatSize& intrinsicSize, double& intrinsicRatio) const
257 {
258 // If there's an embeddedContentBox() of a remote, referenced document avail able, this code-path should never be used.
259 ASSERT(!embeddedContentBox());
260 intrinsicSize = FloatSize(intrinsicLogicalWidth().toFloat(), intrinsicLogica lHeight().toFloat());
261
262 // Figure out if we need to compute an intrinsic ratio.
263 if (intrinsicSize.isEmpty() || !rendererHasAspectRatio(this))
264 return;
265
266 intrinsicRatio = intrinsicSize.width() / intrinsicSize.height();
267 }
268
269 LayoutUnit RenderReplaced::computeReplacedLogicalWidth(ShouldComputePreferred sh ouldComputePreferred) const
270 {
271 if (style()->logicalWidth().isSpecified() || style()->logicalWidth().isIntri nsic())
272 return computeReplacedLogicalWidthRespectingMinMaxWidth(computeReplacedL ogicalWidthUsing(style()->logicalWidth()), shouldComputePreferred);
273
274 RenderBox* contentRenderer = embeddedContentBox();
275
276 // 10.3.2 Inline, replaced elements: http://www.w3.org/TR/CSS21/visudet.html #inline-replaced-width
277 double intrinsicRatio = 0;
278 FloatSize constrainedSize;
279 computeAspectRatioInformationForRenderBox(contentRenderer, constrainedSize, intrinsicRatio);
280
281 if (style()->logicalWidth().isAuto()) {
282 bool computedHeightIsAuto = hasAutoHeightOrContainingBlockWithAutoHeight ();
283 bool hasIntrinsicWidth = constrainedSize.width() > 0;
284
285 // If 'height' and 'width' both have computed values of 'auto' and the e lement also has an intrinsic width, then that intrinsic width is the used value of 'width'.
286 if (computedHeightIsAuto && hasIntrinsicWidth)
287 return computeReplacedLogicalWidthRespectingMinMaxWidth(constrainedS ize.width(), shouldComputePreferred);
288
289 bool hasIntrinsicHeight = constrainedSize.height() > 0;
290 if (intrinsicRatio) {
291 // If 'height' and 'width' both have computed values of 'auto' and t he element has no intrinsic width, but does have an intrinsic height and intrins ic ratio;
292 // or if 'width' has a computed value of 'auto', 'height' has some o ther computed value, and the element does have an intrinsic ratio; then the used value
293 // of 'width' is: (used height) * (intrinsic ratio)
294 if (intrinsicRatio && ((computedHeightIsAuto && !hasIntrinsicWidth & & hasIntrinsicHeight) || !computedHeightIsAuto)) {
295 LayoutUnit logicalHeight = computeReplacedLogicalHeight();
296 return computeReplacedLogicalWidthRespectingMinMaxWidth(roundToI nt(round(logicalHeight * intrinsicRatio)), shouldComputePreferred);
297 }
298
299 // If 'height' and 'width' both have computed values of 'auto' and t he element has an intrinsic ratio but no intrinsic height or width, then the use d value of
300 // 'width' is undefined in CSS 2.1. However, it is suggested that, i f the containing block's width does not itself depend on the replaced element's width, then
301 // the used value of 'width' is calculated from the constraint equat ion used for block-level, non-replaced elements in normal flow.
302 if (computedHeightIsAuto && !hasIntrinsicWidth && !hasIntrinsicHeigh t) {
303 if (shouldComputePreferred == ComputePreferred)
304 return 0;
305 // The aforementioned 'constraint equation' used for block-level , non-replaced elements in normal flow:
306 // 'margin-left' + 'border-left-width' + 'padding-left' + 'width ' + 'padding-right' + 'border-right-width' + 'margin-right' = width of containin g block
307 LayoutUnit logicalWidth = containingBlock()->availableLogicalWid th();
308
309 // This solves above equation for 'width' (== logicalWidth).
310 LayoutUnit marginStart = minimumValueForLength(style()->marginSt art(), logicalWidth);
311 LayoutUnit marginEnd = minimumValueForLength(style()->marginEnd( ), logicalWidth);
312 logicalWidth = std::max<LayoutUnit>(0, logicalWidth - (marginSta rt + marginEnd + (size().width() - clientWidth())));
313 return computeReplacedLogicalWidthRespectingMinMaxWidth(logicalW idth, shouldComputePreferred);
314 }
315 }
316
317 // Otherwise, if 'width' has a computed value of 'auto', and the element has an intrinsic width, then that intrinsic width is the used value of 'width'.
318 if (hasIntrinsicWidth)
319 return computeReplacedLogicalWidthRespectingMinMaxWidth(constrainedS ize.width(), shouldComputePreferred);
320
321 // Otherwise, if 'width' has a computed value of 'auto', but none of the conditions above are met, then the used value of 'width' becomes 300px. If 300p x is too
322 // wide to fit the device, UAs should use the width of the largest recta ngle that has a 2:1 ratio and fits the device instead.
323 // Note: We fall through and instead return intrinsicLogicalWidth() here - to preserve existing WebKit behavior, which might or might not be correct, or desired.
324 // Changing this to return cDefaultWidth, will affect lots of test resul ts. Eg. some tests assume that a blank <img> tag (which implies width/height=aut o)
325 // has no intrinsic size, which is wrong per CSS 2.1, but matches our be havior since a long time.
326 }
327
328 return computeReplacedLogicalWidthRespectingMinMaxWidth(intrinsicLogicalWidt h(), shouldComputePreferred);
329 }
330
331 LayoutUnit RenderReplaced::computeReplacedLogicalHeight() const
332 {
333 // 10.5 Content height: the 'height' property: http://www.w3.org/TR/CSS21/vi sudet.html#propdef-height
334 if (hasReplacedLogicalHeight())
335 return computeReplacedLogicalHeightRespectingMinMaxHeight(computeReplace dLogicalHeightUsing(style()->logicalHeight()));
336
337 RenderBox* contentRenderer = embeddedContentBox();
338
339 // 10.6.2 Inline, replaced elements: http://www.w3.org/TR/CSS21/visudet.html #inline-replaced-height
340 double intrinsicRatio = 0;
341 FloatSize constrainedSize;
342 computeAspectRatioInformationForRenderBox(contentRenderer, constrainedSize, intrinsicRatio);
343
344 bool widthIsAuto = style()->logicalWidth().isAuto();
345 bool hasIntrinsicHeight = constrainedSize.height() > 0;
346
347 // If 'height' and 'width' both have computed values of 'auto' and the eleme nt also has an intrinsic height, then that intrinsic height is the used value of 'height'.
348 if (widthIsAuto && hasIntrinsicHeight)
349 return computeReplacedLogicalHeightRespectingMinMaxHeight(constrainedSiz e.height());
350
351 // Otherwise, if 'height' has a computed value of 'auto', and the element ha s an intrinsic ratio then the used value of 'height' is:
352 // (used width) / (intrinsic ratio)
353 if (intrinsicRatio)
354 return computeReplacedLogicalHeightRespectingMinMaxHeight(roundToInt(rou nd(availableLogicalWidth() / intrinsicRatio)));
355
356 // Otherwise, if 'height' has a computed value of 'auto', and the element ha s an intrinsic height, then that intrinsic height is the used value of 'height'.
357 if (hasIntrinsicHeight)
358 return computeReplacedLogicalHeightRespectingMinMaxHeight(constrainedSiz e.height());
359
360 // Otherwise, if 'height' has a computed value of 'auto', but none of the co nditions above are met, then the used value of 'height' must be set to the heigh t
361 // of the largest rectangle that has a 2:1 ratio, has a height not greater t han 150px, and has a width not greater than the device width.
362 return computeReplacedLogicalHeightRespectingMinMaxHeight(intrinsicLogicalHe ight());
363 }
364
365 void RenderReplaced::computeIntrinsicLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth) const
366 {
367 minLogicalWidth = maxLogicalWidth = intrinsicLogicalWidth();
368 }
369
370 void RenderReplaced::computePreferredLogicalWidths()
371 {
372 ASSERT(preferredLogicalWidthsDirty());
373
374 // We cannot resolve any percent logical width here as the available logical
375 // width may not be set on our containing block.
376 if (style()->logicalWidth().isPercent())
377 computeIntrinsicLogicalWidths(m_minPreferredLogicalWidth, m_maxPreferred LogicalWidth);
378 else
379 m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth = computeReplace dLogicalWidth(ComputePreferred);
380
381 const LayoutStyle& styleToUse = styleRef();
382 if (styleToUse.logicalWidth().isPercent() || styleToUse.logicalMaxWidth().is Percent())
383 m_minPreferredLogicalWidth = 0;
384
385 if (styleToUse.logicalMinWidth().isFixed() && styleToUse.logicalMinWidth().v alue() > 0) {
386 m_maxPreferredLogicalWidth = std::max(m_maxPreferredLogicalWidth, adjust ContentBoxLogicalWidthForBoxSizing(styleToUse.logicalMinWidth().value()));
387 m_minPreferredLogicalWidth = std::max(m_minPreferredLogicalWidth, adjust ContentBoxLogicalWidthForBoxSizing(styleToUse.logicalMinWidth().value()));
388 }
389
390 if (styleToUse.logicalMaxWidth().isFixed()) {
391 m_maxPreferredLogicalWidth = std::min(m_maxPreferredLogicalWidth, adjust ContentBoxLogicalWidthForBoxSizing(styleToUse.logicalMaxWidth().value()));
392 m_minPreferredLogicalWidth = std::min(m_minPreferredLogicalWidth, adjust ContentBoxLogicalWidthForBoxSizing(styleToUse.logicalMaxWidth().value()));
393 }
394
395 LayoutUnit borderAndPadding = borderAndPaddingLogicalWidth();
396 m_minPreferredLogicalWidth += borderAndPadding;
397 m_maxPreferredLogicalWidth += borderAndPadding;
398
399 clearPreferredLogicalWidthsDirty();
400 }
401
402 PositionWithAffinity RenderReplaced::positionForPoint(const LayoutPoint& point)
403 {
404 // FIXME: This code is buggy if the replaced element is relative positioned.
405 InlineBox* box = inlineBoxWrapper();
406 RootInlineBox* rootBox = box ? &box->root() : 0;
407
408 LayoutUnit top = rootBox ? rootBox->selectionTop() : logicalTop();
409 LayoutUnit bottom = rootBox ? rootBox->selectionBottom() : logicalBottom();
410
411 LayoutUnit blockDirectionPosition = isHorizontalWritingMode() ? point.y() + location().y() : point.x() + location().x();
412 LayoutUnit lineDirectionPosition = isHorizontalWritingMode() ? point.x() + l ocation().x() : point.y() + location().y();
413
414 if (blockDirectionPosition < top)
415 return createPositionWithAffinity(caretMinOffset(), DOWNSTREAM); // coor dinates are above
416
417 if (blockDirectionPosition >= bottom)
418 return createPositionWithAffinity(caretMaxOffset(), DOWNSTREAM); // coor dinates are below
419
420 if (node()) {
421 if (lineDirectionPosition <= logicalLeft() + (logicalWidth() / 2))
422 return createPositionWithAffinity(0, DOWNSTREAM);
423 return createPositionWithAffinity(1, DOWNSTREAM);
424 }
425
426 return RenderBox::positionForPoint(point);
427 }
428
429 LayoutRect RenderReplaced::selectionRectForPaintInvalidation(const LayoutLayerMo delObject* paintInvalidationContainer) const
430 {
431 ASSERT(!needsLayout());
432
433 if (!isSelected())
434 return LayoutRect();
435
436 LayoutRect rect = localSelectionRect();
437 mapRectToPaintInvalidationBacking(paintInvalidationContainer, rect, 0);
438 // FIXME: groupedMapping() leaks the squashing abstraction.
439 if (paintInvalidationContainer->layer()->groupedMapping())
440 Layer::mapRectToPaintBackingCoordinates(paintInvalidationContainer, rect );
441 return rect;
442 }
443
444 LayoutRect RenderReplaced::localSelectionRect(bool checkWhetherSelected) const
445 {
446 if (checkWhetherSelected && !isSelected())
447 return LayoutRect();
448
449 if (!inlineBoxWrapper())
450 // We're a block-level replaced element. Just return our own dimensions .
451 return LayoutRect(LayoutPoint(), size());
452
453 RootInlineBox& root = inlineBoxWrapper()->root();
454 LayoutUnit newLogicalTop = root.block().style()->isFlippedBlocksWritingMode( ) ? inlineBoxWrapper()->logicalBottom() - root.selectionBottom() : root.selectio nTop() - inlineBoxWrapper()->logicalTop();
455 if (root.block().style()->isHorizontalWritingMode())
456 return LayoutRect(0, newLogicalTop, size().width(), root.selectionHeight ());
457 return LayoutRect(newLogicalTop, 0, root.selectionHeight(), size().height()) ;
458 }
459
460 void RenderReplaced::setSelectionState(SelectionState state)
461 {
462 // The selection state for our containing block hierarchy is updated by the base class call.
463 RenderBox::setSelectionState(state);
464
465 if (!inlineBoxWrapper())
466 return;
467
468 // We only include the space below the baseline in our layer's cached paint invalidation rect if the
469 // image is selected. Since the selection state has changed update the rect.
470 if (hasLayer())
471 setPreviousPaintInvalidationRect(boundsRectForPaintInvalidation(containe rForPaintInvalidation()));
472
473 if (canUpdateSelectionOnRootLineBoxes())
474 inlineBoxWrapper()->root().setHasSelectedChildren(isSelected());
475 }
476
477 bool RenderReplaced::isSelected() const
478 {
479 SelectionState s = selectionState();
480 if (s == SelectionNone)
481 return false;
482 if (s == SelectionInside)
483 return true;
484
485 int selectionStart, selectionEnd;
486 selectionStartEnd(selectionStart, selectionEnd);
487 if (s == SelectionStart)
488 return selectionStart == 0;
489
490 int end = node()->hasChildren() ? node()->countChildren() : 1;
491 if (s == SelectionEnd)
492 return selectionEnd == end;
493 if (s == SelectionBoth)
494 return selectionStart == 0 && selectionEnd == end;
495
496 ASSERT(0);
497 return false;
498 }
499 LayoutRect RenderReplaced::clippedOverflowRectForPaintInvalidation(const LayoutL ayerModelObject* paintInvalidationContainer, const PaintInvalidationState* paint InvalidationState) const
500 {
501 if (style()->visibility() != VISIBLE && !enclosingLayer()->hasVisibleContent ())
502 return LayoutRect();
503
504 // The selectionRect can project outside of the overflowRect, so take their union
505 // for paint invalidation to avoid selection painting glitches.
506 LayoutRect r = isSelected() ? localSelectionRect() : visualOverflowRect();
507 mapRectToPaintInvalidationBacking(paintInvalidationContainer, r, paintInvali dationState);
508 return r;
509 }
510
511 }
OLDNEW
« no previous file with comments | « Source/core/rendering/RenderReplaced.h ('k') | Source/core/rendering/svg/RenderSVGRoot.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698