Changeset 91628 in webkit
- Timestamp:
- Jul 22, 2011 5:39:54 PM (13 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r91626 r91628 1 2011-07-22 Simon Fraser <simon.fraser@apple.com> 2 3 Avoiding painting backgrounds if they are fully obscures by an object's foreground 4 https://bugs.webkit.org/show_bug.cgi?id=65030 5 6 Reviewed by Dan Bernstein. 7 8 Some pages use animated loading GIFs as the background of <img>, 9 but WebKit keeps animating these after the <img> has loaded. 10 11 Thwart this by avoiding the painting of such backgrounds, if we can 12 determine that they are completely obscured by the border and content 13 of the element. 14 15 * platform/graphics/BitmapImage.h: 16 (WebCore::BitmapImage::currentFrameHasAlpha): Utility method, since currentFrame() 17 is protected. 18 * rendering/RenderBox.cpp: 19 (WebCore::RenderBox::paintBoxDecorations): Call paintBackground(). 20 (WebCore::RenderBox::paintBackground): New wrapper for the paintFillLayers() which 21 paints the background layers, plus some code we call in a couple of places. This 22 checks the new backgroundIsObscured() method before doing any painting. 23 * rendering/RenderBox.h: 24 (WebCore::RenderBox::backgroundIsObscured): New virtual method that determines 25 whether any of the background is visible. 26 * rendering/RenderBoxModelObject.h: 27 * rendering/RenderBoxModelObject.cpp: 28 (WebCore::BorderEdge::obscuresBackground): Returns true if this edge will 29 entirely hide the background under it. 30 (WebCore::RenderBoxModelObject::borderObscuresBackground): Determine whether 31 the border hides the background. 32 * rendering/RenderImage.cpp: 33 (WebCore::RenderImage::backgroundIsObscured): Override the RenderBox method 34 and return true if the image is a loaded, opaque bitmap image, and the background 35 won't show in the border or padding areas. 36 * rendering/RenderImage.h: 37 * rendering/RenderTable.cpp: 38 (WebCore::RenderTable::paintBoxDecorations): Use paintBackground(). 39 1 40 2011-07-22 Kenneth Russell <kbr@google.com> 2 41 -
trunk/Source/WebCore/platform/graphics/BitmapImage.h
r85697 r91628 159 159 160 160 virtual NativeImagePtr nativeImageForCurrentFrame() { return frameAtIndex(currentFrame()); } 161 bool frameHasAlphaAtIndex(size_t); 161 bool frameHasAlphaAtIndex(size_t); 162 bool currentFrameHasAlpha() { return frameHasAlphaAtIndex(currentFrame()); } 162 163 163 164 #if !ASSERT_DISABLED -
trunk/Source/WebCore/rendering/RenderBox.cpp
r91533 r91628 863 863 bool themePainted = style()->hasAppearance() && !theme()->paint(this, paintInfo, paintRect); 864 864 if (!themePainted) { 865 if (isRoot()) 866 paintRootBoxFillLayers(paintInfo); 867 else if (!isBody() || document()->documentElement()->renderer()->hasBackground()) { 868 // The <body> only paints its background if the root element has defined a background 869 // independent of the body. 870 paintFillLayers(paintInfo, style()->visitedDependentColor(CSSPropertyBackgroundColor), style()->backgroundLayers(), paintRect, bleedAvoidance); 871 } 865 paintBackground(paintInfo, paintRect, bleedAvoidance); 866 872 867 if (style()->hasAppearance()) 873 868 theme()->paintDecorations(this, paintInfo, paintRect); … … 881 876 if (bleedAvoidance == BackgroundBleedUseTransparencyLayer) 882 877 paintInfo.context->endTransparencyLayer(); 878 } 879 880 void RenderBox::paintBackground(const PaintInfo& paintInfo, const LayoutRect& paintRect, BackgroundBleedAvoidance bleedAvoidance) 881 { 882 if (isRoot()) 883 paintRootBoxFillLayers(paintInfo); 884 else if (!isBody() || document()->documentElement()->renderer()->hasBackground()) { 885 // The <body> only paints its background if the root element has defined a background 886 // independent of the body. 887 if (!backgroundIsObscured()) 888 paintFillLayers(paintInfo, style()->visitedDependentColor(CSSPropertyBackgroundColor), style()->backgroundLayers(), paintRect, bleedAvoidance); 889 } 883 890 } 884 891 -
trunk/Source/WebCore/rendering/RenderBox.h
r91386 r91628 418 418 virtual void updateBoxModelInfoFromStyle(); 419 419 420 virtual bool backgroundIsObscured() const { return false; } 421 void paintBackground(const PaintInfo&, const LayoutRect&, BackgroundBleedAvoidance = BackgroundBleedNone); 422 420 423 void paintFillLayer(const PaintInfo&, const Color&, const FillLayer*, const LayoutRect&, BackgroundBleedAvoidance, CompositeOperator, RenderObject* backgroundObject); 421 424 void paintFillLayers(const PaintInfo&, const Color&, const FillLayer*, const LayoutRect&, BackgroundBleedAvoidance = BackgroundBleedNone, CompositeOperator = CompositeSourceOver, RenderObject* backgroundObject = 0); -
trunk/Source/WebCore/rendering/RenderBoxModelObject.cpp
r91190 r91628 1096 1096 return true; 1097 1097 } 1098 bool obscuresBackground() const 1099 { 1100 if (!isPresent || isTransparent || color.hasAlpha() || style == BHIDDEN) 1101 return false; 1102 1103 if (style == DOTTED || style == DASHED || style == DOUBLE) 1104 return false; 1105 1106 return true; 1107 } 1098 1108 1099 1109 int usedWidth() const { return isPresent ? width : 0; } … … 2146 2156 } 2147 2157 2158 bool RenderBoxModelObject::borderObscuresBackground() const 2159 { 2160 if (!style()->hasBorder()) 2161 return false; 2162 2163 // Bail if we have any border-image for now. We could look at the image alpha to improve this. 2164 if (style()->borderImage().image()) 2165 return false; 2166 2167 BorderEdge edges[4]; 2168 getBorderEdgeInfo(edges); 2169 2170 for (int i = BSTop; i <= BSLeft; ++i) { 2171 const BorderEdge& currEdge = edges[i]; 2172 if (!currEdge.obscuresBackground()) 2173 return false; 2174 } 2175 2176 return true; 2177 } 2178 2148 2179 static inline IntRect areaCastingShadowInHole(const IntRect& holeRect, int shadowBlur, int shadowSpread, const IntSize& shadowOffset) 2149 2180 { -
trunk/Source/WebCore/rendering/RenderBoxModelObject.h
r91090 r91628 184 184 void getBorderEdgeInfo(class BorderEdge[], bool includeLogicalLeftEdge = true, bool includeLogicalRightEdge = true) const; 185 185 bool borderObscuresBackgroundEdge(const FloatSize& contextScale) const; 186 bool borderObscuresBackground() const; 186 187 187 188 bool shouldPaintAtLowQuality(GraphicsContext*, Image*, const void*, const IntSize&); -
trunk/Source/WebCore/rendering/RenderImage.cpp
r90900 r91628 28 28 #include "RenderImage.h" 29 29 30 #include "BitmapImage.h" 30 31 #include "FontCache.h" 31 32 #include "Frame.h" … … 388 389 } 389 390 391 bool RenderImage::backgroundIsObscured() const 392 { 393 if (!m_imageResource->hasImage() || m_imageResource->errorOccurred()) 394 return false; 395 396 if (m_imageResource->cachedImage() && !m_imageResource->cachedImage()->isLoaded()) 397 return false; 398 399 EFillBox backgroundClip = style()->backgroundClip(); 400 401 // Background paints under borders. 402 if (backgroundClip == BorderFillBox && style()->hasBorder() && !borderObscuresBackground()) 403 return false; 404 405 // Background shows in padding area. 406 if ((backgroundClip == BorderFillBox || backgroundClip == PaddingFillBox) && style()->hasPadding()) 407 return false; 408 409 // Check for bitmap image with alpha. 410 Image* image = m_imageResource->image().get(); 411 if (!image || !image->isBitmapImage()) 412 return false; 413 414 BitmapImage* bitmapImage = static_cast<BitmapImage*>(image); 415 if (bitmapImage->currentFrameHasAlpha()) 416 return false; 417 418 return true; 419 } 420 390 421 int RenderImage::minimumReplacedHeight() const 391 422 { -
trunk/Source/WebCore/rendering/RenderImage.h
r90900 r91628 79 79 virtual void paintReplaced(PaintInfo&, const IntPoint&); 80 80 81 virtual bool backgroundIsObscured() const; 82 81 83 virtual int minimumReplacedHeight() const; 82 84 -
trunk/Source/WebCore/rendering/RenderTable.cpp
r91417 r91628 559 559 560 560 paintBoxShadow(paintInfo.context, rect, style(), Normal); 561 562 if (isRoot()) 563 paintRootBoxFillLayers(paintInfo); 564 else if (!isBody() || document()->documentElement()->renderer()->hasBackground()) 565 // The <body> only paints its background if the root element has defined a background 566 // independent of the body. 567 paintFillLayers(paintInfo, style()->visitedDependentColor(CSSPropertyBackgroundColor), style()->backgroundLayers(), rect); 568 561 paintBackground(paintInfo, rect); 569 562 paintBoxShadow(paintInfo.context, rect, style(), Inset); 570 563
Note: See TracChangeset
for help on using the changeset viewer.