| 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" |
| 11 #include "core/layout/Layer.h" | 11 #include "core/layout/Layer.h" |
| 12 #include "core/layout/LayoutObject.h" |
| 12 #include "core/layout/LayoutTable.h" | 13 #include "core/layout/LayoutTable.h" |
| 13 #include "core/layout/LayoutTheme.h" | 14 #include "core/layout/LayoutTheme.h" |
| 14 #include "core/layout/compositing/CompositedLayerMapping.h" | 15 #include "core/layout/compositing/CompositedLayerMapping.h" |
| 15 #include "core/paint/BackgroundImageGeometry.h" | 16 #include "core/paint/BackgroundImageGeometry.h" |
| 16 #include "core/paint/BoxDecorationData.h" | 17 #include "core/paint/BoxDecorationData.h" |
| 17 #include "core/paint/RenderDrawingRecorder.h" | 18 #include "core/paint/RenderDrawingRecorder.h" |
| 18 #include "core/paint/RoundedInnerRectClipper.h" | 19 #include "core/paint/RoundedInnerRectClipper.h" |
| 19 #include "core/rendering/ImageQualityController.h" | 20 #include "core/rendering/ImageQualityController.h" |
| 20 #include "core/rendering/PaintInfo.h" | 21 #include "core/rendering/PaintInfo.h" |
| 21 #include "core/rendering/RenderBox.h" | 22 #include "core/rendering/RenderBox.h" |
| 22 #include "core/rendering/RenderBoxModelObject.h" | 23 #include "core/rendering/RenderBoxModelObject.h" |
| 23 #include "core/rendering/RenderObject.h" | |
| 24 #include "core/rendering/RenderView.h" | 24 #include "core/rendering/RenderView.h" |
| 25 #include "core/rendering/style/BorderEdge.h" | 25 #include "core/rendering/style/BorderEdge.h" |
| 26 #include "core/rendering/style/ShadowList.h" | 26 #include "core/rendering/style/ShadowList.h" |
| 27 #include "platform/LengthFunctions.h" | 27 #include "platform/LengthFunctions.h" |
| 28 #include "platform/geometry/LayoutPoint.h" | 28 #include "platform/geometry/LayoutPoint.h" |
| 29 #include "platform/graphics/GraphicsContextStateSaver.h" | 29 #include "platform/graphics/GraphicsContextStateSaver.h" |
| 30 #include "platform/graphics/paint/CompositingDisplayItem.h" | 30 #include "platform/graphics/paint/CompositingDisplayItem.h" |
| 31 | 31 |
| 32 namespace blink { | 32 namespace blink { |
| 33 | 33 |
| 34 void BoxPainter::paint(const PaintInfo& paintInfo, const LayoutPoint& paintOffse
t) | 34 void BoxPainter::paint(const PaintInfo& paintInfo, const LayoutPoint& paintOffse
t) |
| 35 { | 35 { |
| 36 LayoutPoint adjustedPaintOffset = paintOffset + m_renderBox.location(); | 36 LayoutPoint adjustedPaintOffset = paintOffset + m_renderBox.location(); |
| 37 // default implementation. Just pass paint through to the children | 37 // default implementation. Just pass paint through to the children |
| 38 PaintInfo childInfo(paintInfo); | 38 PaintInfo childInfo(paintInfo); |
| 39 childInfo.updatePaintingRootForChildren(&m_renderBox); | 39 childInfo.updatePaintingRootForChildren(&m_renderBox); |
| 40 for (RenderObject* child = m_renderBox.slowFirstChild(); child; child = chil
d->nextSibling()) | 40 for (LayoutObject* child = m_renderBox.slowFirstChild(); child; child = chil
d->nextSibling()) |
| 41 child->paint(childInfo, adjustedPaintOffset); | 41 child->paint(childInfo, adjustedPaintOffset); |
| 42 } | 42 } |
| 43 | 43 |
| 44 void BoxPainter::paintBoxDecorationBackground(const PaintInfo& paintInfo, const
LayoutPoint& paintOffset) | 44 void BoxPainter::paintBoxDecorationBackground(const PaintInfo& paintInfo, const
LayoutPoint& paintOffset) |
| 45 { | 45 { |
| 46 if (!paintInfo.shouldPaintWithinRoot(&m_renderBox)) | 46 if (!paintInfo.shouldPaintWithinRoot(&m_renderBox)) |
| 47 return; | 47 return; |
| 48 | 48 |
| 49 LayoutRect paintRect = m_renderBox.borderBoxRect(); | 49 LayoutRect paintRect = m_renderBox.borderBoxRect(); |
| 50 paintRect.moveBy(paintOffset); | 50 paintRect.moveBy(paintOffset); |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 116 && (!boxDecorationData.hasAppearance || (!themePainted && LayoutTheme::t
heme().paintBorderOnly(&m_renderBox, paintInfo, snappedPaintRect))) | 116 && (!boxDecorationData.hasAppearance || (!themePainted && LayoutTheme::t
heme().paintBorderOnly(&m_renderBox, paintInfo, snappedPaintRect))) |
| 117 && !(m_renderBox.isTable() && toLayoutTable(&m_renderBox)->collapseBorde
rs())) | 117 && !(m_renderBox.isTable() && toLayoutTable(&m_renderBox)->collapseBorde
rs())) |
| 118 paintBorder(m_renderBox, paintInfo, paintRect, style, boxDecorationData.
bleedAvoidance()); | 118 paintBorder(m_renderBox, paintInfo, paintRect, style, boxDecorationData.
bleedAvoidance()); |
| 119 } | 119 } |
| 120 | 120 |
| 121 static bool skipBodyBackground(const RenderBox* bodyElementRenderer) | 121 static bool skipBodyBackground(const RenderBox* bodyElementRenderer) |
| 122 { | 122 { |
| 123 ASSERT(bodyElementRenderer->isBody()); | 123 ASSERT(bodyElementRenderer->isBody()); |
| 124 // The <body> only paints its background if the root element has defined a b
ackground independent of the body, | 124 // The <body> only paints its background if the root element has defined a b
ackground independent of the body, |
| 125 // or if the <body>'s parent is not the document element's renderer (e.g. in
side SVG foreignObject). | 125 // or if the <body>'s parent is not the document element's renderer (e.g. in
side SVG foreignObject). |
| 126 RenderObject* documentElementRenderer = bodyElementRenderer->document().docu
mentElement()->renderer(); | 126 LayoutObject* documentElementRenderer = bodyElementRenderer->document().docu
mentElement()->renderer(); |
| 127 return documentElementRenderer | 127 return documentElementRenderer |
| 128 && !documentElementRenderer->hasBackground() | 128 && !documentElementRenderer->hasBackground() |
| 129 && (documentElementRenderer == bodyElementRenderer->parent()); | 129 && (documentElementRenderer == bodyElementRenderer->parent()); |
| 130 } | 130 } |
| 131 | 131 |
| 132 void BoxPainter::paintBackground(const PaintInfo& paintInfo, const LayoutRect& p
aintRect, const Color& backgroundColor, BackgroundBleedAvoidance bleedAvoidance) | 132 void BoxPainter::paintBackground(const PaintInfo& paintInfo, const LayoutRect& p
aintRect, const Color& backgroundColor, BackgroundBleedAvoidance bleedAvoidance) |
| 133 { | 133 { |
| 134 if (m_renderBox.isDocumentElement()) { | 134 if (m_renderBox.isDocumentElement()) { |
| 135 paintRootBoxFillLayers(paintInfo); | 135 paintRootBoxFillLayers(paintInfo); |
| 136 return; | 136 return; |
| 137 } | 137 } |
| 138 if (m_renderBox.isBody() && skipBodyBackground(&m_renderBox)) | 138 if (m_renderBox.isBody() && skipBodyBackground(&m_renderBox)) |
| 139 return; | 139 return; |
| 140 if (m_renderBox.boxDecorationBackgroundIsKnownToBeObscured()) | 140 if (m_renderBox.boxDecorationBackgroundIsKnownToBeObscured()) |
| 141 return; | 141 return; |
| 142 paintFillLayers(paintInfo, backgroundColor, m_renderBox.style()->backgroundL
ayers(), paintRect, bleedAvoidance); | 142 paintFillLayers(paintInfo, backgroundColor, m_renderBox.style()->backgroundL
ayers(), paintRect, bleedAvoidance); |
| 143 } | 143 } |
| 144 | 144 |
| 145 void BoxPainter::paintRootBoxFillLayers(const PaintInfo& paintInfo) | 145 void BoxPainter::paintRootBoxFillLayers(const PaintInfo& paintInfo) |
| 146 { | 146 { |
| 147 if (paintInfo.skipRootBackground()) | 147 if (paintInfo.skipRootBackground()) |
| 148 return; | 148 return; |
| 149 | 149 |
| 150 RenderObject* rootBackgroundRenderer = m_renderBox.rendererForRootBackground
(); | 150 LayoutObject* rootBackgroundRenderer = m_renderBox.rendererForRootBackground
(); |
| 151 | 151 |
| 152 const FillLayer& bgLayer = rootBackgroundRenderer->style()->backgroundLayers
(); | 152 const FillLayer& bgLayer = rootBackgroundRenderer->style()->backgroundLayers
(); |
| 153 Color bgColor = rootBackgroundRenderer->resolveColor(CSSPropertyBackgroundCo
lor); | 153 Color bgColor = rootBackgroundRenderer->resolveColor(CSSPropertyBackgroundCo
lor); |
| 154 | 154 |
| 155 paintFillLayers(paintInfo, bgColor, bgLayer, scrolledBackgroundRect(), Backg
roundBleedNone, SkXfermode::kSrcOver_Mode, rootBackgroundRenderer); | 155 paintFillLayers(paintInfo, bgColor, bgLayer, scrolledBackgroundRect(), Backg
roundBleedNone, SkXfermode::kSrcOver_Mode, rootBackgroundRenderer); |
| 156 } | 156 } |
| 157 | 157 |
| 158 void BoxPainter::paintFillLayers(const PaintInfo& paintInfo, const Color& c, con
st FillLayer& fillLayer, const LayoutRect& rect, | 158 void BoxPainter::paintFillLayers(const PaintInfo& paintInfo, const Color& c, con
st FillLayer& fillLayer, const LayoutRect& rect, |
| 159 BackgroundBleedAvoidance bleedAvoidance, SkXfermode::Mode op, RenderObject*
backgroundObject) | 159 BackgroundBleedAvoidance bleedAvoidance, SkXfermode::Mode op, LayoutObject*
backgroundObject) |
| 160 { | 160 { |
| 161 Vector<const FillLayer*, 8> layers; | 161 Vector<const FillLayer*, 8> layers; |
| 162 const FillLayer* curLayer = &fillLayer; | 162 const FillLayer* curLayer = &fillLayer; |
| 163 bool shouldDrawBackgroundInSeparateBuffer = false; | 163 bool shouldDrawBackgroundInSeparateBuffer = false; |
| 164 bool isBottomLayerOccluded = false; | 164 bool isBottomLayerOccluded = false; |
| 165 while (curLayer) { | 165 while (curLayer) { |
| 166 layers.append(curLayer); | 166 layers.append(curLayer); |
| 167 // Stop traversal when an opaque layer is encountered. | 167 // Stop traversal when an opaque layer is encountered. |
| 168 // FIXME : It would be possible for the following occlusion culling test
to be more aggressive | 168 // FIXME : It would be possible for the following occlusion culling test
to be more aggressive |
| 169 // on layers with no repeat by testing whether the image covers the layo
ut rect. | 169 // on layers with no repeat by testing whether the image covers the layo
ut rect. |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 208 | 208 |
| 209 Vector<const FillLayer*>::const_reverse_iterator topLayer = layers.rend(); | 209 Vector<const FillLayer*>::const_reverse_iterator topLayer = layers.rend(); |
| 210 for (Vector<const FillLayer*>::const_reverse_iterator it = layers.rbegin();
it != topLayer; ++it) | 210 for (Vector<const FillLayer*>::const_reverse_iterator it = layers.rbegin();
it != topLayer; ++it) |
| 211 paintFillLayer(paintInfo, c, **it, rect, bleedAvoidance, op, backgroundO
bject, skipBaseColor); | 211 paintFillLayer(paintInfo, c, **it, rect, bleedAvoidance, op, backgroundO
bject, skipBaseColor); |
| 212 | 212 |
| 213 if (shouldDrawBackgroundInSeparateBuffer) | 213 if (shouldDrawBackgroundInSeparateBuffer) |
| 214 context->endLayer(); | 214 context->endLayer(); |
| 215 } | 215 } |
| 216 | 216 |
| 217 void BoxPainter::paintFillLayer(const PaintInfo& paintInfo, const Color& c, cons
t FillLayer& fillLayer, const LayoutRect& rect, | 217 void BoxPainter::paintFillLayer(const PaintInfo& paintInfo, const Color& c, cons
t FillLayer& fillLayer, const LayoutRect& rect, |
| 218 BackgroundBleedAvoidance bleedAvoidance, SkXfermode::Mode op, RenderObject*
backgroundObject, bool skipBaseColor) | 218 BackgroundBleedAvoidance bleedAvoidance, SkXfermode::Mode op, LayoutObject*
backgroundObject, bool skipBaseColor) |
| 219 { | 219 { |
| 220 BoxPainter::paintFillLayerExtended(m_renderBox, paintInfo, c, fillLayer, rec
t, bleedAvoidance, 0, LayoutSize(), op, backgroundObject, skipBaseColor); | 220 BoxPainter::paintFillLayerExtended(m_renderBox, paintInfo, c, fillLayer, rec
t, bleedAvoidance, 0, LayoutSize(), op, backgroundObject, skipBaseColor); |
| 221 } | 221 } |
| 222 | 222 |
| 223 void BoxPainter::applyBoxShadowForBackground(GraphicsContext* context, RenderObj
ect& obj) | 223 void BoxPainter::applyBoxShadowForBackground(GraphicsContext* context, LayoutObj
ect& obj) |
| 224 { | 224 { |
| 225 const ShadowList* shadowList = obj.style()->boxShadow(); | 225 const ShadowList* shadowList = obj.style()->boxShadow(); |
| 226 ASSERT(shadowList); | 226 ASSERT(shadowList); |
| 227 for (size_t i = shadowList->shadows().size(); i--; ) { | 227 for (size_t i = shadowList->shadows().size(); i--; ) { |
| 228 const ShadowData& boxShadow = shadowList->shadows()[i]; | 228 const ShadowData& boxShadow = shadowList->shadows()[i]; |
| 229 if (boxShadow.style() != Normal) | 229 if (boxShadow.style() != Normal) |
| 230 continue; | 230 continue; |
| 231 FloatSize shadowOffset(boxShadow.x(), boxShadow.y()); | 231 FloatSize shadowOffset(boxShadow.x(), boxShadow.y()); |
| 232 context->setShadow(shadowOffset, boxShadow.blur(), boxShadow.color(), | 232 context->setShadow(shadowOffset, boxShadow.blur(), boxShadow.color(), |
| 233 DrawLooperBuilder::ShadowRespectsTransforms, DrawLooperBuilder::Shad
owIgnoresAlpha); | 233 DrawLooperBuilder::ShadowRespectsTransforms, DrawLooperBuilder::Shad
owIgnoresAlpha); |
| 234 return; | 234 return; |
| 235 } | 235 } |
| 236 } | 236 } |
| 237 | 237 |
| 238 // FIXME: See crbug.com/382491. The use of getCTM in this context is incorrect b
ecause the matrix returned does not | 238 // FIXME: See crbug.com/382491. The use of getCTM in this context is incorrect b
ecause the matrix returned does not |
| 239 // include scales applied at raster time, such as the device zoom. | 239 // include scales applied at raster time, such as the device zoom. |
| 240 static LayoutRect shrinkRectByOnePixel(GraphicsContext* context, const LayoutRec
t& rect) | 240 static LayoutRect shrinkRectByOnePixel(GraphicsContext* context, const LayoutRec
t& rect) |
| 241 { | 241 { |
| 242 ASSERT(!RuntimeEnabledFeatures::slimmingPaintEnabled()); | 242 ASSERT(!RuntimeEnabledFeatures::slimmingPaintEnabled()); |
| 243 LayoutRect shrunkRect = rect; | 243 LayoutRect shrunkRect = rect; |
| 244 AffineTransform transform = context->getCTM(); | 244 AffineTransform transform = context->getCTM(); |
| 245 shrunkRect.inflateX(-static_cast<LayoutUnit>(ceil(1 / transform.xScale()))); | 245 shrunkRect.inflateX(-static_cast<LayoutUnit>(ceil(1 / transform.xScale()))); |
| 246 shrunkRect.inflateY(-static_cast<LayoutUnit>(ceil(1 / transform.yScale()))); | 246 shrunkRect.inflateY(-static_cast<LayoutUnit>(ceil(1 / transform.yScale()))); |
| 247 return shrunkRect; | 247 return shrunkRect; |
| 248 } | 248 } |
| 249 | 249 |
| 250 FloatRoundedRect BoxPainter::getBackgroundRoundedRect(RenderObject& obj, const L
ayoutRect& borderRect, InlineFlowBox* box, LayoutUnit inlineBoxWidth, LayoutUnit
inlineBoxHeight, | 250 FloatRoundedRect BoxPainter::getBackgroundRoundedRect(LayoutObject& obj, const L
ayoutRect& borderRect, InlineFlowBox* box, LayoutUnit inlineBoxWidth, LayoutUnit
inlineBoxHeight, |
| 251 bool includeLogicalLeftEdge, bool includeLogicalRightEdge) | 251 bool includeLogicalLeftEdge, bool includeLogicalRightEdge) |
| 252 { | 252 { |
| 253 FloatRoundedRect border = obj.style()->getRoundedBorderFor(borderRect, inclu
deLogicalLeftEdge, includeLogicalRightEdge); | 253 FloatRoundedRect border = obj.style()->getRoundedBorderFor(borderRect, inclu
deLogicalLeftEdge, includeLogicalRightEdge); |
| 254 if (box && (box->nextLineBox() || box->prevLineBox())) { | 254 if (box && (box->nextLineBox() || box->prevLineBox())) { |
| 255 FloatRoundedRect segmentBorder = obj.style()->getRoundedBorderFor(Layout
Rect(0, 0, inlineBoxWidth, inlineBoxHeight), includeLogicalLeftEdge, includeLogi
calRightEdge); | 255 FloatRoundedRect segmentBorder = obj.style()->getRoundedBorderFor(Layout
Rect(0, 0, inlineBoxWidth, inlineBoxHeight), includeLogicalLeftEdge, includeLogi
calRightEdge); |
| 256 border.setRadii(segmentBorder.radii()); | 256 border.setRadii(segmentBorder.radii()); |
| 257 } | 257 } |
| 258 | 258 |
| 259 return border; | 259 return border; |
| 260 } | 260 } |
| 261 | 261 |
| 262 FloatRoundedRect BoxPainter::backgroundRoundedRectAdjustedForBleedAvoidance(Rend
erObject& obj, GraphicsContext* context, const LayoutRect& borderRect, Backgroun
dBleedAvoidance bleedAvoidance, InlineFlowBox* box, const LayoutSize& boxSize, b
ool includeLogicalLeftEdge, bool includeLogicalRightEdge) | 262 FloatRoundedRect BoxPainter::backgroundRoundedRectAdjustedForBleedAvoidance(Layo
utObject& obj, GraphicsContext* context, const LayoutRect& borderRect, Backgroun
dBleedAvoidance bleedAvoidance, InlineFlowBox* box, const LayoutSize& boxSize, b
ool includeLogicalLeftEdge, bool includeLogicalRightEdge) |
| 263 { | 263 { |
| 264 if (bleedAvoidance == BackgroundBleedShrinkBackground) { | 264 if (bleedAvoidance == BackgroundBleedShrinkBackground) { |
| 265 // We shrink the rectangle by one pixel on each side because the bleed i
s one pixel maximum. | 265 // We shrink the rectangle by one pixel on each side because the bleed i
s one pixel maximum. |
| 266 return BoxPainter::getBackgroundRoundedRect(obj, shrinkRectByOnePixel(co
ntext, borderRect), box, boxSize.width(), boxSize.height(), includeLogicalLeftEd
ge, includeLogicalRightEdge); | 266 return BoxPainter::getBackgroundRoundedRect(obj, shrinkRectByOnePixel(co
ntext, borderRect), box, boxSize.width(), boxSize.height(), includeLogicalLeftEd
ge, includeLogicalRightEdge); |
| 267 } | 267 } |
| 268 if (bleedAvoidance == BackgroundBleedBackgroundOverBorder) | 268 if (bleedAvoidance == BackgroundBleedBackgroundOverBorder) |
| 269 return obj.style()->getRoundedInnerBorderFor(borderRect, includeLogicalL
eftEdge, includeLogicalRightEdge); | 269 return obj.style()->getRoundedInnerBorderFor(borderRect, includeLogicalL
eftEdge, includeLogicalRightEdge); |
| 270 | 270 |
| 271 return BoxPainter::getBackgroundRoundedRect(obj, borderRect, box, boxSize.wi
dth(), boxSize.height(), includeLogicalLeftEdge, includeLogicalRightEdge); | 271 return BoxPainter::getBackgroundRoundedRect(obj, borderRect, box, boxSize.wi
dth(), boxSize.height(), includeLogicalLeftEdge, includeLogicalRightEdge); |
| 272 } | 272 } |
| 273 | 273 |
| 274 void BoxPainter::paintFillLayerExtended(RenderBoxModelObject& obj, const PaintIn
fo& paintInfo, const Color& color, const FillLayer& bgLayer, const LayoutRect& r
ect, | 274 void BoxPainter::paintFillLayerExtended(RenderBoxModelObject& obj, const PaintIn
fo& paintInfo, const Color& color, const FillLayer& bgLayer, const LayoutRect& r
ect, |
| 275 BackgroundBleedAvoidance bleedAvoidance, InlineFlowBox* box, const LayoutSiz
e& boxSize, SkXfermode::Mode op, RenderObject* backgroundObject, bool skipBaseCo
lor) | 275 BackgroundBleedAvoidance bleedAvoidance, InlineFlowBox* box, const LayoutSiz
e& boxSize, SkXfermode::Mode op, LayoutObject* backgroundObject, bool skipBaseCo
lor) |
| 276 { | 276 { |
| 277 GraphicsContext* context = paintInfo.context; | 277 GraphicsContext* context = paintInfo.context; |
| 278 if (rect.isEmpty()) | 278 if (rect.isEmpty()) |
| 279 return; | 279 return; |
| 280 | 280 |
| 281 bool includeLeftEdge = box ? box->includeLogicalLeftEdge() : true; | 281 bool includeLeftEdge = box ? box->includeLogicalLeftEdge() : true; |
| 282 bool includeRightEdge = box ? box->includeLogicalRightEdge() : true; | 282 bool includeRightEdge = box ? box->includeLogicalRightEdge() : true; |
| 283 | 283 |
| 284 bool hasRoundedBorder = obj.style()->hasBorderRadius() && (includeLeftEdge |
| includeRightEdge); | 284 bool hasRoundedBorder = obj.style()->hasBorderRadius() && (includeLeftEdge |
| includeRightEdge); |
| 285 bool clippedWithLocalScrolling = obj.hasOverflowClip() && bgLayer.attachment
() == LocalBackgroundAttachment; | 285 bool clippedWithLocalScrolling = obj.hasOverflowClip() && bgLayer.attachment
() == LocalBackgroundAttachment; |
| (...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 444 } | 444 } |
| 445 | 445 |
| 446 // no progressive loading of the background image | 446 // no progressive loading of the background image |
| 447 if (shouldPaintBackgroundImage) { | 447 if (shouldPaintBackgroundImage) { |
| 448 BackgroundImageGeometry geometry; | 448 BackgroundImageGeometry geometry; |
| 449 calculateBackgroundImageGeometry(obj, paintInfo.paintContainer(), bgLaye
r, scrolledPaintRect, geometry, backgroundObject); | 449 calculateBackgroundImageGeometry(obj, paintInfo.paintContainer(), bgLaye
r, scrolledPaintRect, geometry, backgroundObject); |
| 450 if (!geometry.destRect().isEmpty()) { | 450 if (!geometry.destRect().isEmpty()) { |
| 451 SkXfermode::Mode bgOp = WebCoreCompositeToSkiaComposite(bgLayer.comp
osite(), bgLayer.blendMode()); | 451 SkXfermode::Mode bgOp = WebCoreCompositeToSkiaComposite(bgLayer.comp
osite(), bgLayer.blendMode()); |
| 452 // if op != SkXfermode::kSrcOver_Mode, a mask is being painted. | 452 // if op != SkXfermode::kSrcOver_Mode, a mask is being painted. |
| 453 SkXfermode::Mode compositeOp = op == SkXfermode::kSrcOver_Mode ? bgO
p : op; | 453 SkXfermode::Mode compositeOp = op == SkXfermode::kSrcOver_Mode ? bgO
p : op; |
| 454 RenderObject* clientForBackgroundImage = backgroundObject ? backgrou
ndObject : &obj; | 454 LayoutObject* clientForBackgroundImage = backgroundObject ? backgrou
ndObject : &obj; |
| 455 RefPtr<Image> image = bgImage->image(clientForBackgroundImage, geome
try.tileSize()); | 455 RefPtr<Image> image = bgImage->image(clientForBackgroundImage, geome
try.tileSize()); |
| 456 InterpolationQuality interpolationQuality = chooseInterpolationQuali
ty(obj, context, image.get(), &bgLayer, LayoutSize(geometry.tileSize())); | 456 InterpolationQuality interpolationQuality = chooseInterpolationQuali
ty(obj, context, image.get(), &bgLayer, LayoutSize(geometry.tileSize())); |
| 457 if (bgLayer.maskSourceType() == MaskLuminance) | 457 if (bgLayer.maskSourceType() == MaskLuminance) |
| 458 context->setColorFilter(ColorFilterLuminanceToAlpha); | 458 context->setColorFilter(ColorFilterLuminanceToAlpha); |
| 459 InterpolationQuality previousInterpolationQuality = context->imageIn
terpolationQuality(); | 459 InterpolationQuality previousInterpolationQuality = context->imageIn
terpolationQuality(); |
| 460 context->setImageInterpolationQuality(interpolationQuality); | 460 context->setImageInterpolationQuality(interpolationQuality); |
| 461 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "PaintI
mage", "data", InspectorPaintImageEvent::data(obj, *bgImage)); | 461 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "PaintI
mage", "data", InspectorPaintImageEvent::data(obj, *bgImage)); |
| 462 context->drawTiledImage(image.get(), geometry.destRect(), geometry.p
hase(), geometry.tileSize(), | 462 context->drawTiledImage(image.get(), geometry.destRect(), geometry.p
hase(), geometry.tileSize(), |
| 463 compositeOp, geometry.spaceSize()); | 463 compositeOp, geometry.spaceSize()); |
| 464 context->setImageInterpolationQuality(previousInterpolationQuality); | 464 context->setImageInterpolationQuality(previousInterpolationQuality); |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 542 if (!paintInfo.shouldPaintWithinRoot(&m_renderBox) || m_renderBox.style()->v
isibility() != VISIBLE || paintInfo.phase != PaintPhaseClippingMask) | 542 if (!paintInfo.shouldPaintWithinRoot(&m_renderBox) || m_renderBox.style()->v
isibility() != VISIBLE || paintInfo.phase != PaintPhaseClippingMask) |
| 543 return; | 543 return; |
| 544 | 544 |
| 545 if (!m_renderBox.layer() || m_renderBox.layer()->compositingState() != Paint
sIntoOwnBacking) | 545 if (!m_renderBox.layer() || m_renderBox.layer()->compositingState() != Paint
sIntoOwnBacking) |
| 546 return; | 546 return; |
| 547 | 547 |
| 548 LayoutRect paintRect = LayoutRect(paintOffset, m_renderBox.size()); | 548 LayoutRect paintRect = LayoutRect(paintOffset, m_renderBox.size()); |
| 549 paintInfo.context->fillRect(pixelSnappedIntRect(paintRect), Color::black); | 549 paintInfo.context->fillRect(pixelSnappedIntRect(paintRect), Color::black); |
| 550 } | 550 } |
| 551 | 551 |
| 552 void BoxPainter::paintRootBackgroundColor(RenderObject& obj, const PaintInfo& pa
intInfo, const LayoutRect& rect, const Color& bgColor) | 552 void BoxPainter::paintRootBackgroundColor(LayoutObject& obj, const PaintInfo& pa
intInfo, const LayoutRect& rect, const Color& bgColor) |
| 553 { | 553 { |
| 554 GraphicsContext* context = paintInfo.context; | 554 GraphicsContext* context = paintInfo.context; |
| 555 if (rect.isEmpty()) | 555 if (rect.isEmpty()) |
| 556 return; | 556 return; |
| 557 | 557 |
| 558 ASSERT(obj.isDocumentElement()); | 558 ASSERT(obj.isDocumentElement()); |
| 559 | 559 |
| 560 IntRect backgroundRect(pixelSnappedIntRect(rect)); | 560 IntRect backgroundRect(pixelSnappedIntRect(rect)); |
| 561 backgroundRect.intersect(paintInfo.rect); | 561 backgroundRect.intersect(paintInfo.rect); |
| 562 | 562 |
| 563 Color baseColor = obj.view()->frameView()->baseBackgroundColor(); | 563 Color baseColor = obj.view()->frameView()->baseBackgroundColor(); |
| 564 bool shouldClearDocumentBackground = obj.document().settings() && obj.docume
nt().settings()->shouldClearDocumentBackground(); | 564 bool shouldClearDocumentBackground = obj.document().settings() && obj.docume
nt().settings()->shouldClearDocumentBackground(); |
| 565 SkXfermode::Mode operation = shouldClearDocumentBackground ? SkXfermode::kSr
c_Mode : context->compositeOperation(); | 565 SkXfermode::Mode operation = shouldClearDocumentBackground ? SkXfermode::kSr
c_Mode : context->compositeOperation(); |
| 566 | 566 |
| 567 // If we have an alpha go ahead and blend with the base background color. | 567 // If we have an alpha go ahead and blend with the base background color. |
| 568 if (baseColor.alpha()) { | 568 if (baseColor.alpha()) { |
| 569 if (bgColor.alpha()) | 569 if (bgColor.alpha()) |
| 570 baseColor = baseColor.blend(bgColor); | 570 baseColor = baseColor.blend(bgColor); |
| 571 context->fillRect(backgroundRect, baseColor, operation); | 571 context->fillRect(backgroundRect, baseColor, operation); |
| 572 } else if (bgColor.alpha()) { | 572 } else if (bgColor.alpha()) { |
| 573 context->fillRect(backgroundRect, bgColor, operation); | 573 context->fillRect(backgroundRect, bgColor, operation); |
| 574 } else if (shouldClearDocumentBackground) { | 574 } else if (shouldClearDocumentBackground) { |
| 575 context->clearRect(backgroundRect); | 575 context->clearRect(backgroundRect); |
| 576 } | 576 } |
| 577 } | 577 } |
| 578 | 578 |
| 579 bool BoxPainter::isDocumentElementWithOpaqueBackground(RenderObject& obj) | 579 bool BoxPainter::isDocumentElementWithOpaqueBackground(LayoutObject& obj) |
| 580 { | 580 { |
| 581 if (!obj.isDocumentElement()) | 581 if (!obj.isDocumentElement()) |
| 582 return false; | 582 return false; |
| 583 | 583 |
| 584 // The background is opaque only if we're the root document, since iframes w
ith | 584 // The background is opaque only if we're the root document, since iframes w
ith |
| 585 // no background in the child document should show the parent's background. | 585 // no background in the child document should show the parent's background. |
| 586 bool isOpaque = true; | 586 bool isOpaque = true; |
| 587 Element* ownerElement = obj.document().ownerElement(); | 587 Element* ownerElement = obj.document().ownerElement(); |
| 588 if (ownerElement) { | 588 if (ownerElement) { |
| 589 if (!isHTMLFrameElement(*ownerElement)) { | 589 if (!isHTMLFrameElement(*ownerElement)) { |
| (...skipping 26 matching lines...) Expand all Loading... |
| 616 | 616 |
| 617 if (numberOfTiles > 1) { | 617 if (numberOfTiles > 1) { |
| 618 // Spec doesn't specify rounding, so use the same method as for backgrou
nd-repeat: round. | 618 // Spec doesn't specify rounding, so use the same method as for backgrou
nd-repeat: round. |
| 619 space = lroundf((areaSize - numberOfTiles * tileSize) / (float)(numberOf
Tiles - 1)); | 619 space = lroundf((areaSize - numberOfTiles * tileSize) / (float)(numberOf
Tiles - 1)); |
| 620 } | 620 } |
| 621 | 621 |
| 622 return space; | 622 return space; |
| 623 } | 623 } |
| 624 | 624 |
| 625 void BoxPainter::calculateBackgroundImageGeometry(RenderBoxModelObject& obj, con
st LayoutLayerModelObject* paintContainer, const FillLayer& fillLayer, const Lay
outRect& paintRect, | 625 void BoxPainter::calculateBackgroundImageGeometry(RenderBoxModelObject& obj, con
st LayoutLayerModelObject* paintContainer, const FillLayer& fillLayer, const Lay
outRect& paintRect, |
| 626 BackgroundImageGeometry& geometry, RenderObject* backgroundObject) | 626 BackgroundImageGeometry& geometry, LayoutObject* backgroundObject) |
| 627 { | 627 { |
| 628 LayoutUnit left = 0; | 628 LayoutUnit left = 0; |
| 629 LayoutUnit top = 0; | 629 LayoutUnit top = 0; |
| 630 IntSize positioningAreaSize; | 630 IntSize positioningAreaSize; |
| 631 IntRect snappedPaintRect = pixelSnappedIntRect(paintRect); | 631 IntRect snappedPaintRect = pixelSnappedIntRect(paintRect); |
| 632 | 632 |
| 633 // Determine the background positioning area and set destRect to the backgro
und painting area. | 633 // Determine the background positioning area and set destRect to the backgro
und painting area. |
| 634 // destRect will be adjusted later if the background is non-repeating. | 634 // destRect will be adjusted later if the background is non-repeating. |
| 635 // FIXME: transforms spec says that fixed backgrounds behave like scroll ins
ide transforms. | 635 // FIXME: transforms spec says that fixed backgrounds behave like scroll ins
ide transforms. |
| 636 bool fixedAttachment = fillLayer.attachment() == FixedBackgroundAttachment; | 636 bool fixedAttachment = fillLayer.attachment() == FixedBackgroundAttachment; |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 683 | 683 |
| 684 if (paintContainer) { | 684 if (paintContainer) { |
| 685 IntPoint absoluteContainerOffset = roundedIntPoint(paintContainer->l
ocalToAbsolute(FloatPoint())); | 685 IntPoint absoluteContainerOffset = roundedIntPoint(paintContainer->l
ocalToAbsolute(FloatPoint())); |
| 686 viewportRect.moveBy(-absoluteContainerOffset); | 686 viewportRect.moveBy(-absoluteContainerOffset); |
| 687 } | 687 } |
| 688 | 688 |
| 689 geometry.setDestRect(pixelSnappedIntRect(viewportRect)); | 689 geometry.setDestRect(pixelSnappedIntRect(viewportRect)); |
| 690 positioningAreaSize = geometry.destRect().size(); | 690 positioningAreaSize = geometry.destRect().size(); |
| 691 } | 691 } |
| 692 | 692 |
| 693 const RenderObject* clientForBackgroundImage = backgroundObject ? background
Object : &obj; | 693 const LayoutObject* clientForBackgroundImage = backgroundObject ? background
Object : &obj; |
| 694 IntSize fillTileSize = calculateFillTileSize(obj, fillLayer, positioningArea
Size); | 694 IntSize fillTileSize = calculateFillTileSize(obj, fillLayer, positioningArea
Size); |
| 695 fillLayer.image()->setContainerSizeForRenderer(clientForBackgroundImage, fil
lTileSize, obj.style()->effectiveZoom()); | 695 fillLayer.image()->setContainerSizeForRenderer(clientForBackgroundImage, fil
lTileSize, obj.style()->effectiveZoom()); |
| 696 geometry.setTileSize(fillTileSize); | 696 geometry.setTileSize(fillTileSize); |
| 697 | 697 |
| 698 EFillRepeat backgroundRepeatX = fillLayer.repeatX(); | 698 EFillRepeat backgroundRepeatX = fillLayer.repeatX(); |
| 699 EFillRepeat backgroundRepeatY = fillLayer.repeatY(); | 699 EFillRepeat backgroundRepeatY = fillLayer.repeatY(); |
| 700 int availableWidth = positioningAreaSize.width() - geometry.tileSize().width
(); | 700 int availableWidth = positioningAreaSize.width() - geometry.tileSize().width
(); |
| 701 int availableHeight = positioningAreaSize.height() - geometry.tileSize().hei
ght(); | 701 int availableHeight = positioningAreaSize.height() - geometry.tileSize().hei
ght(); |
| 702 | 702 |
| 703 LayoutUnit computedXPosition = roundedMinimumValueForLength(fillLayer.xPosit
ion(), availableWidth); | 703 LayoutUnit computedXPosition = roundedMinimumValueForLength(fillLayer.xPosit
ion(), availableWidth); |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 780 geometry.useFixedAttachment(snappedPaintRect.location()); | 780 geometry.useFixedAttachment(snappedPaintRect.location()); |
| 781 | 781 |
| 782 geometry.clip(snappedPaintRect); | 782 geometry.clip(snappedPaintRect); |
| 783 } | 783 } |
| 784 | 784 |
| 785 InterpolationQuality BoxPainter::chooseInterpolationQuality(RenderBoxModelObject
& obj, GraphicsContext* context, Image* image, const void* layer, const LayoutSi
ze& size) | 785 InterpolationQuality BoxPainter::chooseInterpolationQuality(RenderBoxModelObject
& obj, GraphicsContext* context, Image* image, const void* layer, const LayoutSi
ze& size) |
| 786 { | 786 { |
| 787 return ImageQualityController::imageQualityController()->chooseInterpolation
Quality(context, &obj, image, layer, size); | 787 return ImageQualityController::imageQualityController()->chooseInterpolation
Quality(context, &obj, image, layer, size); |
| 788 } | 788 } |
| 789 | 789 |
| 790 bool BoxPainter::fixedBackgroundPaintsInLocalCoordinates(const RenderObject& obj
) | 790 bool BoxPainter::fixedBackgroundPaintsInLocalCoordinates(const LayoutObject& obj
) |
| 791 { | 791 { |
| 792 if (!obj.isDocumentElement()) | 792 if (!obj.isDocumentElement()) |
| 793 return false; | 793 return false; |
| 794 | 794 |
| 795 if (obj.view()->frameView() && obj.view()->frameView()->paintBehavior() & Pa
intBehaviorFlattenCompositingLayers) | 795 if (obj.view()->frameView() && obj.view()->frameView()->paintBehavior() & Pa
intBehaviorFlattenCompositingLayers) |
| 796 return false; | 796 return false; |
| 797 | 797 |
| 798 Layer* rootLayer = obj.view()->layer(); | 798 Layer* rootLayer = obj.view()->layer(); |
| 799 if (!rootLayer || rootLayer->compositingState() == NotComposited) | 799 if (!rootLayer || rootLayer->compositingState() == NotComposited) |
| 800 return false; | 800 return false; |
| (...skipping 1390 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2191 | 2191 |
| 2192 FloatPoint secondQuad[4]; | 2192 FloatPoint secondQuad[4]; |
| 2193 secondQuad[0] = quad[0]; | 2193 secondQuad[0] = quad[0]; |
| 2194 secondQuad[1] = FloatPoint(quad[0].x() - r1 * cx, quad[0].y() - r1 * cy); | 2194 secondQuad[1] = FloatPoint(quad[0].x() - r1 * cx, quad[0].y() - r1 * cy); |
| 2195 secondQuad[2] = quad[2]; | 2195 secondQuad[2] = quad[2]; |
| 2196 secondQuad[3] = quad[3]; | 2196 secondQuad[3] = quad[3]; |
| 2197 graphicsContext->clipPolygon(4, secondQuad, !secondEdgeMatches); | 2197 graphicsContext->clipPolygon(4, secondQuad, !secondEdgeMatches); |
| 2198 } | 2198 } |
| 2199 | 2199 |
| 2200 } // namespace blink | 2200 } // namespace blink |
| OLD | NEW |