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 |