| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) | 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) |
| 3 * (C) 1999 Antti Koivisto (koivisto@kde.org) | 3 * (C) 1999 Antti Koivisto (koivisto@kde.org) |
| 4 * (C) 2005 Allan Sandfeld Jensen (kde@carewolf.com) | 4 * (C) 2005 Allan Sandfeld Jensen (kde@carewolf.com) |
| 5 * (C) 2005, 2006 Samuel Weinig (sam.weinig@gmail.com) | 5 * (C) 2005, 2006 Samuel Weinig (sam.weinig@gmail.com) |
| 6 * Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. | 6 * Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. |
| 7 * Copyright (C) 2010 Google Inc. All rights reserved. | 7 * Copyright (C) 2010 Google Inc. All rights reserved. |
| 8 * | 8 * |
| 9 * This library is free software; you can redistribute it and/or | 9 * This library is free software; you can redistribute it and/or |
| 10 * modify it under the terms of the GNU Library General Public | 10 * modify it under the terms of the GNU Library General Public |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 112 if (cb->isRenderView()) | 112 if (cb->isRenderView()) |
| 113 return false; | 113 return false; |
| 114 | 114 |
| 115 if (cb->isOutOfFlowPositioned() && !cb->style()->logicalTop().isAuto() && !c
b->style()->logicalBottom().isAuto()) | 115 if (cb->isOutOfFlowPositioned() && !cb->style()->logicalTop().isAuto() && !c
b->style()->logicalBottom().isAuto()) |
| 116 return false; | 116 return false; |
| 117 | 117 |
| 118 // If the height of the containing block computes to 'auto', then it hasn't
been 'specified explicitly'. | 118 // If the height of the containing block computes to 'auto', then it hasn't
been 'specified explicitly'. |
| 119 return cb->hasAutoHeightOrContainingBlockWithAutoHeight(); | 119 return cb->hasAutoHeightOrContainingBlockWithAutoHeight(); |
| 120 } | 120 } |
| 121 | 121 |
| 122 bool RenderBoxModelObject::isDocumentElementWithOpaqueBackground() const | |
| 123 { | |
| 124 if (!isDocumentElement()) | |
| 125 return false; | |
| 126 | |
| 127 // The background is opaque only if we're the root document, since iframes w
ith | |
| 128 // no background in the child document should show the parent's background. | |
| 129 // FIXME(sky): This used to check the <body> element and is now probably wro
ng. | |
| 130 if (view()->frameView()) | |
| 131 return !view()->frameView()->isTransparent(); | |
| 132 | |
| 133 return true; | |
| 134 } | |
| 135 | |
| 136 void RenderBoxModelObject::paintRootBackgroundColor(const PaintInfo& paintInfo,
const LayoutRect& rect, const Color& bgColor) | |
| 137 { | |
| 138 GraphicsContext* context = paintInfo.context; | |
| 139 if (rect.isEmpty()) | |
| 140 return; | |
| 141 | |
| 142 ASSERT(isDocumentElement()); | |
| 143 | |
| 144 IntRect backgroundRect(pixelSnappedIntRect(rect)); | |
| 145 backgroundRect.intersect(paintInfo.rect); | |
| 146 | |
| 147 Color baseColor = view()->frameView()->baseBackgroundColor(); | |
| 148 bool shouldClearDocumentBackground = document().settings() && document().set
tings()->shouldClearDocumentBackground(); | |
| 149 CompositeOperator operation = shouldClearDocumentBackground ? CompositeCopy
: context->compositeOperation(); | |
| 150 | |
| 151 // If we have an alpha go ahead and blend with the base background color. | |
| 152 if (baseColor.alpha()) { | |
| 153 if (bgColor.alpha()) | |
| 154 baseColor = baseColor.blend(bgColor); | |
| 155 context->fillRect(backgroundRect, baseColor, operation); | |
| 156 } else if (bgColor.alpha()) { | |
| 157 context->fillRect(backgroundRect, bgColor, operation); | |
| 158 } else if (shouldClearDocumentBackground) { | |
| 159 context->clearRect(backgroundRect); | |
| 160 } | |
| 161 } | |
| 162 | |
| 163 LayoutSize RenderBoxModelObject::relativePositionOffset() const | 122 LayoutSize RenderBoxModelObject::relativePositionOffset() const |
| 164 { | 123 { |
| 165 LayoutSize offset; | 124 LayoutSize offset; |
| 166 | 125 |
| 167 RenderBlock* containingBlock = this->containingBlock(); | 126 RenderBlock* containingBlock = this->containingBlock(); |
| 168 | 127 |
| 169 // Objects that shrink to avoid floats normally use available line width whe
n computing containing block width. However | 128 // Objects that shrink to avoid floats normally use available line width whe
n computing containing block width. However |
| 170 // in the case of relative positioning using percentages, we can't do this.
The offset should always be resolved using the | 129 // in the case of relative positioning using percentages, we can't do this.
The offset should always be resolved using the |
| 171 // available width of the containing block. Therefore we don't use containi
ngBlockLogicalWidthForContent() here, but instead explicitly | 130 // available width of the containing block. Therefore we don't use containi
ngBlockLogicalWidthForContent() here, but instead explicitly |
| 172 // call availableWidth on our containing block. | 131 // call availableWidth on our containing block. |
| (...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 364 GraphicsContext* context = paintInfo.context; | 323 GraphicsContext* context = paintInfo.context; |
| 365 if (rect.isEmpty()) | 324 if (rect.isEmpty()) |
| 366 return; | 325 return; |
| 367 | 326 |
| 368 bool includeLeftEdge = box ? box->includeLogicalLeftEdge() : true; | 327 bool includeLeftEdge = box ? box->includeLogicalLeftEdge() : true; |
| 369 bool includeRightEdge = box ? box->includeLogicalRightEdge() : true; | 328 bool includeRightEdge = box ? box->includeLogicalRightEdge() : true; |
| 370 | 329 |
| 371 bool hasRoundedBorder = style()->hasBorderRadius() && (includeLeftEdge || in
cludeRightEdge); | 330 bool hasRoundedBorder = style()->hasBorderRadius() && (includeLeftEdge || in
cludeRightEdge); |
| 372 bool clippedWithLocalScrolling = hasOverflowClip() && bgLayer.attachment() =
= LocalBackgroundAttachment; | 331 bool clippedWithLocalScrolling = hasOverflowClip() && bgLayer.attachment() =
= LocalBackgroundAttachment; |
| 373 bool isBorderFill = bgLayer.clip() == BorderFillBox; | 332 bool isBorderFill = bgLayer.clip() == BorderFillBox; |
| 374 bool isDocumentElementRenderer = this->isDocumentElement(); | |
| 375 bool isBottomLayer = !bgLayer.next(); | 333 bool isBottomLayer = !bgLayer.next(); |
| 376 | 334 |
| 377 Color bgColor = color; | 335 Color bgColor = color; |
| 378 StyleImage* bgImage = bgLayer.image(); | 336 StyleImage* bgImage = bgLayer.image(); |
| 379 bool shouldPaintBackgroundImage = bgImage && bgImage->canRender(*this); | 337 bool shouldPaintBackgroundImage = bgImage && bgImage->canRender(*this); |
| 380 | 338 |
| 381 bool colorVisible = bgColor.alpha(); | 339 bool colorVisible = bgColor.alpha(); |
| 382 | 340 |
| 383 // Fast path for drawing simple color backgrounds. | 341 // Fast path for drawing simple color backgrounds. |
| 384 if (!isDocumentElementRenderer && !clippedWithLocalScrolling && !shouldPaint
BackgroundImage && isBorderFill && isBottomLayer) { | 342 if (!clippedWithLocalScrolling && !shouldPaintBackgroundImage && isBorderFil
l && isBottomLayer) { |
| 385 if (!colorVisible) | 343 if (!colorVisible) |
| 386 return; | 344 return; |
| 387 | 345 |
| 388 bool boxShadowShouldBeAppliedToBackground = this->boxShadowShouldBeAppli
edToBackground(bleedAvoidance, box); | 346 bool boxShadowShouldBeAppliedToBackground = this->boxShadowShouldBeAppli
edToBackground(bleedAvoidance, box); |
| 389 GraphicsContextStateSaver shadowStateSaver(*context, boxShadowShouldBeAp
pliedToBackground); | 347 GraphicsContextStateSaver shadowStateSaver(*context, boxShadowShouldBeAp
pliedToBackground); |
| 390 if (boxShadowShouldBeAppliedToBackground) | 348 if (boxShadowShouldBeAppliedToBackground) |
| 391 applyBoxShadowForBackground(context, this); | 349 applyBoxShadowForBackground(context, this); |
| 392 | 350 |
| 393 if (hasRoundedBorder && bleedAvoidance != BackgroundBleedClipBackground)
{ | 351 if (hasRoundedBorder && bleedAvoidance != BackgroundBleedClipBackground)
{ |
| 394 RoundedRect border = backgroundRoundedRectAdjustedForBleedAvoidance(
context, rect, bleedAvoidance, box, boxSize, includeLeftEdge, includeRightEdge); | 352 RoundedRect border = backgroundRoundedRectAdjustedForBleedAvoidance(
context, rect, bleedAvoidance, box, boxSize, includeLeftEdge, includeRightEdge); |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 465 ASSERT_NOT_REACHED(); | 423 ASSERT_NOT_REACHED(); |
| 466 break; | 424 break; |
| 467 } | 425 } |
| 468 | 426 |
| 469 // Paint the color first underneath all images, culled if background image o
ccludes it. | 427 // Paint the color first underneath all images, culled if background image o
ccludes it. |
| 470 // FIXME: In the bgLayer->hasFiniteBounds() case, we could improve the culli
ng test | 428 // FIXME: In the bgLayer->hasFiniteBounds() case, we could improve the culli
ng test |
| 471 // by verifying whether the background image covers the entire layout rect. | 429 // by verifying whether the background image covers the entire layout rect. |
| 472 if (isBottomLayer) { | 430 if (isBottomLayer) { |
| 473 IntRect backgroundRect(pixelSnappedIntRect(scrolledPaintRect)); | 431 IntRect backgroundRect(pixelSnappedIntRect(scrolledPaintRect)); |
| 474 bool boxShadowShouldBeAppliedToBackground = this->boxShadowShouldBeAppli
edToBackground(bleedAvoidance, box); | 432 bool boxShadowShouldBeAppliedToBackground = this->boxShadowShouldBeAppli
edToBackground(bleedAvoidance, box); |
| 475 bool isOpaqueRoot = (isDocumentElementRenderer && !bgColor.hasAlpha()) |
| isDocumentElementWithOpaqueBackground(); | 433 if (boxShadowShouldBeAppliedToBackground || !shouldPaintBackgroundImage
|| !bgLayer.hasOpaqueImage(this) || !bgLayer.hasRepeatXY()) { |
| 476 if (boxShadowShouldBeAppliedToBackground || !shouldPaintBackgroundImage
|| !bgLayer.hasOpaqueImage(this) || !bgLayer.hasRepeatXY() || (isOpaqueRoot && !
toRenderBox(this)->height())) { | |
| 477 if (!boxShadowShouldBeAppliedToBackground) | 434 if (!boxShadowShouldBeAppliedToBackground) |
| 478 backgroundRect.intersect(paintInfo.rect); | 435 backgroundRect.intersect(paintInfo.rect); |
| 479 | 436 |
| 480 GraphicsContextStateSaver shadowStateSaver(*context, boxShadowShould
BeAppliedToBackground); | 437 GraphicsContextStateSaver shadowStateSaver(*context, boxShadowShould
BeAppliedToBackground); |
| 481 if (boxShadowShouldBeAppliedToBackground) | 438 if (boxShadowShouldBeAppliedToBackground) |
| 482 applyBoxShadowForBackground(context, this); | 439 applyBoxShadowForBackground(context, this); |
| 483 | 440 |
| 484 if (isOpaqueRoot && !skipBaseColor) { | 441 if (bgColor.alpha()) |
| 485 paintRootBackgroundColor(paintInfo, rect, bgColor); | |
| 486 } else if (bgColor.alpha()) { | |
| 487 context->fillRect(backgroundRect, bgColor, context->compositeOpe
ration()); | 442 context->fillRect(backgroundRect, bgColor, context->compositeOpe
ration()); |
| 488 } | |
| 489 } | 443 } |
| 490 } | 444 } |
| 491 | 445 |
| 492 // no progressive loading of the background image | 446 // no progressive loading of the background image |
| 493 if (shouldPaintBackgroundImage) { | 447 if (shouldPaintBackgroundImage) { |
| 494 BackgroundImageGeometry geometry; | 448 BackgroundImageGeometry geometry; |
| 495 calculateBackgroundImageGeometry(paintInfo.paintContainer(), bgLayer, sc
rolledPaintRect, geometry, backgroundObject); | 449 calculateBackgroundImageGeometry(paintInfo.paintContainer(), bgLayer, sc
rolledPaintRect, geometry, backgroundObject); |
| 496 geometry.clip(paintInfo.rect); | 450 geometry.clip(paintInfo.rect); |
| 497 if (!geometry.destRect().isEmpty()) { | 451 if (!geometry.destRect().isEmpty()) { |
| 498 // FIXME(sky): Is it possible for the bgLayer to be something other
that CompositeSourceOver? | 452 // FIXME(sky): Is it possible for the bgLayer to be something other
that CompositeSourceOver? |
| (...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 733 top = borderTop(); | 687 top = borderTop(); |
| 734 bottom = borderBottom(); | 688 bottom = borderBottom(); |
| 735 if (fillLayer.origin() == ContentFillBox) { | 689 if (fillLayer.origin() == ContentFillBox) { |
| 736 left += paddingLeft(); | 690 left += paddingLeft(); |
| 737 right += paddingRight(); | 691 right += paddingRight(); |
| 738 top += paddingTop(); | 692 top += paddingTop(); |
| 739 bottom += paddingBottom(); | 693 bottom += paddingBottom(); |
| 740 } | 694 } |
| 741 } | 695 } |
| 742 | 696 |
| 743 // The background of the box generated by the root element covers the en
tire canvas including | 697 positioningAreaSize = pixelSnappedIntSize(paintRect.size() - LayoutSize(
left + right, top + bottom), paintRect.location()); |
| 744 // its margins. Since those were added in already, we have to factor the
m out when computing | |
| 745 // the background positioning area. | |
| 746 if (isDocumentElement()) { | |
| 747 positioningAreaSize = pixelSnappedIntSize(toRenderBox(this)->size()
- LayoutSize(left + right, top + bottom), toRenderBox(this)->location()); | |
| 748 left += marginLeft(); | |
| 749 top += marginTop(); | |
| 750 } else | |
| 751 positioningAreaSize = pixelSnappedIntSize(paintRect.size() - LayoutS
ize(left + right, top + bottom), paintRect.location()); | |
| 752 } else { | 698 } else { |
| 753 geometry.setHasNonLocalGeometry(); | 699 geometry.setHasNonLocalGeometry(); |
| 754 | 700 |
| 755 IntRect viewportRect = pixelSnappedIntRect(viewRect()); | 701 IntRect viewportRect = pixelSnappedIntRect(viewRect()); |
| 756 | 702 |
| 757 if (paintContainer) { | 703 if (paintContainer) { |
| 758 IntPoint absoluteContainerOffset = roundedIntPoint(paintContainer->l
ocalToAbsolute(FloatPoint())); | 704 IntPoint absoluteContainerOffset = roundedIntPoint(paintContainer->l
ocalToAbsolute(FloatPoint())); |
| 759 viewportRect.moveBy(-absoluteContainerOffset); | 705 viewportRect.moveBy(-absoluteContainerOffset); |
| 760 } | 706 } |
| 761 | 707 |
| (...skipping 1696 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2458 ASSERT(!beforeChild || toBoxModelObject == beforeChild->parent()); | 2404 ASSERT(!beforeChild || toBoxModelObject == beforeChild->parent()); |
| 2459 for (RenderObject* child = slowFirstChild(); child; ) { | 2405 for (RenderObject* child = slowFirstChild(); child; ) { |
| 2460 // Save our next sibling as moveChildTo will clear it. | 2406 // Save our next sibling as moveChildTo will clear it. |
| 2461 RenderObject* nextSibling = child->nextSibling(); | 2407 RenderObject* nextSibling = child->nextSibling(); |
| 2462 moveChildTo(toBoxModelObject, child, beforeChild, fullRemoveInsert); | 2408 moveChildTo(toBoxModelObject, child, beforeChild, fullRemoveInsert); |
| 2463 child = nextSibling; | 2409 child = nextSibling; |
| 2464 } | 2410 } |
| 2465 } | 2411 } |
| 2466 | 2412 |
| 2467 } // namespace blink | 2413 } // namespace blink |
| OLD | NEW |