Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "core/paint/BoxPainter.h" | 5 #include "core/paint/BoxPainter.h" |
| 6 | 6 |
| 7 #include "core/HTMLNames.h" | 7 #include "core/HTMLNames.h" |
| 8 #include "core/frame/Settings.h" | 8 #include "core/frame/Settings.h" |
| 9 #include "core/html/HTMLFrameOwnerElement.h" | 9 #include "core/html/HTMLFrameOwnerElement.h" |
| 10 #include "core/layout/ImageQualityController.h" | 10 #include "core/layout/ImageQualityController.h" |
| (...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 190 | 190 |
| 191 for (auto it = reversedPaintList.rbegin(); it != reversedPaintList.rend(); + +it) | 191 for (auto it = reversedPaintList.rbegin(); it != reversedPaintList.rend(); + +it) |
| 192 paintFillLayer(m_layoutBox, paintInfo, c, **it, rect, bleedAvoidance, 0, LayoutSize(), op, backgroundObject); | 192 paintFillLayer(m_layoutBox, paintInfo, c, **it, rect, bleedAvoidance, 0, LayoutSize(), op, backgroundObject); |
| 193 | 193 |
| 194 if (shouldDrawBackgroundInSeparateBuffer) | 194 if (shouldDrawBackgroundInSeparateBuffer) |
| 195 context.endLayer(); | 195 context.endLayer(); |
| 196 } | 196 } |
| 197 | 197 |
| 198 namespace { | 198 namespace { |
| 199 | 199 |
| 200 void applyBoxShadowForBackground(GraphicsContext& context, const LayoutObject& o bj) | 200 // RAII shadow helper. |
| 201 { | 201 class ShadowContext { |
| 202 const ShadowList* shadowList = obj.style()->boxShadow(); | 202 STACK_ALLOCATED(); |
| 203 ASSERT(shadowList); | 203 public: |
| 204 for (size_t i = shadowList->shadows().size(); i--; ) { | 204 ShadowContext(GraphicsContext& context, const LayoutObject& obj, bool applyS hadow) |
| 205 const ShadowData& boxShadow = shadowList->shadows()[i]; | 205 : m_saver(context, applyShadow) |
| 206 if (boxShadow.style() != Normal) | 206 { |
| 207 continue; | 207 if (!applyShadow) |
| 208 FloatSize shadowOffset(boxShadow.x(), boxShadow.y()); | 208 return; |
| 209 context.setShadow(shadowOffset, boxShadow.blur(), | 209 |
| 210 boxShadow.color().resolve(obj.resolveColor(CSSPropertyColor)), | 210 const ShadowList* shadowList = obj.style()->boxShadow(); |
| 211 DrawLooperBuilder::ShadowRespectsTransforms, DrawLooperBuilder::Shad owIgnoresAlpha); | 211 DCHECK(shadowList); |
| 212 return; | 212 for (size_t i = shadowList->shadows().size(); i--; ) { |
| 213 const ShadowData& boxShadow = shadowList->shadows()[i]; | |
| 214 if (boxShadow.style() != Normal) | |
| 215 continue; | |
| 216 FloatSize shadowOffset(boxShadow.x(), boxShadow.y()); | |
| 217 context.setShadow(shadowOffset, boxShadow.blur(), | |
| 218 boxShadow.color().resolve(obj.resolveColor(CSSPropertyColor)), | |
| 219 DrawLooperBuilder::ShadowRespectsTransforms, DrawLooperBuilder:: ShadowIgnoresAlpha); | |
| 220 break; | |
| 221 } | |
| 213 } | 222 } |
| 214 } | 223 |
| 224 private: | |
| 225 GraphicsContextStateSaver m_saver; | |
| 226 }; | |
| 215 | 227 |
| 216 FloatRoundedRect getBackgroundRoundedRect(const LayoutObject& obj, const LayoutR ect& borderRect, | 228 FloatRoundedRect getBackgroundRoundedRect(const LayoutObject& obj, const LayoutR ect& borderRect, |
| 217 const InlineFlowBox* box, LayoutUnit inlineBoxWidth, LayoutUnit inlineBoxHei ght, | 229 const InlineFlowBox* box, LayoutUnit inlineBoxWidth, LayoutUnit inlineBoxHei ght, |
| 218 bool includeLogicalLeftEdge, bool includeLogicalRightEdge) | 230 bool includeLogicalLeftEdge, bool includeLogicalRightEdge) |
| 219 { | 231 { |
| 220 FloatRoundedRect border = obj.style()->getRoundedBorderFor(borderRect, inclu deLogicalLeftEdge, includeLogicalRightEdge); | 232 FloatRoundedRect border = obj.style()->getRoundedBorderFor(borderRect, inclu deLogicalLeftEdge, includeLogicalRightEdge); |
| 221 if (box && (box->nextLineBox() || box->prevLineBox())) { | 233 if (box && (box->nextLineBox() || box->prevLineBox())) { |
| 222 FloatRoundedRect segmentBorder = obj.style()->getRoundedBorderFor(Layout Rect(0, 0, inlineBoxWidth, inlineBoxHeight), | 234 FloatRoundedRect segmentBorder = obj.style()->getRoundedBorderFor(Layout Rect(0, 0, inlineBoxWidth, inlineBoxHeight), |
| 223 includeLogicalLeftEdge, includeLogicalRightEdge); | 235 includeLogicalLeftEdge, includeLogicalRightEdge); |
| 224 border.setRadii(segmentBorder.getRadii()); | 236 border.setRadii(segmentBorder.getRadii()); |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 314 bool isBottomLayer; | 326 bool isBottomLayer; |
| 315 bool isBorderFill; | 327 bool isBorderFill; |
| 316 bool isClippedWithLocalScrolling; | 328 bool isClippedWithLocalScrolling; |
| 317 bool isRoundedFill; | 329 bool isRoundedFill; |
| 318 | 330 |
| 319 bool shouldPaintImage; | 331 bool shouldPaintImage; |
| 320 bool shouldPaintColor; | 332 bool shouldPaintColor; |
| 321 bool shouldPaintShadow; | 333 bool shouldPaintShadow; |
| 322 }; | 334 }; |
| 323 | 335 |
| 336 // RAII image paint helper. | |
| 337 class ImagePaintContext { | |
| 338 STACK_ALLOCATED(); | |
| 339 public: | |
| 340 ImagePaintContext(const LayoutBoxModelObject& obj, GraphicsContext& context, | |
| 341 const FillLayer& layer, const StyleImage& styleImage, SkXfermode::Mode o p, | |
| 342 const LayoutObject* backgroundObject, const LayoutSize& containerSize) | |
| 343 : m_context(context) | |
| 344 , m_previousInterpolationQuality(context.imageInterpolationQuality()) | |
| 345 { | |
| 346 SkXfermode::Mode bgOp = WebCoreCompositeToSkiaComposite(layer.composite( ), layer.blendMode()); | |
| 347 // if op != SkXfermode::kSrcOver_Mode, a mask is being painted. | |
| 348 m_compositeOp = (op == SkXfermode::kSrcOver_Mode) ? bgOp : op; | |
| 349 | |
| 350 const LayoutObject& imageClient = backgroundObject ? *backgroundObject : obj; | |
| 351 m_image = styleImage.image(imageClient, flooredIntSize(containerSize), o bj.style()->effectiveZoom()); | |
| 352 | |
| 353 m_interpolationQuality = | |
| 354 BoxPainter::chooseInterpolationQuality(imageClient, m_image.get(), & layer, containerSize); | |
| 355 if (m_interpolationQuality != m_previousInterpolationQuality) | |
| 356 context.setImageInterpolationQuality(m_interpolationQuality); | |
| 357 | |
| 358 if (layer.maskSourceType() == MaskLuminance) | |
| 359 context.setColorFilter(ColorFilterLuminanceToAlpha); | |
| 360 } | |
| 361 | |
| 362 ~ImagePaintContext() | |
| 363 { | |
| 364 if (m_interpolationQuality != m_previousInterpolationQuality) | |
| 365 m_context.setImageInterpolationQuality(m_previousInterpolationQualit y); | |
| 366 } | |
| 367 | |
| 368 Image* image() const { return m_image.get(); } | |
| 369 | |
| 370 SkXfermode::Mode compositeOp() const { return m_compositeOp; } | |
| 371 | |
| 372 private: | |
| 373 RefPtr<Image> m_image; | |
| 374 GraphicsContext& m_context; | |
| 375 SkXfermode::Mode m_compositeOp; | |
| 376 InterpolationQuality m_interpolationQuality; | |
| 377 InterpolationQuality m_previousInterpolationQuality; | |
| 378 }; | |
| 379 | |
| 324 inline bool paintFastBottomLayer(const LayoutBoxModelObject& obj, const PaintInf o& paintInfo, | 380 inline bool paintFastBottomLayer(const LayoutBoxModelObject& obj, const PaintInf o& paintInfo, |
| 325 const FillLayerInfo& info, const LayoutRect& rect, BackgroundBleedAvoidance bleedAvoidance, | 381 const FillLayerInfo& info, const FillLayer& layer, const LayoutRect& rect, |
| 326 const InlineFlowBox* box, const LayoutSize& boxSize) | 382 BackgroundBleedAvoidance bleedAvoidance, const InlineFlowBox* box, const Lay outSize& boxSize, |
| 383 SkXfermode::Mode op, const LayoutObject* backgroundObject, | |
| 384 Optional<BackgroundImageGeometry>& geometry) | |
| 327 { | 385 { |
| 328 // Complex cases not handled on the fast path. | 386 // Complex cases not handled on the fast path. |
| 329 if (!info.isBottomLayer || !info.isBorderFill || info.isClippedWithLocalScro lling) | 387 if (!info.isBottomLayer || !info.isBorderFill || info.isClippedWithLocalScro lling) |
| 330 return false; | 388 return false; |
| 331 | 389 |
| 332 // Not yet. | |
| 333 if (info.image) | |
| 334 return false; | |
| 335 | |
| 336 // Transparent layer, nothing to paint. | 390 // Transparent layer, nothing to paint. |
| 337 if (!info.shouldPaintColor) | 391 if (!info.shouldPaintColor && !info.shouldPaintImage) |
| 338 return true; | 392 return true; |
| 339 | 393 |
| 394 // When the layer has an image, figure whether it is covered by a single til e. | |
|
fs
2016/05/20 12:47:35
Nit: figure out
f(malita)
2016/05/20 13:57:57
Done.
| |
| 395 FloatRect imageTile; | |
| 396 if (info.shouldPaintImage) { | |
| 397 DCHECK(!geometry); | |
| 398 geometry.emplace(); | |
| 399 geometry->calculate(obj, paintInfo.paintContainer(), paintInfo.getGlobal PaintFlags(), layer, rect); | |
| 400 | |
| 401 if (!geometry->destRect().isEmpty()) { | |
| 402 // The tile is too small. | |
| 403 if (geometry->tileSize().width() < rect.width() || geometry->tileSiz e().height() < rect.height()) | |
| 404 return false; | |
| 405 | |
| 406 const FloatRect destRect(geometry->destRect()); | |
| 407 const FloatPoint srcPoint(geometry->phase()); | |
| 408 | |
| 409 // This duplicates Image::drawTiled() logic. | |
| 410 // TODO(fmalita): find a way to share? | |
| 411 const FloatSize actualTileSize(geometry->tileSize() + geometry->spac eSize()); | |
| 412 imageTile.setLocation(FloatPoint( | |
| 413 destRect.x() + fmodf(fmodf(-srcPoint.x(), actualTileSize.width() ) - actualTileSize.width(), actualTileSize.width()), | |
| 414 destRect.y() + fmodf(fmodf(-srcPoint.y(), actualTileSize.height( )) - actualTileSize.height(), actualTileSize.height()) | |
| 415 )); | |
| 416 imageTile.setSize(FloatSize(geometry->tileSize())); | |
| 417 | |
| 418 // The tile is misaligned. | |
| 419 if (!imageTile.contains(FloatRect(rect))) | |
| 420 return false; | |
| 421 } | |
| 422 } | |
| 423 | |
| 424 // At this point we're committed to the fast path: the destination (r)rect f its within a single | |
| 425 // tile, and we can paint it using direct draw(R)Rect() calls. | |
| 340 GraphicsContext& context = paintInfo.context; | 426 GraphicsContext& context = paintInfo.context; |
| 341 GraphicsContextStateSaver shadowStateSaver(context, info.shouldPaintShadow); | 427 FloatRoundedRect border = info.isRoundedFill |
| 342 if (info.shouldPaintShadow) | 428 ? backgroundRoundedRectAdjustedForBleedAvoidance(obj, rect, bleedAvoidan ce, box, boxSize, info.includeLeftEdge, info.includeRightEdge) |
| 343 applyBoxShadowForBackground(context, obj); | 429 : FloatRoundedRect(pixelSnappedIntRect(rect)); |
| 344 | 430 |
| 345 if (info.isRoundedFill) { | 431 Optional<RoundedInnerRectClipper> clipper; |
| 346 FloatRoundedRect border = backgroundRoundedRectAdjustedForBleedAvoidance (obj, rect, | 432 if (info.isRoundedFill && !border.isRenderable()) { |
| 347 bleedAvoidance, box, boxSize, info.includeLeftEdge, info.includeRigh tEdge); | 433 // When the rrect is not renderable, we resort to clipping. |
| 434 // RoundedInnerRectClipper handles this case via discrete, corner-wise c lipping. | |
| 435 clipper.emplace(obj, paintInfo, rect, border, ApplyToContext); | |
| 436 border.setRadii(FloatRoundedRect::Radii()); | |
| 437 } | |
| 348 | 438 |
| 349 if (border.isRenderable()) { | 439 // Paint the color + shadow if needed. |
| 350 context.fillRoundedRect(border, info.color); | 440 if (info.shouldPaintColor) { |
| 351 } else { | 441 const ShadowContext shadowContext(context, obj, info.shouldPaintShadow); |
| 352 RoundedInnerRectClipper clipper(obj, paintInfo, rect, border, ApplyT oContext); | 442 context.fillRoundedRect(border, info.color); |
| 353 context.fillRect(border.rect(), info.color); | |
| 354 } | |
| 355 } else { | |
| 356 context.fillRect(pixelSnappedIntRect(rect), info.color); | |
| 357 } | 443 } |
| 358 | 444 |
| 445 // Paint the image + shadow if needed. | |
| 446 if (!info.shouldPaintImage || imageTile.isEmpty()) | |
| 447 return true; | |
| 448 | |
| 449 const ImagePaintContext imageContext(obj, context, layer, *info.image, op, b ackgroundObject, | |
| 450 geometry->tileSize()); | |
| 451 if (!imageContext.image()) | |
| 452 return true; | |
| 453 | |
| 454 // Compute the image src rect (tile subset) which gets mapped onto the dest/ border rect. | |
| 455 // TODO(fmalita): share with Image::drawTiled()? | |
| 456 const FloatSize intrinsicTileSize = imageContext.image()->hasRelativeSize() | |
| 457 ? imageTile.size() | |
| 458 : FloatSize(imageContext.image()->size()); | |
| 459 const FloatSize tileScale( | |
| 460 intrinsicTileSize.width() / imageTile.width(), | |
| 461 intrinsicTileSize.height() / imageTile.height()); | |
| 462 FloatRect srcRect = border.rect(); | |
| 463 srcRect.moveBy(-imageTile.location()); | |
| 464 srcRect.scale(tileScale.width(), tileScale.height()); | |
| 465 | |
| 466 // The shadow may have been applied with the color fill. | |
| 467 const ShadowContext shadowContext(context, obj, info.shouldPaintShadow && !i nfo.shouldPaintColor); | |
| 468 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "PaintImage", " data", | |
| 469 InspectorPaintImageEvent::data(obj, *info.image)); | |
| 470 context.drawImageRRect(imageContext.image(), border, &srcRect, imageContext. compositeOp()); | |
| 471 | |
| 359 return true; | 472 return true; |
| 360 } | 473 } |
| 361 | 474 |
| 362 } // anonymous namespace | 475 } // anonymous namespace |
| 363 | 476 |
| 364 void BoxPainter::paintFillLayer(const LayoutBoxModelObject& obj, const PaintInfo & paintInfo, const Color& color, const FillLayer& bgLayer, const LayoutRect& rec t, BackgroundBleedAvoidance bleedAvoidance, const InlineFlowBox* box, const Layo utSize& boxSize, SkXfermode::Mode op, const LayoutObject* backgroundObject) | 477 void BoxPainter::paintFillLayer(const LayoutBoxModelObject& obj, const PaintInfo & paintInfo, const Color& color, const FillLayer& bgLayer, const LayoutRect& rec t, BackgroundBleedAvoidance bleedAvoidance, const InlineFlowBox* box, const Layo utSize& boxSize, SkXfermode::Mode op, const LayoutObject* backgroundObject) |
| 365 { | 478 { |
| 366 GraphicsContext& context = paintInfo.context; | 479 GraphicsContext& context = paintInfo.context; |
| 367 if (rect.isEmpty()) | 480 if (rect.isEmpty()) |
| 368 return; | 481 return; |
| 369 | 482 |
| 370 const FillLayerInfo info(obj, color, bgLayer, bleedAvoidance, box); | 483 const FillLayerInfo info(obj, color, bgLayer, bleedAvoidance, box); |
| 484 Optional<BackgroundImageGeometry> geometry; | |
| 371 | 485 |
| 372 // Fast path for drawing simple color backgrounds. | 486 // Fast path for drawing simple color backgrounds. |
| 373 if (paintFastBottomLayer(obj, paintInfo, info, rect, bleedAvoidance, box, bo xSize)) | 487 if (paintFastBottomLayer(obj, paintInfo, info, bgLayer, rect, bleedAvoidance , box, boxSize, op, |
| 488 backgroundObject, geometry)) { | |
| 374 return; | 489 return; |
| 490 } | |
| 375 | 491 |
| 376 Optional<RoundedInnerRectClipper> clipToBorder; | 492 Optional<RoundedInnerRectClipper> clipToBorder; |
| 377 if (info.isRoundedFill) { | 493 if (info.isRoundedFill) { |
| 378 FloatRoundedRect border = info.isBorderFill | 494 FloatRoundedRect border = info.isBorderFill |
| 379 ? backgroundRoundedRectAdjustedForBleedAvoidance(obj, rect, bleedAvo idance, box, boxSize, info.includeLeftEdge, info.includeRightEdge) | 495 ? backgroundRoundedRectAdjustedForBleedAvoidance(obj, rect, bleedAvo idance, box, boxSize, info.includeLeftEdge, info.includeRightEdge) |
| 380 : getBackgroundRoundedRect(obj, rect, box, boxSize.width(), boxSize. height(), info.includeLeftEdge, info.includeRightEdge); | 496 : getBackgroundRoundedRect(obj, rect, box, boxSize.width(), boxSize. height(), info.includeLeftEdge, info.includeRightEdge); |
| 381 | 497 |
| 382 // Clip to the padding or content boxes as necessary. | 498 // Clip to the padding or content boxes as necessary. |
| 383 if (bgLayer.clip() == ContentFillBox) { | 499 if (bgLayer.clip() == ContentFillBox) { |
| 384 border = obj.style()->getRoundedInnerBorderFor(LayoutRect(border.rec t()), | 500 border = obj.style()->getRoundedInnerBorderFor(LayoutRect(border.rec t()), |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 455 ASSERT_NOT_REACHED(); | 571 ASSERT_NOT_REACHED(); |
| 456 break; | 572 break; |
| 457 } | 573 } |
| 458 | 574 |
| 459 // Paint the color first underneath all images, culled if background image o ccludes it. | 575 // Paint the color first underneath all images, culled if background image o ccludes it. |
| 460 // TODO(trchen): In the !bgLayer.hasRepeatXY() case, we could improve the cu lling test | 576 // TODO(trchen): In the !bgLayer.hasRepeatXY() case, we could improve the cu lling test |
| 461 // by verifying whether the background image covers the entire painting area . | 577 // by verifying whether the background image covers the entire painting area . |
| 462 if (info.isBottomLayer && info.color.alpha()) { | 578 if (info.isBottomLayer && info.color.alpha()) { |
| 463 IntRect backgroundRect(pixelSnappedIntRect(scrolledPaintRect)); | 579 IntRect backgroundRect(pixelSnappedIntRect(scrolledPaintRect)); |
| 464 if (info.shouldPaintColor || info.shouldPaintShadow) { | 580 if (info.shouldPaintColor || info.shouldPaintShadow) { |
| 465 GraphicsContextStateSaver shadowStateSaver(context, info.shouldPaint Shadow); | 581 const ShadowContext shadowContext(context, obj, info.shouldPaintShad ow); |
| 466 if (info.shouldPaintShadow) | |
| 467 applyBoxShadowForBackground(context, obj); | |
| 468 | |
| 469 context.fillRect(backgroundRect, info.color); | 582 context.fillRect(backgroundRect, info.color); |
| 470 } | 583 } |
| 471 } | 584 } |
| 472 | 585 |
| 473 // no progressive loading of the background image | 586 // no progressive loading of the background image |
| 474 if (info.shouldPaintImage) { | 587 if (info.shouldPaintImage) { |
| 475 BackgroundImageGeometry geometry; | 588 if (!geometry) { |
| 476 geometry.calculate(obj, paintInfo.paintContainer(), paintInfo.getGlobalP aintFlags(), bgLayer, scrolledPaintRect); | 589 geometry.emplace(); |
| 590 geometry->calculate(obj, paintInfo.paintContainer(), paintInfo.getGl obalPaintFlags(), bgLayer, scrolledPaintRect); | |
| 591 } else { | |
| 592 // The geometry was calculated in paintFastBottomLayer(). | |
| 593 DCHECK(info.isBottomLayer && info.isBorderFill && !info.isClippedWit hLocalScrolling); | |
| 594 } | |
| 477 | 595 |
| 478 if (!geometry.destRect().isEmpty()) { | 596 if (!geometry->destRect().isEmpty()) { |
| 479 SkXfermode::Mode bgOp = WebCoreCompositeToSkiaComposite(bgLayer.comp osite(), bgLayer.blendMode()); | 597 const ImagePaintContext imageContext(obj, context, bgLayer, *info.im age, op, |
| 480 // if op != SkXfermode::kSrcOver_Mode, a mask is being painted. | 598 backgroundObject, geometry->tileSize()); |
| 481 SkXfermode::Mode compositeOp = op == SkXfermode::kSrcOver_Mode ? bgO p : op; | 599 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "PaintI mage", "data", |
| 482 const LayoutObject& clientForBackgroundImage = backgroundObject ? *b ackgroundObject : obj; | 600 InspectorPaintImageEvent::data(obj, *info.image)); |
| 483 RefPtr<Image> image = info.image->image(clientForBackgroundImage, fl ooredIntSize(geometry.tileSize()), obj.style()->effectiveZoom()); | 601 context.drawTiledImage(imageContext.image(), FloatRect(geometry->des tRect()), |
| 484 InterpolationQuality interpolationQuality = chooseInterpolationQuali ty(clientForBackgroundImage, image.get(), &bgLayer, LayoutSize(geometry.tileSize ())); | 602 FloatPoint(geometry->phase()), FloatSize(geometry->tileSize()), |
| 485 if (bgLayer.maskSourceType() == MaskLuminance) | 603 imageContext.compositeOp(), FloatSize(geometry->spaceSize())); |
| 486 context.setColorFilter(ColorFilterLuminanceToAlpha); | |
| 487 InterpolationQuality previousInterpolationQuality = context.imageInt erpolationQuality(); | |
| 488 context.setImageInterpolationQuality(interpolationQuality); | |
| 489 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "PaintI mage", "data", InspectorPaintImageEvent::data(obj, *info.image)); | |
| 490 context.drawTiledImage(image.get(), FloatRect(geometry.destRect()), FloatPoint(geometry.phase()), FloatSize(geometry.tileSize()), | |
| 491 compositeOp, FloatSize(geometry.spaceSize())); | |
| 492 context.setImageInterpolationQuality(previousInterpolationQuality); | |
| 493 } | 604 } |
| 494 } | 605 } |
| 495 | 606 |
| 496 if (bgLayer.clip() == TextFillBox) { | 607 if (bgLayer.clip() == TextFillBox) { |
| 497 // Create the text mask layer. | 608 // Create the text mask layer. |
| 498 context.beginLayer(1, SkXfermode::kDstIn_Mode); | 609 context.beginLayer(1, SkXfermode::kDstIn_Mode); |
| 499 | 610 |
| 500 // Now draw the text into the mask. We do this by painting using a speci al paint phase that signals to | 611 // Now draw the text into the mask. We do this by painting using a speci al paint phase that signals to |
| 501 // InlineTextBoxes that they should just add their contents to the clip. | 612 // InlineTextBoxes that they should just add their contents to the clip. |
| 502 PaintInfo info(context, maskRect, PaintPhaseTextClip, GlobalPaintNormalP hase, 0); | 613 PaintInfo info(context, maskRect, PaintPhaseTextClip, GlobalPaintNormalP hase, 0); |
| (...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 721 } | 832 } |
| 722 } | 833 } |
| 723 | 834 |
| 724 bool BoxPainter::shouldForceWhiteBackgroundForPrintEconomy(const ComputedStyle& style, const Document& document) | 835 bool BoxPainter::shouldForceWhiteBackgroundForPrintEconomy(const ComputedStyle& style, const Document& document) |
| 725 { | 836 { |
| 726 return document.printing() && style.getPrintColorAdjust() == PrintColorAdjus tEconomy | 837 return document.printing() && style.getPrintColorAdjust() == PrintColorAdjus tEconomy |
| 727 && (!document.settings() || !document.settings()->shouldPrintBackgrounds ()); | 838 && (!document.settings() || !document.settings()->shouldPrintBackgrounds ()); |
| 728 } | 839 } |
| 729 | 840 |
| 730 } // namespace blink | 841 } // namespace blink |
| OLD | NEW |