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 |