Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(622)

Side by Side Diff: third_party/WebKit/Source/core/paint/BoxPainter.cpp

Issue 1512803004: Use refs for GraphicsContext (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@ScrollbarTheme
Patch Set: Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
74 } // anonymous namespace 74 } // anonymous namespace
75 75
76 void BoxPainter::paintBoxDecorationBackgroundWithRect(const PaintInfo& paintInfo , const LayoutPoint& paintOffset, const LayoutRect& paintRect) 76 void BoxPainter::paintBoxDecorationBackgroundWithRect(const PaintInfo& paintInfo , const LayoutPoint& paintOffset, const LayoutRect& paintRect)
77 { 77 {
78 const ComputedStyle& style = m_layoutBox.styleRef(); 78 const ComputedStyle& style = m_layoutBox.styleRef();
79 79
80 // FIXME: For now we don't have notification on media buffered range change from media player 80 // FIXME: For now we don't have notification on media buffered range change from media player
81 // and miss paint invalidation on buffered range change. crbug.com/484288. 81 // and miss paint invalidation on buffered range change. crbug.com/484288.
82 Optional<DisplayItemCacheSkipper> cacheSkipper; 82 Optional<DisplayItemCacheSkipper> cacheSkipper;
83 if (style.appearance() == MediaSliderPart) 83 if (style.appearance() == MediaSliderPart)
84 cacheSkipper.emplace(*paintInfo.context); 84 cacheSkipper.emplace(paintInfo.context);
85 85
86 if (LayoutObjectDrawingRecorder::useCachedDrawingIfPossible(*paintInfo.conte xt, m_layoutBox, DisplayItem::BoxDecorationBackground, paintOffset)) 86 if (LayoutObjectDrawingRecorder::useCachedDrawingIfPossible(paintInfo.contex t, m_layoutBox, DisplayItem::BoxDecorationBackground, paintOffset))
87 return; 87 return;
88 88
89 LayoutObjectDrawingRecorder recorder(*paintInfo.context, m_layoutBox, Displa yItem::BoxDecorationBackground, boundsForDrawingRecorder(paintOffset), paintOffs et); 89 LayoutObjectDrawingRecorder recorder(paintInfo.context, m_layoutBox, Display Item::BoxDecorationBackground, boundsForDrawingRecorder(paintOffset), paintOffse t);
90 90
91 BoxDecorationData boxDecorationData(m_layoutBox); 91 BoxDecorationData boxDecorationData(m_layoutBox);
92 92
93 // FIXME: Should eventually give the theme control over whether the box shad ow should paint, since controls could have 93 // FIXME: Should eventually give the theme control over whether the box shad ow should paint, since controls could have
94 // custom shadows of their own. 94 // custom shadows of their own.
95 if (!m_layoutBox.boxShadowShouldBeAppliedToBackground(boxDecorationData.blee dAvoidance)) 95 if (!m_layoutBox.boxShadowShouldBeAppliedToBackground(boxDecorationData.blee dAvoidance))
96 paintBoxShadow(paintInfo, paintRect, style, Normal); 96 paintBoxShadow(paintInfo, paintRect, style, Normal);
97 97
98 GraphicsContextStateSaver stateSaver(*paintInfo.context, false); 98 GraphicsContextStateSaver stateSaver(paintInfo.context, false);
99 if (bleedAvoidanceIsClipping(boxDecorationData.bleedAvoidance)) { 99 if (bleedAvoidanceIsClipping(boxDecorationData.bleedAvoidance)) {
100 100
101 stateSaver.save(); 101 stateSaver.save();
102 FloatRoundedRect border = style.getRoundedBorderFor(paintRect); 102 FloatRoundedRect border = style.getRoundedBorderFor(paintRect);
103 paintInfo.context->clipRoundedRect(border); 103 paintInfo.context.clipRoundedRect(border);
104 104
105 if (boxDecorationData.bleedAvoidance == BackgroundBleedClipLayer) 105 if (boxDecorationData.bleedAvoidance == BackgroundBleedClipLayer)
106 paintInfo.context->beginLayer(); 106 paintInfo.context.beginLayer();
107 } 107 }
108 108
109 // If we have a native theme appearance, paint that before painting our back ground. 109 // If we have a native theme appearance, paint that before painting our back ground.
110 // The theme will tell us whether or not we should also paint the CSS backgr ound. 110 // The theme will tell us whether or not we should also paint the CSS backgr ound.
111 IntRect snappedPaintRect(pixelSnappedIntRect(paintRect)); 111 IntRect snappedPaintRect(pixelSnappedIntRect(paintRect));
112 ThemePainter& themePainter = LayoutTheme::theme().painter(); 112 ThemePainter& themePainter = LayoutTheme::theme().painter();
113 bool themePainted = boxDecorationData.hasAppearance && !themePainter.paint(m _layoutBox, paintInfo, snappedPaintRect); 113 bool themePainted = boxDecorationData.hasAppearance && !themePainter.paint(m _layoutBox, paintInfo, snappedPaintRect);
114 if (!themePainted) { 114 if (!themePainted) {
115 paintBackground(paintInfo, paintRect, boxDecorationData.backgroundColor, boxDecorationData.bleedAvoidance); 115 paintBackground(paintInfo, paintRect, boxDecorationData.backgroundColor, boxDecorationData.bleedAvoidance);
116 116
117 if (boxDecorationData.hasAppearance) 117 if (boxDecorationData.hasAppearance)
118 themePainter.paintDecorations(m_layoutBox, paintInfo, snappedPaintRe ct); 118 themePainter.paintDecorations(m_layoutBox, paintInfo, snappedPaintRe ct);
119 } 119 }
120 paintBoxShadow(paintInfo, paintRect, style, Inset); 120 paintBoxShadow(paintInfo, paintRect, style, Inset);
121 121
122 // The theme will tell us whether or not we should also paint the CSS border . 122 // The theme will tell us whether or not we should also paint the CSS border .
123 if (boxDecorationData.hasBorderDecoration 123 if (boxDecorationData.hasBorderDecoration
124 && (!boxDecorationData.hasAppearance || (!themePainted && LayoutTheme::t heme().painter().paintBorderOnly(m_layoutBox, paintInfo, snappedPaintRect))) 124 && (!boxDecorationData.hasAppearance || (!themePainted && LayoutTheme::t heme().painter().paintBorderOnly(m_layoutBox, paintInfo, snappedPaintRect)))
125 && !(m_layoutBox.isTable() && toLayoutTable(&m_layoutBox)->collapseBorde rs())) 125 && !(m_layoutBox.isTable() && toLayoutTable(&m_layoutBox)->collapseBorde rs()))
126 paintBorder(m_layoutBox, paintInfo, paintRect, style, boxDecorationData. bleedAvoidance); 126 paintBorder(m_layoutBox, paintInfo, paintRect, style, boxDecorationData. bleedAvoidance);
127 127
128 if (boxDecorationData.bleedAvoidance == BackgroundBleedClipLayer) 128 if (boxDecorationData.bleedAvoidance == BackgroundBleedClipLayer)
129 paintInfo.context->endLayer(); 129 paintInfo.context.endLayer();
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_layoutBox.isDocumentElement()) 134 if (m_layoutBox.isDocumentElement())
135 return; 135 return;
136 if (m_layoutBox.backgroundStolenForBeingBody()) 136 if (m_layoutBox.backgroundStolenForBeingBody())
137 return; 137 return;
138 if (m_layoutBox.boxDecorationBackgroundIsKnownToBeObscured()) 138 if (m_layoutBox.boxDecorationBackgroundIsKnownToBeObscured())
139 return; 139 return;
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
192 for (auto currentLayer = &fillLayer; currentLayer; currentLayer = curren tLayer->next()) { 192 for (auto currentLayer = &fillLayer; currentLayer; currentLayer = curren tLayer->next()) {
193 reversedPaintList.append(currentLayer); 193 reversedPaintList.append(currentLayer);
194 if (currentLayer->composite() != CompositeSourceOver || currentLayer ->blendMode() != WebBlendModeNormal) 194 if (currentLayer->composite() != CompositeSourceOver || currentLayer ->blendMode() != WebBlendModeNormal)
195 shouldDrawBackgroundInSeparateBuffer = true; 195 shouldDrawBackgroundInSeparateBuffer = true;
196 } 196 }
197 } 197 }
198 198
199 // TODO(trchen): We can optimize out isolation group if we have a non-transp arent 199 // TODO(trchen): We can optimize out isolation group if we have a non-transp arent
200 // background color and the bottom layer encloses all other layers. 200 // background color and the bottom layer encloses all other layers.
201 201
202 GraphicsContext* context = paintInfo.context; 202 GraphicsContext& context = paintInfo.context;
203 if (!context)
204 shouldDrawBackgroundInSeparateBuffer = false;
205 203
206 if (shouldDrawBackgroundInSeparateBuffer) 204 if (shouldDrawBackgroundInSeparateBuffer)
207 context->beginLayer(); 205 context.beginLayer();
208 206
209 for (auto it = reversedPaintList.rbegin(); it != reversedPaintList.rend(); + +it) 207 for (auto it = reversedPaintList.rbegin(); it != reversedPaintList.rend(); + +it)
210 paintFillLayer(paintInfo, c, **it, rect, bleedAvoidance, op, backgroundO bject); 208 paintFillLayer(paintInfo, c, **it, rect, bleedAvoidance, op, backgroundO bject);
211 209
212 if (shouldDrawBackgroundInSeparateBuffer) 210 if (shouldDrawBackgroundInSeparateBuffer)
213 context->endLayer(); 211 context.endLayer();
214 } 212 }
215 213
216 void BoxPainter::paintFillLayer(const PaintInfo& paintInfo, const Color& c, cons t FillLayer& fillLayer, const LayoutRect& rect, 214 void BoxPainter::paintFillLayer(const PaintInfo& paintInfo, const Color& c, cons t FillLayer& fillLayer, const LayoutRect& rect,
217 BackgroundBleedAvoidance bleedAvoidance, SkXfermode::Mode op, const LayoutOb ject* backgroundObject) 215 BackgroundBleedAvoidance bleedAvoidance, SkXfermode::Mode op, const LayoutOb ject* backgroundObject)
218 { 216 {
219 BoxPainter::paintFillLayerExtended(m_layoutBox, paintInfo, c, fillLayer, rec t, bleedAvoidance, 0, LayoutSize(), op, backgroundObject); 217 BoxPainter::paintFillLayerExtended(m_layoutBox, paintInfo, c, fillLayer, rec t, bleedAvoidance, 0, LayoutSize(), op, backgroundObject);
220 } 218 }
221 219
222 void BoxPainter::applyBoxShadowForBackground(GraphicsContext* context, const Lay outObject& obj) 220 void BoxPainter::applyBoxShadowForBackground(GraphicsContext& context, const Lay outObject& obj)
223 { 221 {
224 const ShadowList* shadowList = obj.style()->boxShadow(); 222 const ShadowList* shadowList = obj.style()->boxShadow();
225 ASSERT(shadowList); 223 ASSERT(shadowList);
226 for (size_t i = shadowList->shadows().size(); i--; ) { 224 for (size_t i = shadowList->shadows().size(); i--; ) {
227 const ShadowData& boxShadow = shadowList->shadows()[i]; 225 const ShadowData& boxShadow = shadowList->shadows()[i];
228 if (boxShadow.style() != Normal) 226 if (boxShadow.style() != Normal)
229 continue; 227 continue;
230 FloatSize shadowOffset(boxShadow.x(), boxShadow.y()); 228 FloatSize shadowOffset(boxShadow.x(), boxShadow.y());
231 context->setShadow(shadowOffset, boxShadow.blur(), 229 context.setShadow(shadowOffset, boxShadow.blur(),
232 boxShadow.color().resolve(obj.resolveColor(CSSPropertyColor)), 230 boxShadow.color().resolve(obj.resolveColor(CSSPropertyColor)),
233 DrawLooperBuilder::ShadowRespectsTransforms, DrawLooperBuilder::Shad owIgnoresAlpha); 231 DrawLooperBuilder::ShadowRespectsTransforms, DrawLooperBuilder::Shad owIgnoresAlpha);
234 return; 232 return;
235 } 233 }
236 } 234 }
237 235
238 FloatRoundedRect BoxPainter::getBackgroundRoundedRect(const LayoutObject& obj, c onst LayoutRect& borderRect, 236 FloatRoundedRect BoxPainter::getBackgroundRoundedRect(const LayoutObject& obj, c onst LayoutRect& borderRect,
239 const InlineFlowBox* box, LayoutUnit inlineBoxWidth, LayoutUnit inlineBoxHei ght, 237 const InlineFlowBox* box, LayoutUnit inlineBoxWidth, LayoutUnit inlineBoxHei ght,
240 bool includeLogicalLeftEdge, bool includeLogicalRightEdge) 238 bool includeLogicalLeftEdge, bool includeLogicalRightEdge)
241 { 239 {
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
283 FloatRoundedRect::Radii insetRadii(backgroundRoundedRect.radii()); 281 FloatRoundedRect::Radii insetRadii(backgroundRoundedRect.radii());
284 insetRadii.shrink(-insets.top(), -insets.bottom(), -insets.left(), -inse ts.right()); 282 insetRadii.shrink(-insets.top(), -insets.bottom(), -insets.left(), -inse ts.right());
285 return FloatRoundedRect(insetRect, insetRadii); 283 return FloatRoundedRect(insetRect, insetRadii);
286 } 284 }
287 285
288 return getBackgroundRoundedRect(obj, borderRect, box, boxSize.width(), boxSi ze.height(), includeLogicalLeftEdge, includeLogicalRightEdge); 286 return getBackgroundRoundedRect(obj, borderRect, box, boxSize.width(), boxSi ze.height(), includeLogicalLeftEdge, includeLogicalRightEdge);
289 } 287 }
290 288
291 void BoxPainter::paintFillLayerExtended(const LayoutBoxModelObject& obj, const P aintInfo& paintInfo, const Color& color, const FillLayer& bgLayer, const LayoutR ect& rect, BackgroundBleedAvoidance bleedAvoidance, const InlineFlowBox* box, co nst LayoutSize& boxSize, SkXfermode::Mode op, const LayoutObject* backgroundObje ct) 289 void BoxPainter::paintFillLayerExtended(const LayoutBoxModelObject& obj, const P aintInfo& paintInfo, const Color& color, const FillLayer& bgLayer, const LayoutR ect& rect, BackgroundBleedAvoidance bleedAvoidance, const InlineFlowBox* box, co nst LayoutSize& boxSize, SkXfermode::Mode op, const LayoutObject* backgroundObje ct)
292 { 290 {
293 GraphicsContext* context = paintInfo.context; 291 GraphicsContext& context = paintInfo.context;
294 if (rect.isEmpty()) 292 if (rect.isEmpty())
295 return; 293 return;
296 294
297 bool includeLeftEdge = box ? box->includeLogicalLeftEdge() : true; 295 bool includeLeftEdge = box ? box->includeLogicalLeftEdge() : true;
298 bool includeRightEdge = box ? box->includeLogicalRightEdge() : true; 296 bool includeRightEdge = box ? box->includeLogicalRightEdge() : true;
299 297
300 bool hasRoundedBorder = obj.style()->hasBorderRadius() && (includeLeftEdge | | includeRightEdge); 298 bool hasRoundedBorder = obj.style()->hasBorderRadius() && (includeLeftEdge | | includeRightEdge);
301 bool clippedWithLocalScrolling = obj.hasOverflowClip() && bgLayer.attachment () == LocalBackgroundAttachment; 299 bool clippedWithLocalScrolling = obj.hasOverflowClip() && bgLayer.attachment () == LocalBackgroundAttachment;
302 bool isBorderFill = bgLayer.clip() == BorderFillBox; 300 bool isBorderFill = bgLayer.clip() == BorderFillBox;
303 bool isBottomLayer = !bgLayer.next(); 301 bool isBottomLayer = !bgLayer.next();
(...skipping 18 matching lines...) Expand all
322 bgImage = nullptr; 320 bgImage = nullptr;
323 } 321 }
324 } 322 }
325 323
326 // Fast path for drawing simple color backgrounds. 324 // Fast path for drawing simple color backgrounds.
327 if (!clippedWithLocalScrolling && !bgImage && isBorderFill && isBottomLayer) { 325 if (!clippedWithLocalScrolling && !bgImage && isBorderFill && isBottomLayer) {
328 if (!bgColor.alpha()) 326 if (!bgColor.alpha())
329 return; 327 return;
330 328
331 bool boxShadowShouldBeAppliedToBackground = obj.boxShadowShouldBeApplied ToBackground(bleedAvoidance, box); 329 bool boxShadowShouldBeAppliedToBackground = obj.boxShadowShouldBeApplied ToBackground(bleedAvoidance, box);
332 GraphicsContextStateSaver shadowStateSaver(*context, boxShadowShouldBeAp pliedToBackground); 330 GraphicsContextStateSaver shadowStateSaver(context, boxShadowShouldBeApp liedToBackground);
333 if (boxShadowShouldBeAppliedToBackground) 331 if (boxShadowShouldBeAppliedToBackground)
334 BoxPainter::applyBoxShadowForBackground(context, obj); 332 BoxPainter::applyBoxShadowForBackground(context, obj);
335 333
336 if (hasRoundedBorder && !bleedAvoidanceIsClipping(bleedAvoidance)) { 334 if (hasRoundedBorder && !bleedAvoidanceIsClipping(bleedAvoidance)) {
337 FloatRoundedRect border = backgroundRoundedRectAdjustedForBleedAvoid ance(obj, rect, 335 FloatRoundedRect border = backgroundRoundedRectAdjustedForBleedAvoid ance(obj, rect,
338 bleedAvoidance, box, boxSize, includeLeftEdge, includeRightEdge) ; 336 bleedAvoidance, box, boxSize, includeLeftEdge, includeRightEdge) ;
339 337
340 if (border.isRenderable()) { 338 if (border.isRenderable()) {
341 context->fillRoundedRect(border, bgColor); 339 context.fillRoundedRect(border, bgColor);
342 } else { 340 } else {
343 RoundedInnerRectClipper clipper(obj, paintInfo, rect, border, Ap plyToContext); 341 RoundedInnerRectClipper clipper(obj, paintInfo, rect, border, Ap plyToContext);
344 context->fillRect(border.rect(), bgColor); 342 context.fillRect(border.rect(), bgColor);
345 } 343 }
346 } else { 344 } else {
347 context->fillRect(pixelSnappedIntRect(rect), bgColor); 345 context.fillRect(pixelSnappedIntRect(rect), bgColor);
348 } 346 }
349 347
350 return; 348 return;
351 } 349 }
352 350
353 // BorderFillBox radius clipping is taken care of by BackgroundBleedClip{Onl y,Layer} 351 // BorderFillBox radius clipping is taken care of by BackgroundBleedClip{Onl y,Layer}
354 bool clipToBorderRadius = hasRoundedBorder && !(isBorderFill && bleedAvoidan ceIsClipping(bleedAvoidance)); 352 bool clipToBorderRadius = hasRoundedBorder && !(isBorderFill && bleedAvoidan ceIsClipping(bleedAvoidance));
355 Optional<RoundedInnerRectClipper> clipToBorder; 353 Optional<RoundedInnerRectClipper> clipToBorder;
356 if (clipToBorderRadius) { 354 if (clipToBorderRadius) {
357 FloatRoundedRect border = isBorderFill 355 FloatRoundedRect border = isBorderFill
(...skipping 14 matching lines...) Expand all
372 } 370 }
373 371
374 clipToBorder.emplace(obj, paintInfo, rect, border, ApplyToContext); 372 clipToBorder.emplace(obj, paintInfo, rect, border, ApplyToContext);
375 } 373 }
376 374
377 int bLeft = includeLeftEdge ? obj.borderLeft() : 0; 375 int bLeft = includeLeftEdge ? obj.borderLeft() : 0;
378 int bRight = includeRightEdge ? obj.borderRight() : 0; 376 int bRight = includeRightEdge ? obj.borderRight() : 0;
379 LayoutUnit pLeft = includeLeftEdge ? obj.paddingLeft() : LayoutUnit(); 377 LayoutUnit pLeft = includeLeftEdge ? obj.paddingLeft() : LayoutUnit();
380 LayoutUnit pRight = includeRightEdge ? obj.paddingRight() : LayoutUnit(); 378 LayoutUnit pRight = includeRightEdge ? obj.paddingRight() : LayoutUnit();
381 379
382 GraphicsContextStateSaver clipWithScrollingStateSaver(*context, clippedWithL ocalScrolling); 380 GraphicsContextStateSaver clipWithScrollingStateSaver(context, clippedWithLo calScrolling);
383 LayoutRect scrolledPaintRect = rect; 381 LayoutRect scrolledPaintRect = rect;
384 if (clippedWithLocalScrolling) { 382 if (clippedWithLocalScrolling) {
385 // Clip to the overflow area. 383 // Clip to the overflow area.
386 const LayoutBox& thisBox = toLayoutBox(obj); 384 const LayoutBox& thisBox = toLayoutBox(obj);
387 // TODO(chrishtr): this should be pixel-snapped. 385 // TODO(chrishtr): this should be pixel-snapped.
388 context->clip(FloatRect(thisBox.overflowClipRect(rect.location()))); 386 context.clip(FloatRect(thisBox.overflowClipRect(rect.location())));
389 387
390 // Adjust the paint rect to reflect a scrolled content box with borders at the ends. 388 // Adjust the paint rect to reflect a scrolled content box with borders at the ends.
391 IntSize offset = thisBox.scrolledContentOffset(); 389 IntSize offset = thisBox.scrolledContentOffset();
392 scrolledPaintRect.move(-offset); 390 scrolledPaintRect.move(-offset);
393 scrolledPaintRect.setWidth(bLeft + thisBox.scrollWidth() + bRight); 391 scrolledPaintRect.setWidth(bLeft + thisBox.scrollWidth() + bRight);
394 scrolledPaintRect.setHeight(thisBox.borderTop() + thisBox.scrollHeight() + thisBox.borderBottom()); 392 scrolledPaintRect.setHeight(thisBox.borderTop() + thisBox.scrollHeight() + thisBox.borderBottom());
395 } 393 }
396 394
397 GraphicsContextStateSaver backgroundClipStateSaver(*context, false); 395 GraphicsContextStateSaver backgroundClipStateSaver(context, false);
398 IntRect maskRect; 396 IntRect maskRect;
399 397
400 switch (bgLayer.clip()) { 398 switch (bgLayer.clip()) {
401 case PaddingFillBox: 399 case PaddingFillBox:
402 case ContentFillBox: { 400 case ContentFillBox: {
403 if (clipToBorderRadius) 401 if (clipToBorderRadius)
404 break; 402 break;
405 403
406 // Clip to the padding or content boxes as necessary. 404 // Clip to the padding or content boxes as necessary.
407 bool includePadding = bgLayer.clip() == ContentFillBox; 405 bool includePadding = bgLayer.clip() == ContentFillBox;
408 LayoutRect clipRect(scrolledPaintRect.x() + bLeft + (includePadding ? pL eft : LayoutUnit()), 406 LayoutRect clipRect(scrolledPaintRect.x() + bLeft + (includePadding ? pL eft : LayoutUnit()),
409 scrolledPaintRect.y() + obj.borderTop() + (includePadding ? obj.padd ingTop() : LayoutUnit()), 407 scrolledPaintRect.y() + obj.borderTop() + (includePadding ? obj.padd ingTop() : LayoutUnit()),
410 scrolledPaintRect.width() - bLeft - bRight - (includePadding ? pLeft + pRight : LayoutUnit()), 408 scrolledPaintRect.width() - bLeft - bRight - (includePadding ? pLeft + pRight : LayoutUnit()),
411 scrolledPaintRect.height() - obj.borderTop() - obj.borderBottom() - (includePadding ? obj.paddingTop() + obj.paddingBottom() : LayoutUnit())); 409 scrolledPaintRect.height() - obj.borderTop() - obj.borderBottom() - (includePadding ? obj.paddingTop() + obj.paddingBottom() : LayoutUnit()));
412 backgroundClipStateSaver.save(); 410 backgroundClipStateSaver.save();
413 // TODO(chrishtr): this should be pixel-snapped. 411 // TODO(chrishtr): this should be pixel-snapped.
414 context->clip(FloatRect(clipRect)); 412 context.clip(FloatRect(clipRect));
415 413
416 break; 414 break;
417 } 415 }
418 case TextFillBox: { 416 case TextFillBox: {
419 // First figure out how big the mask has to be. It should be no bigger t han what we need 417 // First figure out how big the mask has to be. It should be no bigger t han what we need
420 // to actually render, so we should intersect the dirty rect with the bo rder box of the background. 418 // to actually render, so we should intersect the dirty rect with the bo rder box of the background.
421 maskRect = pixelSnappedIntRect(rect); 419 maskRect = pixelSnappedIntRect(rect);
422 420
423 // We draw the background into a separate layer, to be later masked with yet another layer 421 // We draw the background into a separate layer, to be later masked with yet another layer
424 // holding the text content. 422 // holding the text content.
425 backgroundClipStateSaver.save(); 423 backgroundClipStateSaver.save();
426 context->clip(maskRect); 424 context.clip(maskRect);
427 context->beginLayer(); 425 context.beginLayer();
428 426
429 break; 427 break;
430 } 428 }
431 case BorderFillBox: 429 case BorderFillBox:
432 break; 430 break;
433 default: 431 default:
434 ASSERT_NOT_REACHED(); 432 ASSERT_NOT_REACHED();
435 break; 433 break;
436 } 434 }
437 435
438 BackgroundImageGeometry geometry; 436 BackgroundImageGeometry geometry;
439 if (bgImage) 437 if (bgImage)
440 geometry.calculate(obj, paintInfo.paintContainer(), paintInfo.globalPain tFlags(), bgLayer, scrolledPaintRect); 438 geometry.calculate(obj, paintInfo.paintContainer(), paintInfo.globalPain tFlags(), bgLayer, scrolledPaintRect);
441 bool shouldPaintBackgroundImage = bgImage && bgImage->canRender(); 439 bool shouldPaintBackgroundImage = bgImage && bgImage->canRender();
442 440
443 // Paint the color first underneath all images, culled if background image o ccludes it. 441 // Paint the color first underneath all images, culled if background image o ccludes it.
444 // TODO(trchen): In the !bgLayer.hasRepeatXY() case, we could improve the cu lling test 442 // TODO(trchen): In the !bgLayer.hasRepeatXY() case, we could improve the cu lling test
445 // by verifying whether the background image covers the entire painting area . 443 // by verifying whether the background image covers the entire painting area .
446 if (isBottomLayer) { 444 if (isBottomLayer) {
447 IntRect backgroundRect(pixelSnappedIntRect(scrolledPaintRect)); 445 IntRect backgroundRect(pixelSnappedIntRect(scrolledPaintRect));
448 bool boxShadowShouldBeAppliedToBackground = obj.boxShadowShouldBeApplied ToBackground(bleedAvoidance, box); 446 bool boxShadowShouldBeAppliedToBackground = obj.boxShadowShouldBeApplied ToBackground(bleedAvoidance, box);
449 bool backgroundImageOccludesBackgroundColor = shouldPaintBackgroundImage && isFillLayerOpaque(bgLayer, obj); 447 bool backgroundImageOccludesBackgroundColor = shouldPaintBackgroundImage && isFillLayerOpaque(bgLayer, obj);
450 if (boxShadowShouldBeAppliedToBackground || !backgroundImageOccludesBack groundColor) { 448 if (boxShadowShouldBeAppliedToBackground || !backgroundImageOccludesBack groundColor) {
451 GraphicsContextStateSaver shadowStateSaver(*context, boxShadowShould BeAppliedToBackground); 449 GraphicsContextStateSaver shadowStateSaver(context, boxShadowShouldB eAppliedToBackground);
452 if (boxShadowShouldBeAppliedToBackground) 450 if (boxShadowShouldBeAppliedToBackground)
453 BoxPainter::applyBoxShadowForBackground(context, obj); 451 BoxPainter::applyBoxShadowForBackground(context, obj);
454 452
455 if (bgColor.alpha()) 453 if (bgColor.alpha())
456 context->fillRect(backgroundRect, bgColor); 454 context.fillRect(backgroundRect, bgColor);
457 } 455 }
458 } 456 }
459 457
460 // no progressive loading of the background image 458 // no progressive loading of the background image
461 if (shouldPaintBackgroundImage) { 459 if (shouldPaintBackgroundImage) {
462 if (!geometry.destRect().isEmpty()) { 460 if (!geometry.destRect().isEmpty()) {
463 SkXfermode::Mode bgOp = WebCoreCompositeToSkiaComposite(bgLayer.comp osite(), bgLayer.blendMode()); 461 SkXfermode::Mode bgOp = WebCoreCompositeToSkiaComposite(bgLayer.comp osite(), bgLayer.blendMode());
464 // if op != SkXfermode::kSrcOver_Mode, a mask is being painted. 462 // if op != SkXfermode::kSrcOver_Mode, a mask is being painted.
465 SkXfermode::Mode compositeOp = op == SkXfermode::kSrcOver_Mode ? bgO p : op; 463 SkXfermode::Mode compositeOp = op == SkXfermode::kSrcOver_Mode ? bgO p : op;
466 const LayoutObject* clientForBackgroundImage = backgroundObject ? ba ckgroundObject : &obj; 464 const LayoutObject* clientForBackgroundImage = backgroundObject ? ba ckgroundObject : &obj;
467 RefPtr<Image> image = bgImage->image(clientForBackgroundImage, floor edIntSize(geometry.imageContainerSize()), obj.style()->effectiveZoom()); 465 RefPtr<Image> image = bgImage->image(clientForBackgroundImage, floor edIntSize(geometry.imageContainerSize()), obj.style()->effectiveZoom());
468 InterpolationQuality interpolationQuality = chooseInterpolationQuali ty(*clientForBackgroundImage, context, image.get(), &bgLayer, LayoutSize(geometr y.tileSize())); 466 InterpolationQuality interpolationQuality = chooseInterpolationQuali ty(*clientForBackgroundImage, image.get(), &bgLayer, LayoutSize(geometry.tileSiz e()));
469 if (bgLayer.maskSourceType() == MaskLuminance) 467 if (bgLayer.maskSourceType() == MaskLuminance)
470 context->setColorFilter(ColorFilterLuminanceToAlpha); 468 context.setColorFilter(ColorFilterLuminanceToAlpha);
471 InterpolationQuality previousInterpolationQuality = context->imageIn terpolationQuality(); 469 InterpolationQuality previousInterpolationQuality = context.imageInt erpolationQuality();
472 context->setImageInterpolationQuality(interpolationQuality); 470 context.setImageInterpolationQuality(interpolationQuality);
473 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "PaintI mage", "data", InspectorPaintImageEvent::data(obj, *bgImage)); 471 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "PaintI mage", "data", InspectorPaintImageEvent::data(obj, *bgImage));
474 context->drawTiledImage(image.get(), FloatRect(geometry.destRect()), FloatPoint(geometry.phase()), FloatSize(geometry.tileSize()), 472 context.drawTiledImage(image.get(), FloatRect(geometry.destRect()), FloatPoint(geometry.phase()), FloatSize(geometry.tileSize()),
475 compositeOp, FloatSize(geometry.spaceSize())); 473 compositeOp, FloatSize(geometry.spaceSize()));
476 context->setImageInterpolationQuality(previousInterpolationQuality); 474 context.setImageInterpolationQuality(previousInterpolationQuality);
477 } 475 }
478 } 476 }
479 477
480 if (bgLayer.clip() == TextFillBox) { 478 if (bgLayer.clip() == TextFillBox) {
481 // Create the text mask layer. 479 // Create the text mask layer.
482 context->beginLayer(1, SkXfermode::kDstIn_Mode); 480 context.beginLayer(1, SkXfermode::kDstIn_Mode);
483 481
484 // Now draw the text into the mask. We do this by painting using a speci al paint phase that signals to 482 // Now draw the text into the mask. We do this by painting using a speci al paint phase that signals to
485 // InlineTextBoxes that they should just add their contents to the clip. 483 // InlineTextBoxes that they should just add their contents to the clip.
486 PaintInfo info(context, maskRect, PaintPhaseTextClip, GlobalPaintNormalP hase, 0); 484 PaintInfo info(context, maskRect, PaintPhaseTextClip, GlobalPaintNormalP hase, 0);
487 if (box) { 485 if (box) {
488 const RootInlineBox& root = box->root(); 486 const RootInlineBox& root = box->root();
489 box->paint(info, LayoutPoint(scrolledPaintRect.x() - box->x(), scrol ledPaintRect.y() - box->y()), root.lineTop(), root.lineBottom()); 487 box->paint(info, LayoutPoint(scrolledPaintRect.x() - box->x(), scrol ledPaintRect.y() - box->y()), root.lineTop(), root.lineBottom());
490 } else { 488 } else {
491 // FIXME: this should only have an effect for the line box list with in |obj|. Change this to create a LineBoxListPainter directly. 489 // FIXME: this should only have an effect for the line box list with in |obj|. Change this to create a LineBoxListPainter directly.
492 LayoutSize localOffset = obj.isBox() ? toLayoutBox(&obj)->locationOf fset() : LayoutSize(); 490 LayoutSize localOffset = obj.isBox() ? toLayoutBox(&obj)->locationOf fset() : LayoutSize();
493 obj.paint(info, scrolledPaintRect.location() - localOffset); 491 obj.paint(info, scrolledPaintRect.location() - localOffset);
494 } 492 }
495 493
496 context->endLayer(); 494 context.endLayer();
497 context->endLayer(); 495 context.endLayer();
498 } 496 }
499 } 497 }
500 498
501 void BoxPainter::paintMask(const PaintInfo& paintInfo, const LayoutPoint& paintO ffset) 499 void BoxPainter::paintMask(const PaintInfo& paintInfo, const LayoutPoint& paintO ffset)
502 { 500 {
503 if (!paintInfo.shouldPaintWithinRoot(&m_layoutBox) || m_layoutBox.style()->v isibility() != VISIBLE || paintInfo.phase != PaintPhaseMask) 501 if (!paintInfo.shouldPaintWithinRoot(&m_layoutBox) || m_layoutBox.style()->v isibility() != VISIBLE || paintInfo.phase != PaintPhaseMask)
504 return; 502 return;
505 503
506 if (LayoutObjectDrawingRecorder::useCachedDrawingIfPossible(*paintInfo.conte xt, m_layoutBox, paintInfo.phase, paintOffset)) 504 if (LayoutObjectDrawingRecorder::useCachedDrawingIfPossible(paintInfo.contex t, m_layoutBox, paintInfo.phase, paintOffset))
507 return; 505 return;
508 506
509 LayoutRect visualOverflowRect(m_layoutBox.visualOverflowRect()); 507 LayoutRect visualOverflowRect(m_layoutBox.visualOverflowRect());
510 visualOverflowRect.moveBy(paintOffset); 508 visualOverflowRect.moveBy(paintOffset);
511 509
512 LayoutObjectDrawingRecorder recorder(*paintInfo.context, m_layoutBox, paintI nfo.phase, visualOverflowRect, paintOffset); 510 LayoutObjectDrawingRecorder recorder(paintInfo.context, m_layoutBox, paintIn fo.phase, visualOverflowRect, paintOffset);
513 LayoutRect paintRect = LayoutRect(paintOffset, m_layoutBox.size()); 511 LayoutRect paintRect = LayoutRect(paintOffset, m_layoutBox.size());
514 paintMaskImages(paintInfo, paintRect); 512 paintMaskImages(paintInfo, paintRect);
515 } 513 }
516 514
517 void BoxPainter::paintMaskImages(const PaintInfo& paintInfo, const LayoutRect& p aintRect) 515 void BoxPainter::paintMaskImages(const PaintInfo& paintInfo, const LayoutRect& p aintRect)
518 { 516 {
519 // Figure out if we need to push a transparency layer to render our mask. 517 // Figure out if we need to push a transparency layer to render our mask.
520 bool pushTransparencyLayer = false; 518 bool pushTransparencyLayer = false;
521 bool compositedMask = m_layoutBox.hasLayer() && m_layoutBox.layer()->hasComp ositedMask(); 519 bool compositedMask = m_layoutBox.hasLayer() && m_layoutBox.layer()->hasComp ositedMask();
522 bool flattenCompositingLayers = paintInfo.globalPaintFlags() & GlobalPaintFl attenCompositingLayers; 520 bool flattenCompositingLayers = paintInfo.globalPaintFlags() & GlobalPaintFl attenCompositingLayers;
523 521
524 bool allMaskImagesLoaded = true; 522 bool allMaskImagesLoaded = true;
525 523
526 if (!compositedMask || flattenCompositingLayers) { 524 if (!compositedMask || flattenCompositingLayers) {
527 pushTransparencyLayer = true; 525 pushTransparencyLayer = true;
528 StyleImage* maskBoxImage = m_layoutBox.style()->maskBoxImage().image(); 526 StyleImage* maskBoxImage = m_layoutBox.style()->maskBoxImage().image();
529 const FillLayer& maskLayers = m_layoutBox.style()->maskLayers(); 527 const FillLayer& maskLayers = m_layoutBox.style()->maskLayers();
530 528
531 // Don't render a masked element until all the mask images have loaded, to prevent a flash of unmasked content. 529 // Don't render a masked element until all the mask images have loaded, to prevent a flash of unmasked content.
532 if (maskBoxImage) 530 if (maskBoxImage)
533 allMaskImagesLoaded &= maskBoxImage->isLoaded(); 531 allMaskImagesLoaded &= maskBoxImage->isLoaded();
534 532
535 allMaskImagesLoaded &= maskLayers.imagesAreLoaded(); 533 allMaskImagesLoaded &= maskLayers.imagesAreLoaded();
536 534
537 paintInfo.context->beginLayer(1, SkXfermode::kDstIn_Mode); 535 paintInfo.context.beginLayer(1, SkXfermode::kDstIn_Mode);
538 } 536 }
539 537
540 if (allMaskImagesLoaded) { 538 if (allMaskImagesLoaded) {
541 paintFillLayers(paintInfo, Color::transparent, m_layoutBox.style()->mask Layers(), paintRect); 539 paintFillLayers(paintInfo, Color::transparent, m_layoutBox.style()->mask Layers(), paintRect);
542 paintNinePieceImage(m_layoutBox, paintInfo.context, paintRect, m_layoutB ox.styleRef(), m_layoutBox.style()->maskBoxImage()); 540 paintNinePieceImage(m_layoutBox, paintInfo.context, paintRect, m_layoutB ox.styleRef(), m_layoutBox.style()->maskBoxImage());
543 } 541 }
544 542
545 if (pushTransparencyLayer) 543 if (pushTransparencyLayer)
546 paintInfo.context->endLayer(); 544 paintInfo.context.endLayer();
547 } 545 }
548 546
549 void BoxPainter::paintClippingMask(const PaintInfo& paintInfo, const LayoutPoint & paintOffset) 547 void BoxPainter::paintClippingMask(const PaintInfo& paintInfo, const LayoutPoint & paintOffset)
550 { 548 {
551 ASSERT(paintInfo.phase == PaintPhaseClippingMask); 549 ASSERT(paintInfo.phase == PaintPhaseClippingMask);
552 550
553 if (!paintInfo.shouldPaintWithinRoot(&m_layoutBox) || m_layoutBox.style()->v isibility() != VISIBLE) 551 if (!paintInfo.shouldPaintWithinRoot(&m_layoutBox) || m_layoutBox.style()->v isibility() != VISIBLE)
554 return; 552 return;
555 553
556 if (!m_layoutBox.layer() || m_layoutBox.layer()->compositingState() != Paint sIntoOwnBacking) 554 if (!m_layoutBox.layer() || m_layoutBox.layer()->compositingState() != Paint sIntoOwnBacking)
557 return; 555 return;
558 556
559 if (LayoutObjectDrawingRecorder::useCachedDrawingIfPossible(*paintInfo.conte xt, m_layoutBox, paintInfo.phase, paintOffset)) 557 if (LayoutObjectDrawingRecorder::useCachedDrawingIfPossible(paintInfo.contex t, m_layoutBox, paintInfo.phase, paintOffset))
560 return; 558 return;
561 559
562 IntRect paintRect = pixelSnappedIntRect(LayoutRect(paintOffset, m_layoutBox. size())); 560 IntRect paintRect = pixelSnappedIntRect(LayoutRect(paintOffset, m_layoutBox. size()));
563 LayoutObjectDrawingRecorder drawingRecorder(*paintInfo.context, m_layoutBox, paintInfo.phase, paintRect, paintOffset); 561 LayoutObjectDrawingRecorder drawingRecorder(paintInfo.context, m_layoutBox, paintInfo.phase, paintRect, paintOffset);
564 paintInfo.context->fillRect(paintRect, Color::black); 562 paintInfo.context.fillRect(paintRect, Color::black);
565 } 563 }
566 564
567 InterpolationQuality BoxPainter::chooseInterpolationQuality(const LayoutObject& obj, GraphicsContext* context, Image* image, const void* layer, const LayoutSize & size) 565 InterpolationQuality BoxPainter::chooseInterpolationQuality(const LayoutObject& obj, Image* image, const void* layer, const LayoutSize& size)
568 { 566 {
569 return ImageQualityController::imageQualityController()->chooseInterpolation Quality(context, &obj, image, layer, size); 567 return ImageQualityController::imageQualityController()->chooseInterpolation Quality(obj, image, layer, size);
570 } 568 }
571 569
572 bool BoxPainter::paintNinePieceImage(const LayoutBoxModelObject& obj, GraphicsCo ntext* graphicsContext, const LayoutRect& rect, const ComputedStyle& style, cons t NinePieceImage& ninePieceImage, SkXfermode::Mode op) 570 bool BoxPainter::paintNinePieceImage(const LayoutBoxModelObject& obj, GraphicsCo ntext& graphicsContext, const LayoutRect& rect, const ComputedStyle& style, cons t NinePieceImage& ninePieceImage, SkXfermode::Mode op)
573 { 571 {
574 NinePieceImagePainter ninePieceImagePainter(obj); 572 NinePieceImagePainter ninePieceImagePainter(obj);
575 return ninePieceImagePainter.paint(graphicsContext, rect, style, ninePieceIm age, op); 573 return ninePieceImagePainter.paint(graphicsContext, rect, style, ninePieceIm age, op);
576 } 574 }
577 575
578 void BoxPainter::paintBorder(const LayoutBoxModelObject& obj, const PaintInfo& i nfo, 576 void BoxPainter::paintBorder(const LayoutBoxModelObject& obj, const PaintInfo& i nfo,
579 const LayoutRect& rect, const ComputedStyle& style, BackgroundBleedAvoidance bleedAvoidance, 577 const LayoutRect& rect, const ComputedStyle& style, BackgroundBleedAvoidance bleedAvoidance,
580 bool includeLogicalLeftEdge, bool includeLogicalRightEdge) 578 bool includeLogicalLeftEdge, bool includeLogicalRightEdge)
581 { 579 {
582 // border-image is not affected by border-radius. 580 // border-image is not affected by border-radius.
583 if (paintNinePieceImage(obj, info.context, rect, style, style.borderImage()) ) 581 if (paintNinePieceImage(obj, info.context, rect, style, style.borderImage()) )
584 return; 582 return;
585 583
586 const BoxBorderPainter borderPainter(rect, style, bleedAvoidance, 584 const BoxBorderPainter borderPainter(rect, style, bleedAvoidance,
587 includeLogicalLeftEdge, includeLogicalRightEdge); 585 includeLogicalLeftEdge, includeLogicalRightEdge);
588 borderPainter.paintBorder(info, rect); 586 borderPainter.paintBorder(info, rect);
589 } 587 }
590 588
591 void BoxPainter::paintBoxShadow(const PaintInfo& info, const LayoutRect& paintRe ct, const ComputedStyle& style, ShadowStyle shadowStyle, bool includeLogicalLeft Edge, bool includeLogicalRightEdge) 589 void BoxPainter::paintBoxShadow(const PaintInfo& info, const LayoutRect& paintRe ct, const ComputedStyle& style, ShadowStyle shadowStyle, bool includeLogicalLeft Edge, bool includeLogicalRightEdge)
592 { 590 {
593 // FIXME: Deal with border-image. Would be great to use border-image as a ma sk. 591 // FIXME: Deal with border-image. Would be great to use border-image as a ma sk.
594 GraphicsContext* context = info.context; 592 GraphicsContext& context = info.context;
595 if (!style.boxShadow()) 593 if (!style.boxShadow())
596 return; 594 return;
597 FloatRoundedRect border = (shadowStyle == Inset) ? style.getRoundedInnerBord erFor(paintRect, includeLogicalLeftEdge, includeLogicalRightEdge) 595 FloatRoundedRect border = (shadowStyle == Inset) ? style.getRoundedInnerBord erFor(paintRect, includeLogicalLeftEdge, includeLogicalRightEdge)
598 : style.getRoundedBorderFor(paintRect, includeLogicalLeftEdge, includeLo gicalRightEdge); 596 : style.getRoundedBorderFor(paintRect, includeLogicalLeftEdge, includeLo gicalRightEdge);
599 597
600 bool hasBorderRadius = style.hasBorderRadius(); 598 bool hasBorderRadius = style.hasBorderRadius();
601 bool isHorizontal = style.isHorizontalWritingMode(); 599 bool isHorizontal = style.isHorizontalWritingMode();
602 bool hasOpaqueBackground = style.visitedDependentColor(CSSPropertyBackground Color).alpha() == 255; 600 bool hasOpaqueBackground = style.visitedDependentColor(CSSPropertyBackground Color).alpha() == 255;
603 601
604 GraphicsContextStateSaver stateSaver(*context, false); 602 GraphicsContextStateSaver stateSaver(context, false);
605 603
606 const ShadowList* shadowList = style.boxShadow(); 604 const ShadowList* shadowList = style.boxShadow();
607 for (size_t i = shadowList->shadows().size(); i--; ) { 605 for (size_t i = shadowList->shadows().size(); i--; ) {
608 const ShadowData& shadow = shadowList->shadows()[i]; 606 const ShadowData& shadow = shadowList->shadows()[i];
609 if (shadow.style() != shadowStyle) 607 if (shadow.style() != shadowStyle)
610 continue; 608 continue;
611 609
612 FloatSize shadowOffset(shadow.x(), shadow.y()); 610 FloatSize shadowOffset(shadow.x(), shadow.y());
613 float shadowBlur = shadow.blur(); 611 float shadowBlur = shadow.blur();
614 float shadowSpread = shadow.spread(); 612 float shadowSpread = shadow.spread();
(...skipping 20 matching lines...) Expand all
635 if (hasBorderRadius) { 633 if (hasBorderRadius) {
636 FloatRoundedRect rectToClipOut = border; 634 FloatRoundedRect rectToClipOut = border;
637 635
638 // If the box is opaque, it is unnecessary to clip it out. H owever, doing so saves time 636 // If the box is opaque, it is unnecessary to clip it out. H owever, doing so saves time
639 // when painting the shadow. On the other hand, it introduce s subpixel gaps along the 637 // when painting the shadow. On the other hand, it introduce s subpixel gaps along the
640 // corners. Those are avoided by insetting the clipping path by one CSS pixel. 638 // corners. Those are avoided by insetting the clipping path by one CSS pixel.
641 if (hasOpaqueBackground) 639 if (hasOpaqueBackground)
642 rectToClipOut.inflateWithRadii(-1); 640 rectToClipOut.inflateWithRadii(-1);
643 641
644 if (!rectToClipOut.isEmpty()) 642 if (!rectToClipOut.isEmpty())
645 context->clipOutRoundedRect(rectToClipOut); 643 context.clipOutRoundedRect(rectToClipOut);
646 } else { 644 } else {
647 // This IntRect is correct even with fractional shadows, bec ause it is used for the rectangle 645 // This IntRect is correct even with fractional shadows, bec ause it is used for the rectangle
648 // of the box itself, which is always pixel-aligned. 646 // of the box itself, which is always pixel-aligned.
649 FloatRect rectToClipOut = border.rect(); 647 FloatRect rectToClipOut = border.rect();
650 648
651 // If the box is opaque, it is unnecessary to clip it out. H owever, doing so saves time 649 // If the box is opaque, it is unnecessary to clip it out. H owever, doing so saves time
652 // when painting the shadow. On the other hand, it introduce s subpixel gaps along the 650 // when painting the shadow. On the other hand, it introduce s subpixel gaps along the
653 // edges if they are not pixel-aligned. Those are avoided by insetting the clipping path 651 // edges if they are not pixel-aligned. Those are avoided by insetting the clipping path
654 // by one CSS pixel. 652 // by one CSS pixel.
655 if (hasOpaqueBackground) 653 if (hasOpaqueBackground)
656 rectToClipOut.inflate(-1); 654 rectToClipOut.inflate(-1);
657 655
658 if (!rectToClipOut.isEmpty()) 656 if (!rectToClipOut.isEmpty())
659 context->clipOut(rectToClipOut); 657 context.clipOut(rectToClipOut);
660 } 658 }
661 } 659 }
662 660
663 // Draw only the shadow. 661 // Draw only the shadow.
664 context->setShadow(shadowOffset, shadowBlur, shadowColor, DrawLooper Builder::ShadowRespectsTransforms, DrawLooperBuilder::ShadowIgnoresAlpha, DrawSh adowOnly); 662 context.setShadow(shadowOffset, shadowBlur, shadowColor, DrawLooperB uilder::ShadowRespectsTransforms, DrawLooperBuilder::ShadowIgnoresAlpha, DrawSha dowOnly);
665 663
666 if (hasBorderRadius) { 664 if (hasBorderRadius) {
667 FloatRoundedRect influenceRect(pixelSnappedIntRect(LayoutRect(sh adowRect)), border.radii()); 665 FloatRoundedRect influenceRect(pixelSnappedIntRect(LayoutRect(sh adowRect)), border.radii());
668 float changeAmount = 2 * shadowBlur + shadowSpread; 666 float changeAmount = 2 * shadowBlur + shadowSpread;
669 if (changeAmount >= 0) 667 if (changeAmount >= 0)
670 influenceRect.expandRadii(changeAmount); 668 influenceRect.expandRadii(changeAmount);
671 else 669 else
672 influenceRect.shrinkRadii(-changeAmount); 670 influenceRect.shrinkRadii(-changeAmount);
673 671
674 FloatRoundedRect roundedFillRect = border; 672 FloatRoundedRect roundedFillRect = border;
675 roundedFillRect.inflate(shadowSpread); 673 roundedFillRect.inflate(shadowSpread);
676 674
677 if (shadowSpread >= 0) 675 if (shadowSpread >= 0)
678 roundedFillRect.expandRadii(shadowSpread); 676 roundedFillRect.expandRadii(shadowSpread);
679 else 677 else
680 roundedFillRect.shrinkRadii(-shadowSpread); 678 roundedFillRect.shrinkRadii(-shadowSpread);
681 if (!roundedFillRect.isRenderable()) 679 if (!roundedFillRect.isRenderable())
682 roundedFillRect.adjustRadii(); 680 roundedFillRect.adjustRadii();
683 roundedFillRect.constrainRadii(); 681 roundedFillRect.constrainRadii();
684 context->fillRoundedRect(roundedFillRect, Color::black); 682 context.fillRoundedRect(roundedFillRect, Color::black);
685 } else { 683 } else {
686 context->fillRect(fillRect, Color::black); 684 context.fillRect(fillRect, Color::black);
687 } 685 }
688 } else { 686 } else {
689 // The inset shadow case. 687 // The inset shadow case.
690 GraphicsContext::Edges clippedEdges = GraphicsContext::NoEdge; 688 GraphicsContext::Edges clippedEdges = GraphicsContext::NoEdge;
691 if (!includeLogicalLeftEdge) { 689 if (!includeLogicalLeftEdge) {
692 if (isHorizontal) 690 if (isHorizontal)
693 clippedEdges |= GraphicsContext::LeftEdge; 691 clippedEdges |= GraphicsContext::LeftEdge;
694 else 692 else
695 clippedEdges |= GraphicsContext::TopEdge; 693 clippedEdges |= GraphicsContext::TopEdge;
696 } 694 }
697 if (!includeLogicalRightEdge) { 695 if (!includeLogicalRightEdge) {
698 if (isHorizontal) 696 if (isHorizontal)
699 clippedEdges |= GraphicsContext::RightEdge; 697 clippedEdges |= GraphicsContext::RightEdge;
700 else 698 else
701 clippedEdges |= GraphicsContext::BottomEdge; 699 clippedEdges |= GraphicsContext::BottomEdge;
702 } 700 }
703 context->drawInnerShadow(border, shadowColor, shadowOffset, shadowBl ur, shadowSpread, clippedEdges); 701 context.drawInnerShadow(border, shadowColor, shadowOffset, shadowBlu r, shadowSpread, clippedEdges);
704 } 702 }
705 } 703 }
706 } 704 }
707 705
708 bool BoxPainter::shouldForceWhiteBackgroundForPrintEconomy(const ComputedStyle& style, const Document& document) 706 bool BoxPainter::shouldForceWhiteBackgroundForPrintEconomy(const ComputedStyle& style, const Document& document)
709 { 707 {
710 return document.printing() && style.printColorAdjust() == PrintColorAdjustEc onomy 708 return document.printing() && style.printColorAdjust() == PrintColorAdjustEc onomy
711 && (!document.settings() || !document.settings()->shouldPrintBackgrounds ()); 709 && (!document.settings() || !document.settings()->shouldPrintBackgrounds ());
712 } 710 }
713 711
714 } // namespace blink 712 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/paint/BoxPainter.h ('k') | third_party/WebKit/Source/core/paint/ClipScope.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698