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, 2010 Apple Inc. All rights reserv
ed. | 6 * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserv
ed. |
7 * Copyright (C) 2013 Adobe Systems Incorporated. All rights reserved. | 7 * Copyright (C) 2013 Adobe Systems Incorporated. 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 685 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
696 offset.move(absPos.x(), absPos.y()); | 696 offset.move(absPos.x(), absPos.y()); |
697 return toIntSize(offset); | 697 return toIntSize(offset); |
698 } | 698 } |
699 | 699 |
700 FloatQuad LayoutBox::absoluteContentQuad() const | 700 FloatQuad LayoutBox::absoluteContentQuad() const |
701 { | 701 { |
702 LayoutRect rect = contentBoxRect(); | 702 LayoutRect rect = contentBoxRect(); |
703 return localToAbsoluteQuad(FloatRect(rect)); | 703 return localToAbsoluteQuad(FloatRect(rect)); |
704 } | 704 } |
705 | 705 |
706 LayoutRect LayoutBox::backgroundClipRect() const | 706 LayoutRect LayoutBox::backgroundRect(BackgroundRectType rectType) const |
707 { | 707 { |
708 // TODO(flackr): Check for the maximum background clip rect. | 708 EFillBox backgroundBox = TextFillBox; |
709 switch (style()->backgroundClip()) { | 709 // Find the largest background rect of the given opaqueness. |
| 710 if (const FillLayer* current = &(style()->backgroundLayers())) { |
| 711 do { |
| 712 const FillLayer* cur = current; |
| 713 current = current->next(); |
| 714 if (rectType == BackgroundKnownOpaqueRect) { |
| 715 if (cur->blendMode() != WebBlendModeNormal || cur->composite() !
= CompositeSourceOver) |
| 716 continue; |
| 717 |
| 718 bool layerKnownOpaque = false; |
| 719 // Check if the image is opaque and fills the clip. |
| 720 if (const StyleImage* image = cur->image()) { |
| 721 if ((cur->repeatX() == RepeatFill || cur->repeatX() == Round
Fill) |
| 722 && (cur->repeatY() == RepeatFill || cur->repeatY() == Ro
undFill) |
| 723 && image->knownToBeOpaque(*this)) { |
| 724 layerKnownOpaque = true; |
| 725 } |
| 726 } |
| 727 |
| 728 // The background color is painted into the last layer. |
| 729 if (!cur->next()) { |
| 730 Color backgroundColor = resolveColor(CSSPropertyBackgroundCo
lor); |
| 731 if (!backgroundColor.hasAlpha()) |
| 732 layerKnownOpaque = true; |
| 733 } |
| 734 |
| 735 // If neither the image nor the color are opaque then skip this
layer. |
| 736 if (!layerKnownOpaque) |
| 737 continue; |
| 738 } |
| 739 EFillBox currentClip = cur->clip(); |
| 740 // Restrict clip if attachment is local. |
| 741 if (currentClip == BorderFillBox && cur->attachment() == LocalBackgr
oundAttachment) |
| 742 currentClip = PaddingFillBox; |
| 743 |
| 744 // If we're asking for the clip rect, a content-box clipped fill lay
er can be scrolled |
| 745 // into the padding box of the overflow container. |
| 746 if (rectType == BackgroundClipRect |
| 747 && currentClip == ContentFillBox && cur->attachment() == LocalBa
ckgroundAttachment) { |
| 748 currentClip = PaddingFillBox; |
| 749 } |
| 750 |
| 751 backgroundBox = enclosingFillBox(backgroundBox, currentClip); |
| 752 } while (current); |
| 753 } |
| 754 switch (backgroundBox) { |
710 case BorderFillBox: | 755 case BorderFillBox: |
711 // A 'border-box' clip on scrollable elements local attachment is treate
d as 'padding-box'. | |
712 // https://www.w3.org/TR/css3-background/#the-background-attachment | |
713 if (!style()->isOverflowVisible() && style()->backgroundLayers().attachm
ent() == LocalBackgroundAttachment) | |
714 return paddingBoxRect(); | |
715 return borderBoxRect(); | 756 return borderBoxRect(); |
716 break; | 757 break; |
717 case PaddingFillBox: | 758 case PaddingFillBox: |
718 return paddingBoxRect(); | 759 return paddingBoxRect(); |
719 break; | 760 break; |
720 case ContentFillBox: | 761 case ContentFillBox: |
721 return contentBoxRect(); | 762 return contentBoxRect(); |
722 break; | 763 break; |
723 default: | 764 default: |
724 break; | 765 break; |
(...skipping 662 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1387 return false; | 1428 return false; |
1388 paintedExtent = LayoutRect(geometry.destRect()); | 1429 paintedExtent = LayoutRect(geometry.destRect()); |
1389 return true; | 1430 return true; |
1390 } | 1431 } |
1391 | 1432 |
1392 bool LayoutBox::backgroundIsKnownToBeOpaqueInRect(const LayoutRect& localRect) c
onst | 1433 bool LayoutBox::backgroundIsKnownToBeOpaqueInRect(const LayoutRect& localRect) c
onst |
1393 { | 1434 { |
1394 if (isDocumentElement() || backgroundStolenForBeingBody()) | 1435 if (isDocumentElement() || backgroundStolenForBeingBody()) |
1395 return false; | 1436 return false; |
1396 | 1437 |
1397 Color backgroundColor = resolveColor(CSSPropertyBackgroundColor); | |
1398 if (backgroundColor.hasAlpha()) | |
1399 return false; | |
1400 | |
1401 // If the element has appearance, it might be painted by theme. | 1438 // If the element has appearance, it might be painted by theme. |
1402 // We cannot be sure if theme paints the background opaque. | 1439 // We cannot be sure if theme paints the background opaque. |
1403 // In this case it is safe to not assume opaqueness. | 1440 // In this case it is safe to not assume opaqueness. |
1404 // FIXME: May be ask theme if it paints opaque. | 1441 // FIXME: May be ask theme if it paints opaque. |
1405 if (style()->hasAppearance()) | 1442 if (style()->hasAppearance()) |
1406 return false; | 1443 return false; |
1407 // FIXME: Check the opaqueness of background images. | 1444 // FIXME: Check the opaqueness of background images. |
1408 | 1445 |
1409 // FIXME: Use rounded rect if border radius is present. | 1446 // FIXME: Use rounded rect if border radius is present. |
1410 if (style()->hasBorderRadius()) | 1447 if (style()->hasBorderRadius()) |
1411 return false; | 1448 return false; |
1412 if (hasClipPath()) | 1449 if (hasClipPath()) |
1413 return false; | 1450 return false; |
1414 // FIXME: The background color clip is defined by the last layer. | 1451 if (style()->hasBlendMode()) |
1415 if (style()->backgroundLayers().next()) | |
1416 return false; | 1452 return false; |
1417 return backgroundClipRect().contains(localRect); | 1453 return backgroundRect(BackgroundKnownOpaqueRect).contains(localRect); |
1418 } | 1454 } |
1419 | 1455 |
1420 static bool isCandidateForOpaquenessTest(const LayoutBox& childBox) | 1456 static bool isCandidateForOpaquenessTest(const LayoutBox& childBox) |
1421 { | 1457 { |
1422 const ComputedStyle& childStyle = childBox.styleRef(); | 1458 const ComputedStyle& childStyle = childBox.styleRef(); |
1423 if (childStyle.position() != StaticPosition && childBox.containingBlock() !=
childBox.parent()) | 1459 if (childStyle.position() != StaticPosition && childBox.containingBlock() !=
childBox.parent()) |
1424 return false; | 1460 return false; |
1425 if (childStyle.visibility() != EVisibility::Visible || childStyle.shapeOutsi
de()) | 1461 if (childStyle.visibility() != EVisibility::Visible || childStyle.shapeOutsi
de()) |
1426 return false; | 1462 return false; |
1427 if (childBox.size().isZero()) | 1463 if (childBox.size().isZero()) |
(...skipping 347 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1775 LayoutBoxModelObject::mapLocalToAncestor(ancestor, transformState, mode); | 1811 LayoutBoxModelObject::mapLocalToAncestor(ancestor, transformState, mode); |
1776 } | 1812 } |
1777 | 1813 |
1778 void LayoutBox::mapAncestorToLocal(const LayoutBoxModelObject* ancestor, Transfo
rmState& transformState, MapCoordinatesFlags mode) const | 1814 void LayoutBox::mapAncestorToLocal(const LayoutBoxModelObject* ancestor, Transfo
rmState& transformState, MapCoordinatesFlags mode) const |
1779 { | 1815 { |
1780 if (this == ancestor) | 1816 if (this == ancestor) |
1781 return; | 1817 return; |
1782 | 1818 |
1783 bool isFixedPos = style()->position() == FixedPosition; | 1819 bool isFixedPos = style()->position() == FixedPosition; |
1784 | 1820 |
1785 if (style()->canContainFixedPositionObjects() && !isFixedPos) { | 1821 // If this box has a transform or contains paint, it acts as a fixed positio
n container for fixed descendants, |
1786 // If this box has a transform or contains paint, it acts as a fixed pos
ition container for fixed descendants, | 1822 // and may itself also be fixed position. So propagate 'fixed' up only if th
is box is fixed position. |
1787 // and may itself also be fixed position. So propagate 'fixed' up only i
f this box is fixed position. | 1823 if (style()->canContainFixedPositionObjects() && !isFixedPos) |
1788 mode &= ~IsFixed; | 1824 mode &= ~IsFixed; |
1789 } else if (isFixedPos) { | 1825 else if (isFixedPos) |
1790 mode |= IsFixed; | 1826 mode |= IsFixed; |
1791 } | |
1792 | 1827 |
1793 LayoutBoxModelObject::mapAncestorToLocal(ancestor, transformState, mode); | 1828 LayoutBoxModelObject::mapAncestorToLocal(ancestor, transformState, mode); |
1794 } | 1829 } |
1795 | 1830 |
1796 LayoutSize LayoutBox::offsetFromContainer(const LayoutObject* o) const | 1831 LayoutSize LayoutBox::offsetFromContainer(const LayoutObject* o) const |
1797 { | 1832 { |
1798 ASSERT(o == container()); | 1833 ASSERT(o == container()); |
1799 | 1834 |
1800 LayoutSize offset; | 1835 LayoutSize offset; |
1801 if (isInFlowPositioned()) | 1836 if (isInFlowPositioned()) |
(...skipping 3023 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4825 m_rareData->m_snapAreas->remove(&snapArea); | 4860 m_rareData->m_snapAreas->remove(&snapArea); |
4826 } | 4861 } |
4827 } | 4862 } |
4828 | 4863 |
4829 SnapAreaSet* LayoutBox::snapAreas() const | 4864 SnapAreaSet* LayoutBox::snapAreas() const |
4830 { | 4865 { |
4831 return m_rareData ? m_rareData->m_snapAreas.get() : nullptr; | 4866 return m_rareData ? m_rareData->m_snapAreas.get() : nullptr; |
4832 } | 4867 } |
4833 | 4868 |
4834 } // namespace blink | 4869 } // namespace blink |
OLD | NEW |