Chromium Code Reviews| 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. |