Index: Source/core/rendering/RenderObject.cpp |
diff --git a/Source/core/rendering/RenderObject.cpp b/Source/core/rendering/RenderObject.cpp |
index d6f6ef8d07cb5d2af2a7100f2890331458520219..e283949bd083d1563e965bf0de1c57241253a273 100644 |
--- a/Source/core/rendering/RenderObject.cpp |
+++ b/Source/core/rendering/RenderObject.cpp |
@@ -838,7 +838,15 @@ RenderObject* RenderObject::clippingContainer() const |
return 0; |
} |
-static bool mustRepaintFillLayers(const RenderObject& renderer, const FillLayer* layer) |
+bool RenderObject::borderImageIsLoadedAndCanBeRendered() const |
esprehn
2014/05/29 22:20:12
canRenderBorderImage()
Xianzhu
2014/05/30 00:47:56
Done.
|
+{ |
+ ASSERT(style()->hasBorder()); |
+ |
+ StyleImage* borderImage = style()->borderImage().image(); |
+ return borderImage && borderImage->canRender(*this, style()->effectiveZoom()) && borderImage->isLoaded(); |
+} |
+ |
+bool RenderObject::mustRepaintFillLayersOnWidthChange(const FillLayer* layer) const |
{ |
// Nobody will use multiple layers without wanting fancy positioning. |
if (layer->next()) |
@@ -846,10 +854,16 @@ static bool mustRepaintFillLayers(const RenderObject& renderer, const FillLayer* |
// Make sure we have a valid image. |
StyleImage* img = layer->image(); |
- if (!img || !img->canRender(renderer, renderer.style()->effectiveZoom())) |
+ if (!img || !img->canRender(*this, style()->effectiveZoom())) |
return false; |
- if (!layer->xPosition().isZero() || !layer->yPosition().isZero()) |
+ if (layer->repeatX() != RepeatFill && layer->repeatX() != NoRepeatFill) |
+ return true; |
+ |
+ if (layer->xPosition().isPercent() && !layer->xPosition().isZero()) |
+ return true; |
+ |
+ if (layer->backgroundXOrigin() != LeftEdge) |
return true; |
EFillSizeType sizeType = layer->sizeType(); |
@@ -858,9 +872,9 @@ static bool mustRepaintFillLayers(const RenderObject& renderer, const FillLayer* |
return true; |
if (sizeType == SizeLength) { |
- if (layer->sizeLength().width().isPercent() || layer->sizeLength().height().isPercent()) |
+ if (layer->sizeLength().width().isPercent() && !layer->sizeLength().width().isZero()) |
return true; |
- if (img->isGeneratedImage() && (layer->sizeLength().width().isAuto() || layer->sizeLength().height().isAuto())) |
+ if (img->isGeneratedImage() && layer->sizeLength().width().isAuto()) |
return true; |
} else if (img->usesImageContainerSize()) { |
return true; |
@@ -869,24 +883,72 @@ static bool mustRepaintFillLayers(const RenderObject& renderer, const FillLayer* |
return false; |
} |
-bool RenderObject::borderImageIsLoadedAndCanBeRendered() const |
+bool RenderObject::mustRepaintFillLayersOnHeightChange(const FillLayer* layer) const |
{ |
- ASSERT(style()->hasBorder()); |
+ // Nobody will use multiple layers without wanting fancy positioning. |
+ if (layer->next()) |
+ return true; |
- StyleImage* borderImage = style()->borderImage().image(); |
- return borderImage && borderImage->canRender(*this, style()->effectiveZoom()) && borderImage->isLoaded(); |
+ // Make sure we have a valid image. |
+ StyleImage* img = layer->image(); |
+ if (!img || !img->canRender(*this, style()->effectiveZoom())) |
+ return false; |
+ |
+ if (layer->repeatY() != RepeatFill && layer->repeatY() != NoRepeatFill) |
+ return true; |
+ |
+ if (layer->yPosition().isPercent() && !layer->yPosition().isZero()) |
+ return true; |
+ |
+ if (layer->backgroundYOrigin() != TopEdge) |
+ return true; |
+ |
+ EFillSizeType sizeType = layer->sizeType(); |
+ |
+ if (sizeType == Contain || sizeType == Cover) |
+ return true; |
+ |
+ if (sizeType == SizeLength) { |
+ if (layer->sizeLength().height().isPercent() && !layer->sizeLength().height().isZero()) |
+ return true; |
+ if (img->isGeneratedImage() && layer->sizeLength().height().isAuto()) |
+ return true; |
+ } else if (img->usesImageContainerSize()) { |
+ return true; |
+ } |
+ |
+ return false; |
} |
-bool RenderObject::mustRepaintBackgroundOrBorder() const |
+bool RenderObject::mustRepaintBackgroundOrBorderOnWidthChange() const |
{ |
- if (hasMask() && mustRepaintFillLayers(*this, style()->maskLayers())) |
+ if (hasMask() && mustRepaintFillLayersOnWidthChange(style()->maskLayers())) |
return true; |
// If we don't have a background/border/mask, then nothing to do. |
if (!hasBoxDecorations()) |
return false; |
- if (mustRepaintFillLayers(*this, style()->backgroundLayers())) |
+ if (mustRepaintFillLayersOnWidthChange(style()->backgroundLayers())) |
+ return true; |
+ |
+ // Our fill layers are ok. Let's check border. |
+ if (style()->hasBorder() && borderImageIsLoadedAndCanBeRendered()) |
+ return true; |
+ |
+ return false; |
+} |
+ |
+bool RenderObject::mustRepaintBackgroundOrBorderOnHeightChange() const |
+{ |
+ if (hasMask() && mustRepaintFillLayersOnHeightChange(style()->maskLayers())) |
+ return true; |
+ |
+ // If we don't have a background/border/mask, then nothing to do. |
+ if (!hasBoxDecorations()) |
+ return false; |
+ |
+ if (mustRepaintFillLayersOnHeightChange(style()->backgroundLayers())) |
return true; |
// Our fill layers are ok. Let's check border. |
@@ -1601,8 +1663,12 @@ bool RenderObject::repaintAfterLayoutIfNeeded(const RenderLayerModelObject* repa |
if (invalidationReason == InvalidationIncremental && oldBounds == newBounds) |
return false; |
- if (invalidationReason == InvalidationIncremental && mustRepaintBackgroundOrBorder()) |
- invalidationReason = InvalidationBoundsChangeWithBackground; |
+ if (invalidationReason == InvalidationIncremental) { |
+ if (oldBounds.width() != newBounds.width() && mustRepaintBackgroundOrBorderOnWidthChange()) |
+ invalidationReason = InvalidationBoundsChangeWithBackground; |
+ else if (oldBounds.height() != newBounds.height() && mustRepaintBackgroundOrBorderOnHeightChange()) |
+ invalidationReason = InvalidationBoundsChangeWithBackground; |
+ } |
// If we shifted, we don't know the exact reason so we are conservative and trigger a full invalidation. Shifting could |
// be caused by some layout property (left / top) or some in-flow renderer inserted / removed before us in the tree. |