LCOV - code coverage report
Current view: top level - layout/painting - DisplayListClipState.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 63 81 77.8 %
Date: 2017-07-14 16:53:18 Functions: 8 9 88.9 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
       2             :  * This Source Code Form is subject to the terms of the Mozilla Public
       3             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       4             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       5             : 
       6             : #include "DisplayListClipState.h"
       7             : 
       8             : #include "nsDisplayList.h"
       9             : 
      10             : namespace mozilla {
      11             : 
      12             : void
      13         871 : DisplayListClipState::ClearUpToASR(const ActiveScrolledRoot* aASR)
      14             : {
      15         871 :   while (mClipChainContentDescendants &&
      16           0 :          ActiveScrolledRoot::IsAncestor(aASR, mClipChainContentDescendants->mASR)) {
      17           0 :     mClipChainContentDescendants = mClipChainContentDescendants->mParent;
      18             :   }
      19        3118 :   while (mClipChainContainingBlockDescendants &&
      20         749 :          ActiveScrolledRoot::IsAncestor(aASR, mClipChainContainingBlockDescendants->mASR)) {
      21         749 :     mClipChainContainingBlockDescendants = mClipChainContainingBlockDescendants->mParent;
      22             :   }
      23         871 :   InvalidateCurrentCombinedClipChain(aASR);
      24         871 : }
      25             : 
      26             : const DisplayItemClipChain*
      27        5464 : DisplayListClipState::GetCurrentCombinedClipChain(nsDisplayListBuilder* aBuilder)
      28             : {
      29        5464 :   if (mCurrentCombinedClipChainIsValid) {
      30        3930 :     return mCurrentCombinedClipChain;
      31             :   }
      32        1534 :   if (!mClipChainContentDescendants && !mClipChainContainingBlockDescendants) {
      33         699 :     mCurrentCombinedClipChain = nullptr;
      34         699 :     mCurrentCombinedClipChainIsValid = true;
      35         699 :     return nullptr;
      36             :   }
      37             : 
      38         835 :   mCurrentCombinedClipChain =
      39         835 :     aBuilder->CreateClipChainIntersection(mCurrentCombinedClipChain,
      40             :                                              mClipChainContentDescendants,
      41             :                                              mClipChainContainingBlockDescendants);
      42         835 :   mCurrentCombinedClipChainIsValid = true;
      43         835 :   return mCurrentCombinedClipChain;
      44             : }
      45             : 
      46             : static void
      47         949 : ApplyClip(nsDisplayListBuilder* aBuilder,
      48             :           const DisplayItemClipChain*& aClipToModify,
      49             :           const ActiveScrolledRoot* aASR,
      50             :           DisplayItemClipChain& aClipChainOnStack)
      51             : {
      52         949 :   aClipChainOnStack.mASR = aASR;
      53         949 :   if (aClipToModify && aClipToModify->mASR == aASR) {
      54             :     // Intersect with aClipToModify and replace the clip chain item.
      55         436 :     aClipChainOnStack.mClip.IntersectWith(aClipToModify->mClip);
      56         436 :     aClipChainOnStack.mParent = aClipToModify->mParent;
      57         436 :     aClipToModify = &aClipChainOnStack;
      58         513 :   } else if (!aClipToModify ||
      59           0 :              ActiveScrolledRoot::IsAncestor(aClipToModify->mASR, aASR)) {
      60             :     // Add a new clip chain item at the bottom.
      61         513 :     aClipChainOnStack.mParent = aClipToModify;
      62         513 :     aClipToModify = &aClipChainOnStack;
      63             :   } else {
      64             :     // We need to insert / intersect a DisplayItemClipChain in the middle of the
      65             :     // aClipToModify chain. This is a very rare case.
      66             :     // Find the common ancestor and have the builder create the DisplayItemClipChain
      67             :     // intersection. This will create new DisplayItemClipChain objects for all
      68             :     // descendants of ancestorSC and we will not hold on to a pointer to
      69             :     // aClipChainOnStack.
      70           0 :     const DisplayItemClipChain* ancestorSC = aClipToModify;
      71           0 :     while (ancestorSC && ActiveScrolledRoot::IsAncestor(aASR, ancestorSC->mASR)) {
      72           0 :       ancestorSC = ancestorSC->mParent;
      73             :     }
      74           0 :     aClipChainOnStack.mParent = nullptr;
      75           0 :     aClipToModify =
      76           0 :       aBuilder->CreateClipChainIntersection(ancestorSC, aClipToModify, &aClipChainOnStack);
      77             :   }
      78         949 : }
      79             : 
      80             : void
      81         561 : DisplayListClipState::ClipContainingBlockDescendants(nsDisplayListBuilder* aBuilder,
      82             :                                                      const nsRect& aRect,
      83             :                                                      const nscoord* aRadii,
      84             :                                                      DisplayItemClipChain& aClipChainOnStack)
      85             : {
      86         561 :   if (aRadii) {
      87          48 :     aClipChainOnStack.mClip.SetTo(aRect, aRadii);
      88             :   } else {
      89         513 :     aClipChainOnStack.mClip.SetTo(aRect);
      90             :   }
      91         561 :   const ActiveScrolledRoot* asr = aBuilder->CurrentActiveScrolledRoot();
      92         561 :   ApplyClip(aBuilder, mClipChainContainingBlockDescendants, asr, aClipChainOnStack);
      93         561 :   InvalidateCurrentCombinedClipChain(asr);
      94         561 : }
      95             : 
      96             : void
      97         388 : DisplayListClipState::ClipContentDescendants(nsDisplayListBuilder* aBuilder,
      98             :                                              const nsRect& aRect,
      99             :                                              const nscoord* aRadii,
     100             :                                              DisplayItemClipChain& aClipChainOnStack)
     101             : {
     102         388 :   if (aRadii) {
     103          72 :     aClipChainOnStack.mClip.SetTo(aRect, aRadii);
     104             :   } else {
     105         316 :     aClipChainOnStack.mClip.SetTo(aRect);
     106             :   }
     107         388 :   const ActiveScrolledRoot* asr = aBuilder->CurrentActiveScrolledRoot();
     108         388 :   ApplyClip(aBuilder, mClipChainContentDescendants, asr, aClipChainOnStack);
     109         388 :   InvalidateCurrentCombinedClipChain(asr);
     110         388 : }
     111             : 
     112             : void
     113           0 : DisplayListClipState::ClipContentDescendants(nsDisplayListBuilder* aBuilder,
     114             :                                              const nsRect& aRect,
     115             :                                              const nsRect& aRoundedRect,
     116             :                                              const nscoord* aRadii,
     117             :                                              DisplayItemClipChain& aClipChainOnStack)
     118             : {
     119           0 :   if (aRadii) {
     120           0 :     aClipChainOnStack.mClip.SetTo(aRect, aRoundedRect, aRadii);
     121             :   } else {
     122           0 :     nsRect intersect = aRect.Intersect(aRoundedRect);
     123           0 :     aClipChainOnStack.mClip.SetTo(intersect);
     124             :   }
     125           0 :   const ActiveScrolledRoot* asr = aBuilder->CurrentActiveScrolledRoot();
     126           0 :   ApplyClip(aBuilder, mClipChainContentDescendants, asr, aClipChainOnStack);
     127           0 :   InvalidateCurrentCombinedClipChain(asr);
     128           0 : }
     129             : 
     130             : 
     131             : void
     132        1905 : DisplayListClipState::InvalidateCurrentCombinedClipChain(const ActiveScrolledRoot* aInvalidateUpTo)
     133             : {
     134        1905 :   mCurrentCombinedClipChainIsValid = false;
     135        5946 :   while (mCurrentCombinedClipChain &&
     136        1347 :          ActiveScrolledRoot::IsAncestor(aInvalidateUpTo, mCurrentCombinedClipChain->mASR)) {
     137        1347 :     mCurrentCombinedClipChain = mCurrentCombinedClipChain->mParent;
     138             :   }
     139        1905 : }
     140             : 
     141             : void
     142         359 : DisplayListClipState::ClipContainingBlockDescendantsToContentBox(nsDisplayListBuilder* aBuilder,
     143             :                                                                  nsIFrame* aFrame,
     144             :                                                                  DisplayItemClipChain& aClipChainOnStack,
     145             :                                                                  uint32_t aFlags)
     146             : {
     147             :   nscoord radii[8];
     148         359 :   bool hasBorderRadius = aFrame->GetContentBoxBorderRadii(radii);
     149         359 :   if (!hasBorderRadius && (aFlags & ASSUME_DRAWING_RESTRICTED_TO_CONTENT_RECT)) {
     150         317 :     return;
     151             :   }
     152             : 
     153          84 :   nsRect clipRect = aFrame->GetContentRectRelativeToSelf() +
     154         168 :     aBuilder->ToReferenceFrame(aFrame);
     155             :   // If we have a border-radius, we have to clip our content to that
     156             :   // radius.
     157          42 :   ClipContainingBlockDescendants(aBuilder, clipRect, hasBorderRadius ? radii : nullptr,
     158          42 :                                  aClipChainOnStack);
     159             : }
     160             : 
     161        4112 : DisplayListClipState::AutoSaveRestore::AutoSaveRestore(nsDisplayListBuilder* aBuilder)
     162             :   : mBuilder(aBuilder)
     163        4112 :   , mState(aBuilder->ClipState())
     164        4112 :   , mSavedState(aBuilder->ClipState())
     165             : #ifdef DEBUG
     166             :   , mClipUsed(false)
     167       12336 :   , mRestored(false)
     168             : #endif
     169        4112 : {}
     170             : 
     171             : } // namespace mozilla

Generated by: LCOV version 1.13