Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "config.h" | 5 #include "config.h" |
| 6 #include "core/paint/BoxPainter.h" | 6 #include "core/paint/BoxPainter.h" |
| 7 | 7 |
| 8 #include "core/HTMLNames.h" | 8 #include "core/HTMLNames.h" |
| 9 #include "core/frame/Settings.h" | 9 #include "core/frame/Settings.h" |
| 10 #include "core/html/HTMLFrameOwnerElement.h" | 10 #include "core/html/HTMLFrameOwnerElement.h" |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 56 paintBoxDecorationBackgroundWithRect(paintInfo, paintOffset, paintRect); | 56 paintBoxDecorationBackgroundWithRect(paintInfo, paintOffset, paintRect); |
| 57 } | 57 } |
| 58 | 58 |
| 59 LayoutRect BoxPainter::boundsForDrawingRecorder(const LayoutPoint& paintOffset) | 59 LayoutRect BoxPainter::boundsForDrawingRecorder(const LayoutPoint& paintOffset) |
| 60 { | 60 { |
| 61 if (!RuntimeEnabledFeatures::slimmingPaintEnabled()) | 61 if (!RuntimeEnabledFeatures::slimmingPaintEnabled()) |
| 62 return LayoutRect(); | 62 return LayoutRect(); |
| 63 | 63 |
| 64 // The document element is specified to paint its background infinitely. | 64 // The document element is specified to paint its background infinitely. |
| 65 if (m_layoutBox.isDocumentElement()) | 65 if (m_layoutBox.isDocumentElement()) |
| 66 return rootBackgroundRect(); | 66 return rootBackgroundRect(); |
|
trchen
2015/06/02 21:33:36
Correct. I will remove those in the next CL too.
| |
| 67 | 67 |
| 68 // Use the visual overflow rect here, because it will include overflow intro duced by the theme. | 68 // Use the visual overflow rect here, because it will include overflow intro duced by the theme. |
| 69 LayoutRect bounds = m_layoutBox.visualOverflowRect(); | 69 LayoutRect bounds = m_layoutBox.visualOverflowRect(); |
| 70 bounds.moveBy(paintOffset); | 70 bounds.moveBy(paintOffset); |
| 71 return LayoutRect(pixelSnappedIntRect(bounds)); | 71 return LayoutRect(pixelSnappedIntRect(bounds)); |
| 72 } | 72 } |
| 73 | 73 |
| 74 LayoutRect BoxPainter::rootBackgroundRect() | 74 LayoutRect BoxPainter::rootBackgroundRect() |
| 75 { | 75 { |
| 76 LayoutView* layoutView = m_layoutBox.view(); | 76 LayoutView* layoutView = m_layoutBox.view(); |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 142 // The theme will tell us whether or not we should also paint the CSS border . | 142 // The theme will tell us whether or not we should also paint the CSS border . |
| 143 if (boxDecorationData.hasBorder && boxDecorationData.bleedAvoidance != Backg roundBleedBackgroundOverBorder | 143 if (boxDecorationData.hasBorder && boxDecorationData.bleedAvoidance != Backg roundBleedBackgroundOverBorder |
| 144 && (!boxDecorationData.hasAppearance || (!themePainted && LayoutTheme::t heme().painter().paintBorderOnly(&m_layoutBox, paintInfo, snappedPaintRect))) | 144 && (!boxDecorationData.hasAppearance || (!themePainted && LayoutTheme::t heme().painter().paintBorderOnly(&m_layoutBox, paintInfo, snappedPaintRect))) |
| 145 && !(m_layoutBox.isTable() && toLayoutTable(&m_layoutBox)->collapseBorde rs())) | 145 && !(m_layoutBox.isTable() && toLayoutTable(&m_layoutBox)->collapseBorde rs())) |
| 146 paintBorder(m_layoutBox, paintInfo, paintRect, style, boxDecorationData. bleedAvoidance); | 146 paintBorder(m_layoutBox, paintInfo, paintRect, style, boxDecorationData. bleedAvoidance); |
| 147 | 147 |
| 148 if (boxDecorationData.bleedAvoidance == BackgroundBleedClipLayer) | 148 if (boxDecorationData.bleedAvoidance == BackgroundBleedClipLayer) |
| 149 paintInfo.context->endLayer(); | 149 paintInfo.context->endLayer(); |
| 150 } | 150 } |
| 151 | 151 |
| 152 static bool skipBodyBackground(const LayoutBox* bodyElementLayoutObject) | |
| 153 { | |
| 154 ASSERT(bodyElementLayoutObject->isBody()); | |
| 155 // The <body> only paints its background if the root element has defined a b ackground independent of the body, | |
| 156 // or if the <body>'s parent is not the document element's layoutObject (e.g . inside SVG foreignObject). | |
| 157 LayoutObject* documentElementLayoutObject = bodyElementLayoutObject->documen t().documentElement()->layoutObject(); | |
| 158 return documentElementLayoutObject | |
| 159 && !documentElementLayoutObject->hasBackground() | |
| 160 && (documentElementLayoutObject == bodyElementLayoutObject->parent()); | |
| 161 } | |
| 162 | |
| 163 void BoxPainter::paintBackground(const PaintInfo& paintInfo, const LayoutRect& p aintRect, const Color& backgroundColor, BackgroundBleedAvoidance bleedAvoidance) | 152 void BoxPainter::paintBackground(const PaintInfo& paintInfo, const LayoutRect& p aintRect, const Color& backgroundColor, BackgroundBleedAvoidance bleedAvoidance) |
| 164 { | 153 { |
| 165 if (m_layoutBox.isDocumentElement()) { | 154 if (m_layoutBox.isDocumentElement()) |
| 166 paintRootBoxFillLayers(paintInfo); | |
| 167 return; | 155 return; |
| 168 } | 156 if (m_layoutBox.backgroundStolenForBeingBody()) |
| 169 if (m_layoutBox.isBody() && skipBodyBackground(&m_layoutBox)) | |
| 170 return; | 157 return; |
| 171 if (m_layoutBox.boxDecorationBackgroundIsKnownToBeObscured()) | 158 if (m_layoutBox.boxDecorationBackgroundIsKnownToBeObscured()) |
| 172 return; | 159 return; |
| 173 paintFillLayers(paintInfo, backgroundColor, m_layoutBox.style()->backgroundL ayers(), paintRect, bleedAvoidance); | 160 paintFillLayers(paintInfo, backgroundColor, m_layoutBox.style()->backgroundL ayers(), paintRect, bleedAvoidance); |
| 174 } | 161 } |
| 175 | 162 |
| 176 void BoxPainter::paintRootBoxFillLayers(const PaintInfo& paintInfo) | 163 static bool isFillLayerOpaque(const FillLayer& layer, const LayoutObject& imageC lient) |
| 177 { | 164 { |
| 178 if (paintInfo.skipRootBackground()) | 165 return layer.hasOpaqueImage(&imageClient) |
| 179 return; | 166 && layer.image()->canRender(imageClient, imageClient.style()->effectiveZ oom()) |
| 180 | 167 && layer.image()->imageSize(&imageClient, imageClient.style()->effective Zoom()).isEmpty() |
| 181 LayoutObject* rootBackgroundLayoutObject = m_layoutBox.layoutObjectForRootBa ckground(); | 168 && layer.hasRepeatXY(); |
| 182 | |
| 183 const FillLayer& bgLayer = rootBackgroundLayoutObject->style()->backgroundLa yers(); | |
| 184 Color bgColor = rootBackgroundLayoutObject->resolveColor(CSSPropertyBackgrou ndColor); | |
| 185 | |
| 186 paintFillLayers(paintInfo, bgColor, bgLayer, rootBackgroundRect(), Backgroun dBleedNone, SkXfermode::kSrcOver_Mode, rootBackgroundLayoutObject); | |
| 187 } | 169 } |
| 188 | 170 |
| 189 void BoxPainter::paintFillLayers(const PaintInfo& paintInfo, const Color& c, con st FillLayer& fillLayer, const LayoutRect& rect, | 171 bool BoxPainter::calculateFillLayerOcclusionCulling(Vector<const FillLayer*, 8> &reversedPaintList, const FillLayer& fillLayer) |
| 190 BackgroundBleedAvoidance bleedAvoidance, SkXfermode::Mode op, LayoutObject* backgroundObject) | |
| 191 { | 172 { |
| 192 Vector<const FillLayer*, 8> layers; | 173 bool isNonAssociative = false; |
| 193 const FillLayer* curLayer = &fillLayer; | 174 for (auto currentLayer = &fillLayer; currentLayer; currentLayer = currentLay er->next()) { |
| 194 bool shouldDrawBackgroundInSeparateBuffer = false; | 175 reversedPaintList.append(currentLayer); |
| 195 bool isBottomLayerOccluded = false; | |
| 196 while (curLayer) { | |
| 197 layers.append(curLayer); | |
| 198 // Stop traversal when an opaque layer is encountered. | 176 // Stop traversal when an opaque layer is encountered. |
| 199 // FIXME : It would be possible for the following occlusion culling test to be more aggressive | 177 // FIXME : It would be possible for the following occlusion culling test to be more aggressive |
| 200 // on layers with no repeat by testing whether the image covers the layo ut rect. | 178 // on layers with no repeat by testing whether the image covers the layo ut rect. |
| 201 // Testing that here would imply duplicating a lot of calculations that are currently done in | 179 // Testing that here would imply duplicating a lot of calculations that are currently done in |
| 202 // LayoutBoxModelObject::paintFillLayerExtended. A more efficient soluti on might be to move | 180 // LayoutBoxModelObject::paintFillLayerExtended. A more efficient soluti on might be to move |
| 203 // the layer recursion into paintFillLayerExtended, or to compute the la yer geometry here | 181 // the layer recursion into paintFillLayerExtended, or to compute the la yer geometry here |
| 204 // and pass it down. | 182 // and pass it down. |
| 205 | 183 |
| 206 if (!shouldDrawBackgroundInSeparateBuffer && curLayer->blendMode() != We bBlendModeNormal) | 184 if (currentLayer->composite() != CompositeSourceOver || currentLayer->bl endMode() != WebBlendModeNormal) |
| 207 shouldDrawBackgroundInSeparateBuffer = true; | 185 isNonAssociative = true; |
| 208 | 186 |
| 209 if (curLayer->clipOccludesNextLayers() | 187 // TODO(trchen): A fill layer cannot paint if the calculated tile size i s empty. |
| 210 && curLayer->hasOpaqueImage(&m_layoutBox) | 188 // This occlusion check can be wrong. |
| 211 && curLayer->image()->canRender(m_layoutBox, m_layoutBox.style()->ef fectiveZoom()) | 189 if (currentLayer->clipOccludesNextLayers() |
| 212 && curLayer->hasRepeatXY() | 190 && isFillLayerOpaque(*currentLayer, m_layoutBox)) { |
| 213 && curLayer->blendMode() == WebBlendModeNormal | 191 if (currentLayer->clip() == BorderFillBox) |
| 214 && !m_layoutBox.boxShadowShouldBeAppliedToBackground(bleedAvoidance) ) | 192 isNonAssociative = false; |
| 215 break; | 193 break; |
| 216 curLayer = curLayer->next(); | 194 } |
| 195 } | |
| 196 return isNonAssociative; | |
| 197 } | |
| 198 | |
| 199 void BoxPainter::paintFillLayers(const PaintInfo& paintInfo, const Color& c, con st FillLayer& fillLayer, const LayoutRect& rect, BackgroundBleedAvoidance bleedA voidance, SkXfermode::Mode op, LayoutObject* backgroundObject) | |
|
Xianzhu
2015/06/02 23:34:35
Could this (as well as other FillLayer changes) be
trchen
2015/06/03 00:06:59
Probably not. The major changes here are:
1. Sepa
| |
| 200 { | |
| 201 Vector<const FillLayer*, 8> reversedPaintList; | |
| 202 bool shouldDrawBackgroundInSeparateBuffer = calculateFillLayerOcclusionCulli ng(reversedPaintList, fillLayer); | |
| 203 ASSERT(reversedPaintList.size()); | |
| 204 | |
| 205 // If we are responsible to paint box shadow, the bottom layer cannot be ski pped. | |
| 206 // TODO(trchen): Box shadow optimization and background color are concepts t hat only | |
| 207 // apply to background layers. Ideally we should refactor those out of paint FillLayer. | |
| 208 if (m_layoutBox.boxShadowShouldBeAppliedToBackground(bleedAvoidance)) { | |
| 209 const FillLayer* bottomLayer = *reversedPaintList.rbegin(); | |
| 210 if (bottomLayer->next()) { | |
| 211 while (bottomLayer->next()) | |
| 212 bottomLayer = bottomLayer->next(); | |
| 213 reversedPaintList.append(bottomLayer); | |
| 214 } | |
| 217 } | 215 } |
| 218 | 216 |
| 219 if (layers.size() > 0 && (**layers.rbegin()).next()) | 217 const FillLayer& lastLayer = **reversedPaintList.rbegin(); |
| 220 isBottomLayerOccluded = true; | 218 if (!lastLayer.next() |
| 219 && lastLayer.clip() == BorderFillBox | |
| 220 && !c.hasAlpha()) | |
| 221 shouldDrawBackgroundInSeparateBuffer = false; | |
| 221 | 222 |
| 222 GraphicsContext* context = paintInfo.context; | 223 GraphicsContext* context = paintInfo.context; |
| 223 if (!context) | 224 if (!context) |
| 224 shouldDrawBackgroundInSeparateBuffer = false; | 225 shouldDrawBackgroundInSeparateBuffer = false; |
| 225 | 226 |
| 226 bool skipBaseColor = false; | 227 if (shouldDrawBackgroundInSeparateBuffer) |
| 227 if (shouldDrawBackgroundInSeparateBuffer) { | 228 context->beginLayer(); |
| 228 bool isBaseColorVisible = !isBottomLayerOccluded && c.hasAlpha(); | |
| 229 | 229 |
| 230 // Paint the document's base background color outside the transparency l ayer, | 230 for (auto it = reversedPaintList.rbegin(); it != reversedPaintList.rend(); + +it) |
| 231 // so that the background images don't blend with this color: http://crb ug.com/389039. | 231 paintFillLayer(paintInfo, c, **it, rect, bleedAvoidance, op, backgroundO bject); |
| 232 if (isBaseColorVisible && isDocumentElementWithOpaqueBackground(m_layout Box)) { | |
| 233 paintRootBackgroundColor(m_layoutBox, paintInfo, rect, Color()); | |
| 234 skipBaseColor = true; | |
| 235 } | |
| 236 context->beginLayer(); | |
| 237 } | |
| 238 | |
| 239 Vector<const FillLayer*>::const_reverse_iterator topLayer = layers.rend(); | |
| 240 for (Vector<const FillLayer*>::const_reverse_iterator it = layers.rbegin(); it != topLayer; ++it) | |
| 241 paintFillLayer(paintInfo, c, **it, rect, bleedAvoidance, op, backgroundO bject, skipBaseColor); | |
| 242 | 232 |
| 243 if (shouldDrawBackgroundInSeparateBuffer) | 233 if (shouldDrawBackgroundInSeparateBuffer) |
| 244 context->endLayer(); | 234 context->endLayer(); |
| 245 } | 235 } |
| 246 | 236 |
| 247 void BoxPainter::paintFillLayer(const PaintInfo& paintInfo, const Color& c, cons t FillLayer& fillLayer, const LayoutRect& rect, | 237 void BoxPainter::paintFillLayer(const PaintInfo& paintInfo, const Color& c, cons t FillLayer& fillLayer, const LayoutRect& rect, |
| 248 BackgroundBleedAvoidance bleedAvoidance, SkXfermode::Mode op, LayoutObject* backgroundObject, bool skipBaseColor) | 238 BackgroundBleedAvoidance bleedAvoidance, SkXfermode::Mode op, LayoutObject* backgroundObject) |
| 249 { | 239 { |
| 250 BoxPainter::paintFillLayerExtended(m_layoutBox, paintInfo, c, fillLayer, rec t, bleedAvoidance, 0, LayoutSize(), op, backgroundObject, skipBaseColor); | 240 BoxPainter::paintFillLayerExtended(m_layoutBox, paintInfo, c, fillLayer, rec t, bleedAvoidance, 0, LayoutSize(), op, backgroundObject); |
| 251 } | 241 } |
| 252 | 242 |
| 253 void BoxPainter::applyBoxShadowForBackground(GraphicsContext* context, LayoutObj ect& obj) | 243 void BoxPainter::applyBoxShadowForBackground(GraphicsContext* context, LayoutObj ect& obj) |
| 254 { | 244 { |
| 255 const ShadowList* shadowList = obj.style()->boxShadow(); | 245 const ShadowList* shadowList = obj.style()->boxShadow(); |
| 256 ASSERT(shadowList); | 246 ASSERT(shadowList); |
| 257 for (size_t i = shadowList->shadows().size(); i--; ) { | 247 for (size_t i = shadowList->shadows().size(); i--; ) { |
| 258 const ShadowData& boxShadow = shadowList->shadows()[i]; | 248 const ShadowData& boxShadow = shadowList->shadows()[i]; |
| 259 if (boxShadow.style() != Normal) | 249 if (boxShadow.style() != Normal) |
| 260 continue; | 250 continue; |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 314 FloatRoundedRect::Radii insetRadii(backgroundRoundedRect.radii()); | 304 FloatRoundedRect::Radii insetRadii(backgroundRoundedRect.radii()); |
| 315 insetRadii.shrink(-insets.top(), -insets.bottom(), -insets.left(), -inse ts.right()); | 305 insetRadii.shrink(-insets.top(), -insets.bottom(), -insets.left(), -inse ts.right()); |
| 316 return FloatRoundedRect(insetRect, insetRadii); | 306 return FloatRoundedRect(insetRect, insetRadii); |
| 317 } | 307 } |
| 318 if (bleedAvoidance == BackgroundBleedBackgroundOverBorder) | 308 if (bleedAvoidance == BackgroundBleedBackgroundOverBorder) |
| 319 return obj.style()->getRoundedInnerBorderFor(borderRect, includeLogicalL eftEdge, includeLogicalRightEdge); | 309 return obj.style()->getRoundedInnerBorderFor(borderRect, includeLogicalL eftEdge, includeLogicalRightEdge); |
| 320 | 310 |
| 321 return getBackgroundRoundedRect(obj, borderRect, box, boxSize.width(), boxSi ze.height(), includeLogicalLeftEdge, includeLogicalRightEdge); | 311 return getBackgroundRoundedRect(obj, borderRect, box, boxSize.width(), boxSi ze.height(), includeLogicalLeftEdge, includeLogicalRightEdge); |
| 322 } | 312 } |
| 323 | 313 |
| 324 void BoxPainter::paintFillLayerExtended(LayoutBoxModelObject& obj, const PaintIn fo& paintInfo, const Color& color, const FillLayer& bgLayer, const LayoutRect& r ect, | 314 void BoxPainter::paintFillLayerExtended(LayoutBoxModelObject& obj, const PaintIn fo& paintInfo, const Color& color, const FillLayer& bgLayer, const LayoutRect& r ect, BackgroundBleedAvoidance bleedAvoidance, InlineFlowBox* box, const LayoutSi ze& boxSize, SkXfermode::Mode op, LayoutObject* backgroundObject) |
| 325 BackgroundBleedAvoidance bleedAvoidance, InlineFlowBox* box, const LayoutSiz e& boxSize, SkXfermode::Mode op, LayoutObject* backgroundObject, bool skipBaseCo lor) | |
| 326 { | 315 { |
| 327 GraphicsContext* context = paintInfo.context; | 316 GraphicsContext* context = paintInfo.context; |
| 328 if (rect.isEmpty()) | 317 if (rect.isEmpty()) |
| 329 return; | 318 return; |
| 330 | 319 |
| 331 bool includeLeftEdge = box ? box->includeLogicalLeftEdge() : true; | 320 bool includeLeftEdge = box ? box->includeLogicalLeftEdge() : true; |
| 332 bool includeRightEdge = box ? box->includeLogicalRightEdge() : true; | 321 bool includeRightEdge = box ? box->includeLogicalRightEdge() : true; |
| 333 | 322 |
| 334 bool hasRoundedBorder = obj.style()->hasBorderRadius() && (includeLeftEdge | | includeRightEdge); | 323 bool hasRoundedBorder = obj.style()->hasBorderRadius() && (includeLeftEdge | | includeRightEdge); |
| 335 bool clippedWithLocalScrolling = obj.hasOverflowClip() && bgLayer.attachment () == LocalBackgroundAttachment; | 324 bool clippedWithLocalScrolling = obj.hasOverflowClip() && bgLayer.attachment () == LocalBackgroundAttachment; |
| 336 bool isBorderFill = bgLayer.clip() == BorderFillBox; | 325 bool isBorderFill = bgLayer.clip() == BorderFillBox; |
| 337 bool isDocumentElementLayoutObject = obj.isDocumentElement(); | |
| 338 bool isBottomLayer = !bgLayer.next(); | 326 bool isBottomLayer = !bgLayer.next(); |
| 339 | 327 |
| 340 Color bgColor = color; | 328 Color bgColor = color; |
| 341 StyleImage* bgImage = bgLayer.image(); | 329 StyleImage* bgImage = bgLayer.image(); |
| 342 bool shouldPaintBackgroundImage = bgImage && bgImage->canRender(obj, obj.sty le()->effectiveZoom()); | |
| 343 | 330 |
| 344 bool forceBackgroundToWhite = false; | 331 bool forceBackgroundToWhite = false; |
| 345 if (obj.document().printing()) { | 332 if (obj.document().printing()) { |
| 346 if (obj.style()->printColorAdjust() == PrintColorAdjustEconomy) | 333 if (obj.style()->printColorAdjust() == PrintColorAdjustEconomy) |
| 347 forceBackgroundToWhite = true; | 334 forceBackgroundToWhite = true; |
| 348 if (obj.document().settings() && obj.document().settings()->shouldPrintB ackgrounds()) | 335 if (obj.document().settings() && obj.document().settings()->shouldPrintB ackgrounds()) |
| 349 forceBackgroundToWhite = false; | 336 forceBackgroundToWhite = false; |
| 350 } | 337 } |
| 351 | 338 |
| 352 // When printing backgrounds is disabled or using economy mode, | 339 // When printing backgrounds is disabled or using economy mode, |
| 353 // change existing background colors and images to a solid white background. | 340 // change existing background colors and images to a solid white background. |
| 354 // If there's no bg color or image, leave it untouched to avoid affecting tr ansparency. | 341 // If there's no bg color or image, leave it untouched to avoid affecting tr ansparency. |
| 355 // We don't try to avoid loading the background images, because this style f lag is only set | 342 // We don't try to avoid loading the background images, because this style f lag is only set |
| 356 // when printing, and at that point we've already loaded the background imag es anyway. (To avoid | 343 // when printing, and at that point we've already loaded the background imag es anyway. (To avoid |
| 357 // loading the background images we'd have to do this check when applying st yles rather than | 344 // loading the background images we'd have to do this check when applying st yles rather than |
| 358 // while layout.) | 345 // while layout.) |
| 359 if (forceBackgroundToWhite) { | 346 if (forceBackgroundToWhite) { |
| 360 // Note that we can't reuse this variable below because the bgColor migh t be changed | 347 // Note that we can't reuse this variable below because the bgColor migh t be changed |
| 361 bool shouldPaintBackgroundColor = isBottomLayer && bgColor.alpha(); | 348 bool shouldPaintBackgroundColor = isBottomLayer && bgColor.alpha(); |
| 362 if (shouldPaintBackgroundImage || shouldPaintBackgroundColor) { | 349 if (bgImage || shouldPaintBackgroundColor) { |
| 363 bgColor = Color::white; | 350 bgColor = Color::white; |
| 364 shouldPaintBackgroundImage = false; | 351 bgImage = nullptr; |
| 365 } | 352 } |
| 366 } | 353 } |
| 367 | 354 |
| 368 bool colorVisible = bgColor.alpha(); | |
| 369 | |
| 370 // Fast path for drawing simple color backgrounds. | 355 // Fast path for drawing simple color backgrounds. |
| 371 if (!isDocumentElementLayoutObject && !clippedWithLocalScrolling && !shouldP aintBackgroundImage && isBorderFill && isBottomLayer) { | 356 if (!clippedWithLocalScrolling && !bgImage && isBorderFill && isBottomLayer) { |
| 372 if (!colorVisible) | 357 if (!bgColor.alpha()) |
| 373 return; | 358 return; |
| 374 | 359 |
| 375 bool boxShadowShouldBeAppliedToBackground = obj.boxShadowShouldBeApplied ToBackground(bleedAvoidance, box); | 360 bool boxShadowShouldBeAppliedToBackground = obj.boxShadowShouldBeApplied ToBackground(bleedAvoidance, box); |
| 376 GraphicsContextStateSaver shadowStateSaver(*context, boxShadowShouldBeAp pliedToBackground); | 361 GraphicsContextStateSaver shadowStateSaver(*context, boxShadowShouldBeAp pliedToBackground); |
| 377 if (boxShadowShouldBeAppliedToBackground) | 362 if (boxShadowShouldBeAppliedToBackground) |
| 378 BoxPainter::applyBoxShadowForBackground(context, obj); | 363 BoxPainter::applyBoxShadowForBackground(context, obj); |
| 379 | 364 |
| 380 if (hasRoundedBorder && !bleedAvoidanceIsClipping(bleedAvoidance)) { | 365 if (hasRoundedBorder && !bleedAvoidanceIsClipping(bleedAvoidance)) { |
| 381 FloatRoundedRect border = backgroundRoundedRectAdjustedForBleedAvoid ance(obj, rect, | 366 FloatRoundedRect border = backgroundRoundedRectAdjustedForBleedAvoid ance(obj, rect, |
| 382 bleedAvoidance, box, boxSize, includeLeftEdge, includeRightEdge) ; | 367 bleedAvoidance, box, boxSize, includeLeftEdge, includeRightEdge) ; |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 472 | 457 |
| 473 break; | 458 break; |
| 474 } | 459 } |
| 475 case BorderFillBox: | 460 case BorderFillBox: |
| 476 break; | 461 break; |
| 477 default: | 462 default: |
| 478 ASSERT_NOT_REACHED(); | 463 ASSERT_NOT_REACHED(); |
| 479 break; | 464 break; |
| 480 } | 465 } |
| 481 | 466 |
| 467 BackgroundImageGeometry geometry; | |
| 468 if (bgImage) | |
| 469 calculateBackgroundImageGeometry(obj, paintInfo.paintContainer(), bgLaye r, scrolledPaintRect, geometry, backgroundObject); | |
| 470 bool shouldPaintBackgroundImage = bgImage && bgImage->canRender(obj, obj.sty le()->effectiveZoom()); | |
| 471 | |
| 482 // Paint the color first underneath all images, culled if background image o ccludes it. | 472 // Paint the color first underneath all images, culled if background image o ccludes it. |
| 483 // FIXME: In the bgLayer->hasFiniteBounds() case, we could improve the culli ng test | 473 // TODO(trchen): In the !bgLayer.hasRepeatXY() case, we could improve the cu lling test |
| 484 // by verifying whether the background image covers the entire layout rect. | 474 // by verifying whether the background image covers the entire painting area . |
| 485 if (isBottomLayer) { | 475 if (isBottomLayer) { |
| 486 IntRect backgroundRect(pixelSnappedIntRect(scrolledPaintRect)); | 476 IntRect backgroundRect(pixelSnappedIntRect(scrolledPaintRect)); |
| 487 bool boxShadowShouldBeAppliedToBackground = obj.boxShadowShouldBeApplied ToBackground(bleedAvoidance, box); | 477 bool boxShadowShouldBeAppliedToBackground = obj.boxShadowShouldBeApplied ToBackground(bleedAvoidance, box); |
| 488 bool isOpaqueRoot = (isDocumentElementLayoutObject && !bgColor.hasAlpha( )) || isDocumentElementWithOpaqueBackground(obj); | 478 bool backgroundImageOccludesBackgroundColor = shouldPaintBackgroundImage && isFillLayerOpaque(bgLayer, obj); |
| 489 if (boxShadowShouldBeAppliedToBackground || !shouldPaintBackgroundImage || !bgLayer.hasOpaqueImage(&obj) || !bgLayer.hasRepeatXY() || (isOpaqueRoot && ! toLayoutBox(&obj)->size().height())) { | 479 if (boxShadowShouldBeAppliedToBackground || !backgroundImageOccludesBack groundColor) { |
| 490 if (!RuntimeEnabledFeatures::slimmingPaintEnabled() && !boxShadowSho uldBeAppliedToBackground) | 480 if (!RuntimeEnabledFeatures::slimmingPaintEnabled() && !boxShadowSho uldBeAppliedToBackground) |
| 491 backgroundRect.intersect(paintInfo.rect); | 481 backgroundRect.intersect(paintInfo.rect); |
| 492 | 482 |
| 493 GraphicsContextStateSaver shadowStateSaver(*context, boxShadowShould BeAppliedToBackground); | 483 GraphicsContextStateSaver shadowStateSaver(*context, boxShadowShould BeAppliedToBackground); |
| 494 if (boxShadowShouldBeAppliedToBackground) | 484 if (boxShadowShouldBeAppliedToBackground) |
| 495 BoxPainter::applyBoxShadowForBackground(context, obj); | 485 BoxPainter::applyBoxShadowForBackground(context, obj); |
| 496 | 486 |
| 497 if (isOpaqueRoot && !skipBaseColor) { | 487 if (bgColor.alpha()) |
| 498 paintRootBackgroundColor(obj, paintInfo, rect, bgColor); | |
| 499 } else if (bgColor.alpha()) { | |
| 500 context->fillRect(backgroundRect, bgColor); | 488 context->fillRect(backgroundRect, bgColor); |
| 501 } | |
| 502 } | 489 } |
| 503 } | 490 } |
| 504 | 491 |
| 505 // no progressive loading of the background image | 492 // no progressive loading of the background image |
| 506 if (shouldPaintBackgroundImage) { | 493 if (shouldPaintBackgroundImage) { |
| 507 BackgroundImageGeometry geometry; | |
| 508 calculateBackgroundImageGeometry(obj, paintInfo.paintContainer(), bgLaye r, scrolledPaintRect, geometry, backgroundObject); | |
| 509 if (!geometry.destRect().isEmpty()) { | 494 if (!geometry.destRect().isEmpty()) { |
| 510 SkXfermode::Mode bgOp = WebCoreCompositeToSkiaComposite(bgLayer.comp osite(), bgLayer.blendMode()); | 495 SkXfermode::Mode bgOp = WebCoreCompositeToSkiaComposite(bgLayer.comp osite(), bgLayer.blendMode()); |
| 511 // if op != SkXfermode::kSrcOver_Mode, a mask is being painted. | 496 // if op != SkXfermode::kSrcOver_Mode, a mask is being painted. |
| 512 SkXfermode::Mode compositeOp = op == SkXfermode::kSrcOver_Mode ? bgO p : op; | 497 SkXfermode::Mode compositeOp = op == SkXfermode::kSrcOver_Mode ? bgO p : op; |
| 513 LayoutObject* clientForBackgroundImage = backgroundObject ? backgrou ndObject : &obj; | 498 LayoutObject* clientForBackgroundImage = backgroundObject ? backgrou ndObject : &obj; |
| 514 RefPtr<Image> image = bgImage->image(clientForBackgroundImage, geome try.tileSize()); | 499 RefPtr<Image> image = bgImage->image(clientForBackgroundImage, geome try.tileSize()); |
| 515 InterpolationQuality interpolationQuality = chooseInterpolationQuali ty(*clientForBackgroundImage, context, image.get(), &bgLayer, LayoutSize(geometr y.tileSize())); | 500 InterpolationQuality interpolationQuality = chooseInterpolationQuali ty(*clientForBackgroundImage, context, image.get(), &bgLayer, LayoutSize(geometr y.tileSize())); |
| 516 if (bgLayer.maskSourceType() == MaskLuminance) | 501 if (bgLayer.maskSourceType() == MaskLuminance) |
| 517 context->setColorFilter(ColorFilterLuminanceToAlpha); | 502 context->setColorFilter(ColorFilterLuminanceToAlpha); |
| 518 InterpolationQuality previousInterpolationQuality = context->imageIn terpolationQuality(); | 503 InterpolationQuality previousInterpolationQuality = context->imageIn terpolationQuality(); |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 600 return; | 585 return; |
| 601 | 586 |
| 602 IntRect paintRect = pixelSnappedIntRect(LayoutRect(paintOffset, m_layoutBox. size())); | 587 IntRect paintRect = pixelSnappedIntRect(LayoutRect(paintOffset, m_layoutBox. size())); |
| 603 LayoutObjectDrawingRecorder drawingRecorder(*paintInfo.context, m_layoutBox, paintInfo.phase, paintRect); | 588 LayoutObjectDrawingRecorder drawingRecorder(*paintInfo.context, m_layoutBox, paintInfo.phase, paintRect); |
| 604 if (drawingRecorder.canUseCachedDrawing()) | 589 if (drawingRecorder.canUseCachedDrawing()) |
| 605 return; | 590 return; |
| 606 | 591 |
| 607 paintInfo.context->fillRect(paintRect, Color::black); | 592 paintInfo.context->fillRect(paintRect, Color::black); |
| 608 } | 593 } |
| 609 | 594 |
| 610 void BoxPainter::paintRootBackgroundColor(LayoutObject& obj, const PaintInfo& pa intInfo, const LayoutRect& rootBackgroundRect, const Color& bgColor) | |
| 611 { | |
| 612 if (rootBackgroundRect.isEmpty()) | |
| 613 return; | |
| 614 | |
| 615 ASSERT(obj.isDocumentElement()); | |
| 616 | |
| 617 IntRect backgroundRect(pixelSnappedIntRect(rootBackgroundRect)); | |
| 618 if (!RuntimeEnabledFeatures::slimmingPaintEnabled()) | |
| 619 backgroundRect.intersect(paintInfo.rect); | |
| 620 | |
| 621 Color baseColor = obj.view()->frameView()->baseBackgroundColor(); | |
| 622 bool shouldClearDocumentBackground = obj.document().settings() && obj.docume nt().settings()->shouldClearDocumentBackground(); | |
| 623 SkXfermode::Mode operation = shouldClearDocumentBackground ? | |
| 624 SkXfermode::kSrc_Mode : SkXfermode::kSrcOver_Mode; | |
| 625 | |
| 626 GraphicsContext* context = paintInfo.context; | |
| 627 | |
| 628 // If we have an alpha go ahead and blend with the base background color. | |
| 629 if (baseColor.alpha()) { | |
| 630 if (bgColor.alpha()) | |
| 631 baseColor = baseColor.blend(bgColor); | |
| 632 context->fillRect(backgroundRect, baseColor, operation); | |
| 633 } else if (bgColor.alpha()) { | |
| 634 context->fillRect(backgroundRect, bgColor, operation); | |
| 635 } else if (shouldClearDocumentBackground) { | |
| 636 context->clearRect(backgroundRect); | |
| 637 } | |
| 638 } | |
| 639 | |
| 640 bool BoxPainter::isDocumentElementWithOpaqueBackground(LayoutObject& obj) | |
| 641 { | |
| 642 if (!obj.isDocumentElement()) | |
| 643 return false; | |
| 644 | |
| 645 // The background is opaque only if we're the root document, since iframes w ith | |
| 646 // no background in the child document should show the parent's background. | |
| 647 bool isOpaque = true; | |
| 648 Element* ownerElement = obj.document().ownerElement(); | |
| 649 if (ownerElement) { | |
| 650 if (!isHTMLFrameElement(*ownerElement)) { | |
| 651 // Locate the <body> element using the DOM. This is easier than tryi ng | |
| 652 // to crawl around a layout tree with potential :before/:after conte nt and | |
| 653 // anonymous blocks created by inline <body> tags etc. We can locate the <body> | |
| 654 // layout object very easily via the DOM. | |
| 655 HTMLElement* body = obj.document().body(); | |
| 656 if (body) { | |
| 657 // Can't scroll a frameset document anyway. | |
| 658 isOpaque = body->hasTagName(HTMLNames::framesetTag); | |
| 659 } else { | |
| 660 // FIXME: SVG specific behavior should be in the SVG code. | |
| 661 // SVG documents and XML documents with SVG root nodes are trans parent. | |
| 662 isOpaque = !obj.document().hasSVGRootNode(); | |
| 663 } | |
| 664 } | |
| 665 } else if (obj.view()->frameView()) { | |
| 666 isOpaque = !obj.view()->frameView()->isTransparent(); | |
| 667 } | |
| 668 | |
| 669 return isOpaque; | |
| 670 } | |
| 671 | |
| 672 // Return the amount of space to leave between image tiles for the background-re peat: space property. | 595 // Return the amount of space to leave between image tiles for the background-re peat: space property. |
| 673 static inline int getSpaceBetweenImageTiles(int areaSize, int tileSize) | 596 static inline int getSpaceBetweenImageTiles(int areaSize, int tileSize) |
| 674 { | 597 { |
| 675 int numberOfTiles = areaSize / tileSize; | 598 int numberOfTiles = areaSize / tileSize; |
| 676 int space = -1; | 599 int space = -1; |
| 677 | 600 |
| 678 if (numberOfTiles > 1) { | 601 if (numberOfTiles > 1) { |
| 679 // Spec doesn't specify rounding, so use the same method as for backgrou nd-repeat: round. | 602 // Spec doesn't specify rounding, so use the same method as for backgrou nd-repeat: round. |
| 680 space = lroundf((areaSize - numberOfTiles * tileSize) / (float)(numberOf Tiles - 1)); | 603 space = lroundf((areaSize - numberOfTiles * tileSize) / (float)(numberOf Tiles - 1)); |
| 681 } | 604 } |
| 682 | 605 |
| 683 return space; | 606 return space; |
| 684 } | 607 } |
| 685 | 608 |
| 686 void BoxPainter::calculateBackgroundImageGeometry(LayoutBoxModelObject& obj, con st LayoutBoxModelObject* paintContainer, const FillLayer& fillLayer, const Layou tRect& paintRect, | 609 void BoxPainter::calculateBackgroundImageGeometry(LayoutBoxModelObject& obj, con st LayoutBoxModelObject* paintContainer, const FillLayer& fillLayer, const Layou tRect& paintRect, |
| 687 BackgroundImageGeometry& geometry, LayoutObject* backgroundObject) | 610 BackgroundImageGeometry& geometry, LayoutObject* backgroundObject) |
| 688 { | 611 { |
| 689 LayoutUnit left = 0; | 612 LayoutUnit left = 0; |
| 690 LayoutUnit top = 0; | 613 LayoutUnit top = 0; |
| 691 IntSize positioningAreaSize; | 614 IntSize positioningAreaSize; |
| 692 IntRect snappedPaintRect = pixelSnappedIntRect(paintRect); | 615 IntRect snappedPaintRect = pixelSnappedIntRect(paintRect); |
| 616 bool isLayoutView = obj.isLayoutView(); | |
| 617 const LayoutBox* rootBox = nullptr; | |
| 618 if (isLayoutView) { | |
| 619 rootBox = toLayoutBox(obj.document().documentElement() ? obj.document(). documentElement()->layoutObject() : nullptr); | |
| 620 ASSERT(rootBox); | |
| 621 } | |
| 622 const LayoutBoxModelObject& positioningBox = isLayoutView ? static_cast<cons t LayoutBoxModelObject&>(*rootBox) : obj; | |
| 693 | 623 |
| 694 // Determine the background positioning area and set destRect to the backgro und painting area. | 624 // Determine the background positioning area and set destRect to the backgro und painting area. |
| 695 // destRect will be adjusted later if the background is non-repeating. | 625 // destRect will be adjusted later if the background is non-repeating. |
| 696 // FIXME: transforms spec says that fixed backgrounds behave like scroll ins ide transforms. | 626 // FIXME: transforms spec says that fixed backgrounds behave like scroll ins ide transforms. |
| 697 bool fixedAttachment = fillLayer.attachment() == FixedBackgroundAttachment; | 627 bool fixedAttachment = fillLayer.attachment() == FixedBackgroundAttachment; |
| 698 | 628 |
| 699 if (RuntimeEnabledFeatures::fastMobileScrollingEnabled()) { | 629 if (RuntimeEnabledFeatures::fastMobileScrollingEnabled()) { |
| 700 // As a side effect of an optimization to blit on scroll, we do not hono r the CSS | 630 // As a side effect of an optimization to blit on scroll, we do not hono r the CSS |
| 701 // property "background-attachment: fixed" because it may result in rend ering | 631 // property "background-attachment: fixed" because it may result in rend ering |
| 702 // artifacts. Note, these artifacts only appear if we are blitting on sc roll of | 632 // artifacts. Note, these artifacts only appear if we are blitting on sc roll of |
| 703 // a page that has fixed background images. | 633 // a page that has fixed background images. |
| 704 fixedAttachment = false; | 634 fixedAttachment = false; |
| 705 } | 635 } |
| 706 | 636 |
| 707 if (!fixedAttachment) { | 637 if (!fixedAttachment) { |
| 708 geometry.setDestRect(snappedPaintRect); | 638 geometry.setDestRect(snappedPaintRect); |
| 709 | 639 |
| 710 LayoutUnit right = 0; | 640 LayoutUnit right = 0; |
| 711 LayoutUnit bottom = 0; | 641 LayoutUnit bottom = 0; |
| 712 // Scroll and Local. | 642 // Scroll and Local. |
| 713 if (fillLayer.origin() != BorderFillBox) { | 643 if (fillLayer.origin() != BorderFillBox) { |
| 714 left = obj.borderLeft(); | 644 left = positioningBox.borderLeft(); |
| 715 right = obj.borderRight(); | 645 right = positioningBox.borderRight(); |
| 716 top = obj.borderTop(); | 646 top = positioningBox.borderTop(); |
| 717 bottom = obj.borderBottom(); | 647 bottom = positioningBox.borderBottom(); |
| 718 if (fillLayer.origin() == ContentFillBox) { | 648 if (fillLayer.origin() == ContentFillBox) { |
| 719 left += obj.paddingLeft(); | 649 left += positioningBox.paddingLeft(); |
| 720 right += obj.paddingRight(); | 650 right += positioningBox.paddingRight(); |
| 721 top += obj.paddingTop(); | 651 top += positioningBox.paddingTop(); |
| 722 bottom += obj.paddingBottom(); | 652 bottom += positioningBox.paddingBottom(); |
| 723 } | 653 } |
| 724 } | 654 } |
| 725 | 655 |
| 726 // The background of the box generated by the root element covers the en tire canvas including | 656 if (isLayoutView) { |
| 727 // its margins. Since those were added in already, we have to factor the m out when computing | 657 // The background of the box generated by the root element covers th e entire canvas and will |
| 728 // the background positioning area. | 658 // be painted by the view object, but the we should still use the ro ot element box for |
| 729 if (obj.isDocumentElement()) { | 659 // positioning. |
| 730 positioningAreaSize = pixelSnappedIntSize(toLayoutBox(&obj)->size() - LayoutSize(left + right, top + bottom), toLayoutBox(&obj)->location()); | 660 positioningAreaSize = pixelSnappedIntSize(rootBox->size() - LayoutSi ze(left + right, top + bottom), rootBox->location()); |
| 731 // The positioning area is right aligned in paintRect if RightToLeft WritingMode, or left aligned otherwise. | 661 // The input paint rect is specified in root element local coordinat e (i.e. a transform |
| 732 if (obj.style()->writingMode() == RightToLeftWritingMode) | 662 // is applied on the context for painting), and is expanded to cover the whole canvas. |
| 733 left = paintRect.width() - positioningAreaSize.width() - right - obj.marginRight(); | 663 // Since left/top is relative to the paint rect, we need to offset t hem back. |
| 734 else | 664 left -= paintRect.x(); |
| 735 left += obj.marginLeft(); | 665 top -= paintRect.y(); |
| 736 top += obj.marginTop(); | |
| 737 } else { | 666 } else { |
| 738 positioningAreaSize = pixelSnappedIntSize(paintRect.size() - LayoutS ize(left + right, top + bottom), paintRect.location()); | 667 positioningAreaSize = pixelSnappedIntSize(paintRect.size() - LayoutS ize(left + right, top + bottom), paintRect.location()); |
| 739 } | 668 } |
| 740 } else { | 669 } else { |
| 741 geometry.setHasNonLocalGeometry(); | 670 geometry.setHasNonLocalGeometry(); |
| 742 | 671 |
| 743 IntRect viewportRect = pixelSnappedIntRect(obj.viewRect()); | 672 IntRect viewportRect = pixelSnappedIntRect(obj.viewRect()); |
| 744 if (fixedBackgroundPaintsInLocalCoordinates(obj)) | 673 if (fixedBackgroundPaintsInLocalCoordinates(obj)) |
| 745 viewportRect.setLocation(IntPoint()); | 674 viewportRect.setLocation(IntPoint()); |
| 746 else if (FrameView* frameView = obj.view()->frameView()) | 675 else if (FrameView* frameView = obj.view()->frameView()) |
| 747 viewportRect.setLocation(IntPoint(frameView->scrollOffsetForViewport ConstrainedObjects())); | 676 viewportRect.setLocation(IntPoint(frameView->scrollOffsetForViewport ConstrainedObjects())); |
| 748 | 677 |
| 749 if (paintContainer) { | 678 if (paintContainer) { |
| 750 IntPoint absoluteContainerOffset = roundedIntPoint(paintContainer->l ocalToAbsolute(FloatPoint())); | 679 IntPoint absoluteContainerOffset = roundedIntPoint(paintContainer->l ocalToAbsolute(FloatPoint())); |
| 751 viewportRect.moveBy(-absoluteContainerOffset); | 680 viewportRect.moveBy(-absoluteContainerOffset); |
| 752 } | 681 } |
| 753 | 682 |
| 754 geometry.setDestRect(viewportRect); | 683 geometry.setDestRect(viewportRect); |
| 755 positioningAreaSize = geometry.destRect().size(); | 684 positioningAreaSize = geometry.destRect().size(); |
| 756 } | 685 } |
| 757 | 686 |
| 758 const LayoutObject* clientForBackgroundImage = backgroundObject ? background Object : &obj; | 687 const LayoutObject* clientForBackgroundImage = backgroundObject ? background Object : &obj; |
| 759 IntSize fillTileSize = calculateFillTileSize(obj, fillLayer, positioningArea Size); | 688 IntSize fillTileSize = calculateFillTileSize(positioningBox, fillLayer, posi tioningAreaSize); |
| 760 fillLayer.image()->setContainerSizeForLayoutObject(clientForBackgroundImage, fillTileSize, obj.style()->effectiveZoom()); | 689 fillLayer.image()->setContainerSizeForLayoutObject(clientForBackgroundImage, fillTileSize, obj.style()->effectiveZoom()); |
| 761 geometry.setTileSize(fillTileSize); | 690 geometry.setTileSize(fillTileSize); |
| 762 | 691 |
| 763 EFillRepeat backgroundRepeatX = fillLayer.repeatX(); | 692 EFillRepeat backgroundRepeatX = fillLayer.repeatX(); |
| 764 EFillRepeat backgroundRepeatY = fillLayer.repeatY(); | 693 EFillRepeat backgroundRepeatY = fillLayer.repeatY(); |
| 765 int availableWidth = positioningAreaSize.width() - geometry.tileSize().width (); | 694 int availableWidth = positioningAreaSize.width() - geometry.tileSize().width (); |
| 766 int availableHeight = positioningAreaSize.height() - geometry.tileSize().hei ght(); | 695 int availableHeight = positioningAreaSize.height() - geometry.tileSize().hei ght(); |
| 767 | 696 |
| 768 LayoutUnit computedXPosition = roundedMinimumValueForLength(fillLayer.xPosit ion(), availableWidth); | 697 LayoutUnit computedXPosition = roundedMinimumValueForLength(fillLayer.xPosit ion(), availableWidth); |
| 769 if (backgroundRepeatX == RoundFill && positioningAreaSize.width() > 0 && fil lTileSize.width() > 0) { | 698 if (backgroundRepeatX == RoundFill && positioningAreaSize.width() > 0 && fil lTileSize.width() > 0) { |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 847 geometry.clip(snappedPaintRect); | 776 geometry.clip(snappedPaintRect); |
| 848 } | 777 } |
| 849 | 778 |
| 850 InterpolationQuality BoxPainter::chooseInterpolationQuality(LayoutObject& obj, G raphicsContext* context, Image* image, const void* layer, const LayoutSize& size ) | 779 InterpolationQuality BoxPainter::chooseInterpolationQuality(LayoutObject& obj, G raphicsContext* context, Image* image, const void* layer, const LayoutSize& size ) |
| 851 { | 780 { |
| 852 return ImageQualityController::imageQualityController()->chooseInterpolation Quality(context, &obj, image, layer, size); | 781 return ImageQualityController::imageQualityController()->chooseInterpolation Quality(context, &obj, image, layer, size); |
| 853 } | 782 } |
| 854 | 783 |
| 855 bool BoxPainter::fixedBackgroundPaintsInLocalCoordinates(const LayoutObject& obj ) | 784 bool BoxPainter::fixedBackgroundPaintsInLocalCoordinates(const LayoutObject& obj ) |
| 856 { | 785 { |
| 857 if (!obj.isDocumentElement()) | 786 if (!obj.isLayoutView()) |
| 858 return false; | 787 return false; |
| 859 | 788 |
| 860 if (obj.view()->frameView() && obj.view()->frameView()->paintBehavior() & Pa intBehaviorFlattenCompositingLayers) | 789 const LayoutView& view = toLayoutView(obj); |
| 790 | |
| 791 if (view.frameView() && view.frameView()->paintBehavior() & PaintBehaviorFla ttenCompositingLayers) | |
| 861 return false; | 792 return false; |
| 862 | 793 |
| 863 DeprecatedPaintLayer* rootLayer = obj.view()->layer(); | 794 DeprecatedPaintLayer* rootLayer = view.layer(); |
| 864 if (!rootLayer || rootLayer->compositingState() == NotComposited) | 795 if (!rootLayer || rootLayer->compositingState() == NotComposited) |
| 865 return false; | 796 return false; |
| 866 | 797 |
| 867 return rootLayer->compositedDeprecatedPaintLayerMapping()->backgroundLayerPa intsFixedRootBackground(); | 798 return rootLayer->compositedDeprecatedPaintLayerMapping()->backgroundLayerPa intsFixedRootBackground(); |
| 868 } | 799 } |
| 869 | 800 |
| 870 static inline void applySubPixelHeuristicForTileSize(LayoutSize& tileSize, const IntSize& positioningAreaSize) | 801 static inline void applySubPixelHeuristicForTileSize(LayoutSize& tileSize, const IntSize& positioningAreaSize) |
| 871 { | 802 { |
| 872 tileSize.setWidth(positioningAreaSize.width() - tileSize.width() <= 1 ? tile Size.width().ceil() : tileSize.width().floor()); | 803 tileSize.setWidth(positioningAreaSize.width() - tileSize.width() <= 1 ? tile Size.width().ceil() : tileSize.width().floor()); |
| 873 tileSize.setHeight(positioningAreaSize.height() - tileSize.height() <= 1 ? t ileSize.height().ceil() : tileSize.height().floor()); | 804 tileSize.setHeight(positioningAreaSize.height() - tileSize.height() <= 1 ? t ileSize.height().ceil() : tileSize.height().floor()); |
| (...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1123 else | 1054 else |
| 1124 clippedEdges |= GraphicsContext::BottomEdge; | 1055 clippedEdges |= GraphicsContext::BottomEdge; |
| 1125 } | 1056 } |
| 1126 // TODO: support non-integer shadows - crbug.com/334828 | 1057 // TODO: support non-integer shadows - crbug.com/334828 |
| 1127 context->drawInnerShadow(border, shadowColor, flooredIntSize(shadowO ffset), shadowBlur, shadowSpread, clippedEdges); | 1058 context->drawInnerShadow(border, shadowColor, flooredIntSize(shadowO ffset), shadowBlur, shadowSpread, clippedEdges); |
| 1128 } | 1059 } |
| 1129 } | 1060 } |
| 1130 } | 1061 } |
| 1131 | 1062 |
| 1132 } // namespace blink | 1063 } // namespace blink |
| OLD | NEW |