OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2004, 2005, 2007 Nikolas Zimmermann <zimmermann@kde.org> | 2 * Copyright (C) 2004, 2005, 2007 Nikolas Zimmermann <zimmermann@kde.org> |
3 * Copyright (C) 2004, 2005, 2007, 2008, 2009 Rob Buis <buis@kde.org> | 3 * Copyright (C) 2004, 2005, 2007, 2008, 2009 Rob Buis <buis@kde.org> |
4 * Copyright (C) 2007 Eric Seidel <eric@webkit.org> | 4 * Copyright (C) 2007 Eric Seidel <eric@webkit.org> |
5 * Copyright (C) 2009 Google, Inc. | 5 * Copyright (C) 2009 Google, Inc. |
6 * Copyright (C) Research In Motion Limited 2011. All rights reserved. | 6 * Copyright (C) Research In Motion Limited 2011. 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 11 matching lines...) Expand all Loading... |
22 */ | 22 */ |
23 | 23 |
24 #include "config.h" | 24 #include "config.h" |
25 | 25 |
26 #include "core/rendering/svg/RenderSVGRoot.h" | 26 #include "core/rendering/svg/RenderSVGRoot.h" |
27 | 27 |
28 #include "core/frame/LocalFrame.h" | 28 #include "core/frame/LocalFrame.h" |
29 #include "core/rendering/HitTestResult.h" | 29 #include "core/rendering/HitTestResult.h" |
30 #include "core/rendering/LayoutRectRecorder.h" | 30 #include "core/rendering/LayoutRectRecorder.h" |
31 #include "core/rendering/LayoutRepainter.h" | 31 #include "core/rendering/LayoutRepainter.h" |
| 32 #include "core/rendering/RenderLayer.h" |
32 #include "core/rendering/RenderPart.h" | 33 #include "core/rendering/RenderPart.h" |
33 #include "core/rendering/RenderView.h" | 34 #include "core/rendering/RenderView.h" |
34 #include "core/rendering/svg/RenderSVGResourceContainer.h" | 35 #include "core/rendering/svg/RenderSVGResourceContainer.h" |
35 #include "core/rendering/svg/SVGRenderingContext.h" | 36 #include "core/rendering/svg/SVGRenderingContext.h" |
36 #include "core/rendering/svg/SVGResources.h" | 37 #include "core/rendering/svg/SVGResources.h" |
37 #include "core/rendering/svg/SVGResourcesCache.h" | 38 #include "core/rendering/svg/SVGResourcesCache.h" |
38 #include "core/svg/SVGElement.h" | 39 #include "core/svg/SVGElement.h" |
39 #include "core/svg/SVGSVGElement.h" | 40 #include "core/svg/SVGSVGElement.h" |
40 #include "core/svg/graphics/SVGImage.h" | 41 #include "core/svg/graphics/SVGImage.h" |
41 #include "platform/LengthFunctions.h" | 42 #include "platform/LengthFunctions.h" |
42 #include "platform/graphics/GraphicsContext.h" | 43 #include "platform/graphics/GraphicsContext.h" |
43 | 44 |
44 using namespace std; | 45 using namespace std; |
45 | 46 |
46 namespace WebCore { | 47 namespace WebCore { |
47 | 48 |
48 RenderSVGRoot::RenderSVGRoot(SVGElement* node) | 49 RenderSVGRoot::RenderSVGRoot(SVGElement* node) |
49 : RenderReplaced(node) | 50 : RenderReplaced(node) |
50 , m_objectBoundingBoxValid(false) | 51 , m_objectBoundingBoxValid(false) |
51 , m_isLayoutSizeChanged(false) | 52 , m_isLayoutSizeChanged(false) |
52 , m_needsBoundariesOrTransformUpdate(true) | 53 , m_needsBoundariesOrTransformUpdate(true) |
| 54 , m_hasBoxDecorations(false) |
53 { | 55 { |
54 } | 56 } |
55 | 57 |
56 RenderSVGRoot::~RenderSVGRoot() | 58 RenderSVGRoot::~RenderSVGRoot() |
57 { | 59 { |
58 } | 60 } |
59 | 61 |
60 void RenderSVGRoot::computeIntrinsicRatioInformation(FloatSize& intrinsicSize, d
ouble& intrinsicRatio, bool& isPercentageIntrinsicSize) const | 62 void RenderSVGRoot::computeIntrinsicRatioInformation(FloatSize& intrinsicSize, d
ouble& intrinsicRatio, bool& isPercentageIntrinsicSize) const |
61 { | 63 { |
62 // Spec: http://www.w3.org/TR/SVG/coords.html#IntrinsicSizing | 64 // Spec: http://www.w3.org/TR/SVG/coords.html#IntrinsicSizing |
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
214 m_isLayoutSizeChanged = needsLayout || (svg->hasRelativeLengths() && oldSize
!= size()); | 216 m_isLayoutSizeChanged = needsLayout || (svg->hasRelativeLengths() && oldSize
!= size()); |
215 SVGRenderSupport::layoutChildren(this, needsLayout || SVGRenderSupport::filt
ersForceContainerLayout(this)); | 217 SVGRenderSupport::layoutChildren(this, needsLayout || SVGRenderSupport::filt
ersForceContainerLayout(this)); |
216 | 218 |
217 // At this point LayoutRepainter already grabbed the old bounds, | 219 // At this point LayoutRepainter already grabbed the old bounds, |
218 // recalculate them now so repaintAfterLayout() uses the new bounds. | 220 // recalculate them now so repaintAfterLayout() uses the new bounds. |
219 if (m_needsBoundariesOrTransformUpdate) { | 221 if (m_needsBoundariesOrTransformUpdate) { |
220 updateCachedBoundaries(); | 222 updateCachedBoundaries(); |
221 m_needsBoundariesOrTransformUpdate = false; | 223 m_needsBoundariesOrTransformUpdate = false; |
222 } | 224 } |
223 | 225 |
| 226 m_overflow.clear(); |
| 227 addVisualEffectOverflow(); |
224 updateLayerTransform(); | 228 updateLayerTransform(); |
| 229 m_hasBoxDecorations = isRoot() ? calculateHasBoxDecorations() : hasBoxDecora
tions(); |
| 230 invalidateBackgroundObscurationStatus(); |
225 | 231 |
226 repainter.repaintAfterLayout(); | 232 repainter.repaintAfterLayout(); |
227 | |
228 clearNeedsLayout(); | 233 clearNeedsLayout(); |
229 } | 234 } |
230 | 235 |
231 void RenderSVGRoot::paintReplaced(PaintInfo& paintInfo, const LayoutPoint& paint
Offset) | 236 void RenderSVGRoot::paintReplaced(PaintInfo& paintInfo, const LayoutPoint& paint
Offset) |
232 { | 237 { |
233 // An empty viewport disables rendering. | 238 // An empty viewport disables rendering. |
234 if (pixelSnappedBorderBoxRect().isEmpty()) | 239 if (pixelSnappedBorderBoxRect().isEmpty()) |
235 return; | 240 return; |
236 | 241 |
237 // Don't paint, if the context explicitly disabled it. | 242 // Don't paint, if the context explicitly disabled it. |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
286 RenderBlock::removePercentHeightDescendant(const_cast<RenderSVGRoot*>(this))
; | 291 RenderBlock::removePercentHeightDescendant(const_cast<RenderSVGRoot*>(this))
; |
287 | 292 |
288 SVGResourcesCache::clientDestroyed(this); | 293 SVGResourcesCache::clientDestroyed(this); |
289 RenderReplaced::willBeDestroyed(); | 294 RenderReplaced::willBeDestroyed(); |
290 } | 295 } |
291 | 296 |
292 void RenderSVGRoot::styleDidChange(StyleDifference diff, const RenderStyle* oldS
tyle) | 297 void RenderSVGRoot::styleDidChange(StyleDifference diff, const RenderStyle* oldS
tyle) |
293 { | 298 { |
294 if (diff == StyleDifferenceLayout) | 299 if (diff == StyleDifferenceLayout) |
295 setNeedsBoundariesUpdate(); | 300 setNeedsBoundariesUpdate(); |
| 301 if (diff == StyleDifferenceRepaint) { |
| 302 // Box decorations may have appeared/disappeared - recompute status. |
| 303 m_hasBoxDecorations = calculateHasBoxDecorations(); |
| 304 } |
296 | 305 |
297 RenderReplaced::styleDidChange(diff, oldStyle); | 306 RenderReplaced::styleDidChange(diff, oldStyle); |
298 SVGResourcesCache::clientStyleChanged(this, diff, style()); | 307 SVGResourcesCache::clientStyleChanged(this, diff, style()); |
299 } | 308 } |
300 | 309 |
301 bool RenderSVGRoot::isChildAllowed(RenderObject* child, RenderStyle*) const | 310 bool RenderSVGRoot::isChildAllowed(RenderObject* child, RenderStyle*) const |
302 { | 311 { |
303 return child->isSVG() && !(child->isSVGInline() || child->isSVGInlineText())
; | 312 return child->isSVG() && !(child->isSVGInline() || child->isSVGInlineText())
; |
304 } | 313 } |
305 | 314 |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
348 m_localToParentTransform = m_localToBorderBoxTransform; | 357 m_localToParentTransform = m_localToBorderBoxTransform; |
349 if (x()) | 358 if (x()) |
350 m_localToParentTransform.setE(m_localToParentTransform.e() + roundToInt(
x())); | 359 m_localToParentTransform.setE(m_localToParentTransform.e() + roundToInt(
x())); |
351 if (y()) | 360 if (y()) |
352 m_localToParentTransform.setF(m_localToParentTransform.f() + roundToInt(
y())); | 361 m_localToParentTransform.setF(m_localToParentTransform.f() + roundToInt(
y())); |
353 return m_localToParentTransform; | 362 return m_localToParentTransform; |
354 } | 363 } |
355 | 364 |
356 LayoutRect RenderSVGRoot::clippedOverflowRectForRepaint(const RenderLayerModelOb
ject* repaintContainer) const | 365 LayoutRect RenderSVGRoot::clippedOverflowRectForRepaint(const RenderLayerModelOb
ject* repaintContainer) const |
357 { | 366 { |
358 return SVGRenderSupport::clippedOverflowRectForRepaint(this, repaintContaine
r); | 367 // This is an open-coded aggregate of SVGRenderSupport::clippedOverflowRectF
orRepaint, |
| 368 // RenderSVGRoot::computeFloatRectForRepaint and RenderReplaced::clippedOver
flowRectForRepaint. |
| 369 // The reason for this is to optimize/minimize the repaint rect when the box
is not "decorated" |
| 370 // (does not have background/border/etc.) |
| 371 |
| 372 // Return early for any cases where we don't actually paint. |
| 373 if (style()->visibility() != VISIBLE && !enclosingLayer()->hasVisibleContent
()) |
| 374 return LayoutRect(); |
| 375 |
| 376 // Compute the repaint rect of the content of the SVG in the border-box coor
dinate space. |
| 377 FloatRect contentRepaintRect = repaintRectInLocalCoordinates(); |
| 378 contentRepaintRect = m_localToBorderBoxTransform.mapRect(contentRepaintRect)
; |
| 379 |
| 380 // Apply initial viewport clip - not affected by overflow settings |
| 381 contentRepaintRect.intersect(pixelSnappedBorderBoxRect()); |
| 382 |
| 383 LayoutRect repaintRect = enclosingLayoutRect(contentRepaintRect); |
| 384 // If the box is decorated or is overflowing, extend it to include the borde
r-box and overflow. |
| 385 if (m_hasBoxDecorations || hasRenderOverflow()) { |
| 386 // The selectionRect can project outside of the overflowRect, so take th
eir union |
| 387 // for repainting to avoid selection painting glitches. |
| 388 LayoutRect decoratedRepaintRect = unionRect(localSelectionRect(false), v
isualOverflowRect()); |
| 389 repaintRect.unite(decoratedRepaintRect); |
| 390 } |
| 391 |
| 392 // Compute the repaint rect in the parent coordinate space. |
| 393 LayoutRect rect = enclosingIntRect(repaintRect); |
| 394 RenderReplaced::computeRectForRepaint(repaintContainer, rect); |
| 395 return rect; |
359 } | 396 } |
360 | 397 |
361 void RenderSVGRoot::computeFloatRectForRepaint(const RenderLayerModelObject* rep
aintContainer, FloatRect& repaintRect, bool fixed) const | 398 void RenderSVGRoot::computeFloatRectForRepaint(const RenderLayerModelObject* rep
aintContainer, FloatRect& repaintRect, bool fixed) const |
362 { | 399 { |
363 // Apply our local transforms (except for x/y translation), then our shadow, | 400 // Apply our local transforms (except for x/y translation), then our shadow, |
364 // and then call RenderBox's method to handle all the normal CSS Box model b
its | 401 // and then call RenderBox's method to handle all the normal CSS Box model b
its |
365 repaintRect = m_localToBorderBoxTransform.mapRect(repaintRect); | 402 repaintRect = m_localToBorderBoxTransform.mapRect(repaintRect); |
366 | 403 |
367 // Apply initial viewport clip - not affected by overflow settings | 404 // Apply initial viewport clip - not affected by overflow settings |
368 repaintRect.intersect(pixelSnappedBorderBoxRect()); | 405 repaintRect.intersect(pixelSnappedBorderBoxRect()); |
(...skipping 16 matching lines...) Expand all Loading... |
385 | 422 |
386 const RenderObject* RenderSVGRoot::pushMappingToContainer(const RenderLayerModel
Object* ancestorToStopAt, RenderGeometryMap& geometryMap) const | 423 const RenderObject* RenderSVGRoot::pushMappingToContainer(const RenderLayerModel
Object* ancestorToStopAt, RenderGeometryMap& geometryMap) const |
387 { | 424 { |
388 return RenderReplaced::pushMappingToContainer(ancestorToStopAt, geometryMap)
; | 425 return RenderReplaced::pushMappingToContainer(ancestorToStopAt, geometryMap)
; |
389 } | 426 } |
390 | 427 |
391 void RenderSVGRoot::updateCachedBoundaries() | 428 void RenderSVGRoot::updateCachedBoundaries() |
392 { | 429 { |
393 SVGRenderSupport::computeContainerBoundingBoxes(this, m_objectBoundingBox, m
_objectBoundingBoxValid, m_strokeBoundingBox, m_repaintBoundingBox); | 430 SVGRenderSupport::computeContainerBoundingBoxes(this, m_objectBoundingBox, m
_objectBoundingBoxValid, m_strokeBoundingBox, m_repaintBoundingBox); |
394 SVGRenderSupport::intersectRepaintRectWithResources(this, m_repaintBoundingB
ox); | 431 SVGRenderSupport::intersectRepaintRectWithResources(this, m_repaintBoundingB
ox); |
395 m_repaintBoundingBox.inflate(borderAndPaddingWidth().toFloat()); | |
396 } | 432 } |
397 | 433 |
398 bool RenderSVGRoot::nodeAtPoint(const HitTestRequest& request, HitTestResult& re
sult, const HitTestLocation& locationInContainer, const LayoutPoint& accumulated
Offset, HitTestAction hitTestAction) | 434 bool RenderSVGRoot::nodeAtPoint(const HitTestRequest& request, HitTestResult& re
sult, const HitTestLocation& locationInContainer, const LayoutPoint& accumulated
Offset, HitTestAction hitTestAction) |
399 { | 435 { |
400 LayoutPoint pointInParent = locationInContainer.point() - toLayoutSize(accum
ulatedOffset); | 436 LayoutPoint pointInParent = locationInContainer.point() - toLayoutSize(accum
ulatedOffset); |
401 LayoutPoint pointInBorderBox = pointInParent - toLayoutSize(location()); | 437 LayoutPoint pointInBorderBox = pointInParent - toLayoutSize(location()); |
402 | 438 |
403 // Only test SVG content if the point is in our content box. | 439 // Only test SVG content if the point is in our content box. |
404 // FIXME: This should be an intersection when rect-based hit tests are suppo
rted by nodeAtFloatPoint. | 440 // FIXME: This should be an intersection when rect-based hit tests are suppo
rted by nodeAtFloatPoint. |
405 if (contentBoxRect().contains(pointInBorderBox)) { | 441 if (contentBoxRect().contains(pointInBorderBox)) { |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
441 | 477 |
442 bool RenderSVGRoot::hasRelativeLogicalHeight() const | 478 bool RenderSVGRoot::hasRelativeLogicalHeight() const |
443 { | 479 { |
444 SVGSVGElement* svg = toSVGSVGElement(node()); | 480 SVGSVGElement* svg = toSVGSVGElement(node()); |
445 ASSERT(svg); | 481 ASSERT(svg); |
446 | 482 |
447 return svg->intrinsicHeight(SVGSVGElement::IgnoreCSSProperties).isPercent(); | 483 return svg->intrinsicHeight(SVGSVGElement::IgnoreCSSProperties).isPercent(); |
448 } | 484 } |
449 | 485 |
450 } | 486 } |
OLD | NEW |