LCOV - code coverage report
Current view: directory - layout/generic - nsFloatManager.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 226 4 1.8 %
Date: 2012-06-02 Functions: 26 1 3.8 %

       1                 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2                 : /* ***** BEGIN LICENSE BLOCK *****
       3                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
       4                 :  *
       5                 :  * The contents of this file are subject to the Mozilla Public License Version
       6                 :  * 1.1 (the "License"); you may not use this file except in compliance with
       7                 :  * the License. You may obtain a copy of the License at
       8                 :  * http://www.mozilla.org/MPL/
       9                 :  *
      10                 :  * Software distributed under the License is distributed on an "AS IS" basis,
      11                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
      12                 :  * for the specific language governing rights and limitations under the
      13                 :  * License.
      14                 :  *
      15                 :  * The Original Code is mozilla.org code.
      16                 :  *
      17                 :  * The Initial Developer of the Original Code is
      18                 :  * Netscape Communications Corporation.
      19                 :  * Portions created by the Initial Developer are Copyright (C) 1998
      20                 :  * the Initial Developer. All Rights Reserved.
      21                 :  *
      22                 :  * Contributor(s):
      23                 :  *   L. David Baron <dbaron@dbaron.org>, Mozilla Corporation
      24                 :  *
      25                 :  * Alternatively, the contents of this file may be used under the terms of
      26                 :  * either of the GNU General Public License Version 2 or later (the "GPL"),
      27                 :  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
      28                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
      29                 :  * of those above. If you wish to allow use of your version of this file only
      30                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
      31                 :  * use your version of this file under the terms of the MPL, indicate your
      32                 :  * decision by deleting the provisions above and replace them with the notice
      33                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
      34                 :  * the provisions above, a recipient may use your version of this file under
      35                 :  * the terms of any one of the MPL, the GPL or the LGPL.
      36                 :  *
      37                 :  * ***** END LICENSE BLOCK ***** */
      38                 : 
      39                 : /* class that manages rules for positioning floats */
      40                 : 
      41                 : #include "nsFloatManager.h"
      42                 : #include "nsIPresShell.h"
      43                 : #include "nsMemory.h"
      44                 : #include "nsHTMLReflowState.h"
      45                 : #include "nsBlockDebugFlags.h"
      46                 : #include "nsContentErrors.h"
      47                 : 
      48                 : using namespace mozilla;
      49                 : 
      50                 : PRInt32 nsFloatManager::sCachedFloatManagerCount = 0;
      51                 : void* nsFloatManager::sCachedFloatManagers[NS_FLOAT_MANAGER_CACHE_SIZE];
      52                 : 
      53                 : /////////////////////////////////////////////////////////////////////////////
      54                 : 
      55                 : // PresShell Arena allocate callback (for nsIntervalSet use below)
      56                 : static void*
      57               0 : PSArenaAllocCB(size_t aSize, void* aClosure)
      58                 : {
      59               0 :   return static_cast<nsIPresShell*>(aClosure)->AllocateMisc(aSize);
      60                 : }
      61                 : 
      62                 : // PresShell Arena free callback (for nsIntervalSet use below)
      63                 : static void
      64               0 : PSArenaFreeCB(size_t aSize, void* aPtr, void* aClosure)
      65                 : {
      66               0 :   static_cast<nsIPresShell*>(aClosure)->FreeMisc(aSize, aPtr);
      67               0 : }
      68                 : 
      69                 : /////////////////////////////////////////////////////////////////////////////
      70                 : // nsFloatManager
      71                 : 
      72               0 : nsFloatManager::nsFloatManager(nsIPresShell* aPresShell)
      73                 :   : mX(0), mY(0),
      74                 :     mFloatDamage(PSArenaAllocCB, PSArenaFreeCB, aPresShell),
      75                 :     mPushedLeftFloatPastBreak(false),
      76                 :     mPushedRightFloatPastBreak(false),
      77                 :     mSplitLeftFloatAcrossBreak(false),
      78               0 :     mSplitRightFloatAcrossBreak(false)
      79                 : {
      80               0 :   MOZ_COUNT_CTOR(nsFloatManager);
      81               0 : }
      82                 : 
      83               0 : nsFloatManager::~nsFloatManager()
      84                 : {
      85               0 :   MOZ_COUNT_DTOR(nsFloatManager);
      86               0 : }
      87                 : 
      88                 : // static
      89               0 : void* nsFloatManager::operator new(size_t aSize) CPP_THROW_NEW
      90                 : {
      91               0 :   if (sCachedFloatManagerCount > 0) {
      92                 :     // We have cached unused instances of this class, return a cached
      93                 :     // instance in stead of always creating a new one.
      94               0 :     return sCachedFloatManagers[--sCachedFloatManagerCount];
      95                 :   }
      96                 : 
      97                 :   // The cache is empty, this means we haveto create a new instance using
      98                 :   // the global |operator new|.
      99               0 :   return nsMemory::Alloc(aSize);
     100                 : }
     101                 : 
     102                 : void
     103               0 : nsFloatManager::operator delete(void* aPtr, size_t aSize)
     104                 : {
     105               0 :   if (!aPtr)
     106               0 :     return;
     107                 :   // This float manager is no longer used, if there's still room in
     108                 :   // the cache we'll cache this float manager, unless the layout
     109                 :   // module was already shut down.
     110                 : 
     111               0 :   if (sCachedFloatManagerCount < NS_FLOAT_MANAGER_CACHE_SIZE &&
     112                 :       sCachedFloatManagerCount >= 0) {
     113                 :     // There's still space in the cache for more instances, put this
     114                 :     // instance in the cache in stead of deleting it.
     115                 : 
     116               0 :     sCachedFloatManagers[sCachedFloatManagerCount++] = aPtr;
     117               0 :     return;
     118                 :   }
     119                 : 
     120                 :   // The cache is full, or the layout module has been shut down,
     121                 :   // delete this float manager.
     122               0 :   nsMemory::Free(aPtr);
     123                 : }
     124                 : 
     125                 : 
     126                 : /* static */
     127            1403 : void nsFloatManager::Shutdown()
     128                 : {
     129                 :   // The layout module is being shut down, clean up the cache and
     130                 :   // disable further caching.
     131                 : 
     132                 :   PRInt32 i;
     133                 : 
     134            1403 :   for (i = 0; i < sCachedFloatManagerCount; i++) {
     135               0 :     void* floatManager = sCachedFloatManagers[i];
     136               0 :     if (floatManager)
     137               0 :       nsMemory::Free(floatManager);
     138                 :   }
     139                 : 
     140                 :   // Disable further caching.
     141            1403 :   sCachedFloatManagerCount = -1;
     142            1403 : }
     143                 : 
     144                 : nsFlowAreaRect
     145               0 : nsFloatManager::GetFlowArea(nscoord aYOffset, BandInfoType aInfoType,
     146                 :                             nscoord aHeight, nsRect aContentArea,
     147                 :                             SavedState* aState) const
     148                 : {
     149               0 :   NS_ASSERTION(aHeight >= 0, "unexpected max height");
     150               0 :   NS_ASSERTION(aContentArea.width >= 0, "unexpected content area width");
     151                 : 
     152               0 :   nscoord top = aYOffset + mY;
     153               0 :   if (top < nscoord_MIN) {
     154               0 :     NS_WARNING("bad value");
     155               0 :     top = nscoord_MIN;
     156                 :   }
     157                 : 
     158                 :   // Determine the last float that we should consider.
     159                 :   PRUint32 floatCount;
     160               0 :   if (aState) {
     161                 :     // Use the provided state.
     162               0 :     floatCount = aState->mFloatInfoCount;
     163               0 :     NS_ABORT_IF_FALSE(floatCount <= mFloats.Length(), "bad state");
     164                 :   } else {
     165                 :     // Use our current state.
     166               0 :     floatCount = mFloats.Length();
     167                 :   }
     168                 : 
     169                 :   // If there are no floats at all, or we're below the last one, return
     170                 :   // quickly.
     171               0 :   if (floatCount == 0 ||
     172               0 :       (mFloats[floatCount-1].mLeftYMost <= top &&
     173               0 :        mFloats[floatCount-1].mRightYMost <= top)) {
     174                 :     return nsFlowAreaRect(aContentArea.x, aYOffset, aContentArea.width,
     175               0 :                           aHeight, false);
     176                 :   }
     177                 : 
     178                 :   nscoord bottom;
     179               0 :   if (aHeight == nscoord_MAX) {
     180                 :     // This warning (and the two below) are possible to hit on pages
     181                 :     // with really large objects.
     182               0 :     NS_WARN_IF_FALSE(aInfoType == BAND_FROM_POINT,
     183                 :                      "bad height");
     184               0 :     bottom = nscoord_MAX;
     185                 :   } else {
     186               0 :     bottom = top + aHeight;
     187               0 :     if (bottom < top || bottom > nscoord_MAX) {
     188               0 :       NS_WARNING("bad value");
     189               0 :       bottom = nscoord_MAX;
     190                 :     }
     191                 :   }
     192               0 :   nscoord left = mX + aContentArea.x;
     193               0 :   nscoord right = mX + aContentArea.XMost();
     194               0 :   if (right < left) {
     195               0 :     NS_WARNING("bad value");
     196               0 :     right = left;
     197                 :   }
     198                 : 
     199                 :   // Walk backwards through the floats until we either hit the front of
     200                 :   // the list or we're above |top|.
     201               0 :   bool haveFloats = false;
     202               0 :   for (PRUint32 i = floatCount; i > 0; --i) {
     203               0 :     const FloatInfo &fi = mFloats[i-1];
     204               0 :     if (fi.mLeftYMost <= top && fi.mRightYMost <= top) {
     205                 :       // There aren't any more floats that could intersect this band.
     206               0 :       break;
     207                 :     }
     208               0 :     if (fi.mRect.IsEmpty()) {
     209                 :       // For compatibility, ignore floats with empty rects, even though it
     210                 :       // disagrees with the spec.  (We might want to fix this in the
     211                 :       // future, though.)
     212               0 :       continue;
     213                 :     }
     214               0 :     nscoord floatTop = fi.mRect.y, floatBottom = fi.mRect.YMost();
     215               0 :     if (top < floatTop && aInfoType == BAND_FROM_POINT) {
     216                 :       // This float is below our band.  Shrink our band's height if needed.
     217               0 :       if (floatTop < bottom) {
     218               0 :         bottom = floatTop;
     219                 :       }
     220                 :     }
     221                 :     // If top == bottom (which happens only with WIDTH_WITHIN_HEIGHT),
     222                 :     // we include floats that begin at our 0-height vertical area.  We
     223                 :     // need to to this to satisfy the invariant that a
     224                 :     // WIDTH_WITHIN_HEIGHT call is at least as narrow on both sides as a
     225                 :     // BAND_WITHIN_POINT call beginning at its top.
     226               0 :     else if (top < floatBottom &&
     227                 :              (floatTop < bottom || (floatTop == bottom && top == bottom))) {
     228                 :       // This float is in our band.
     229                 : 
     230                 :       // Shrink our band's height if needed.
     231               0 :       if (floatBottom < bottom && aInfoType == BAND_FROM_POINT) {
     232               0 :         bottom = floatBottom;
     233                 :       }
     234                 : 
     235                 :       // Shrink our band's width if needed.
     236               0 :       if (fi.mFrame->GetStyleDisplay()->mFloats == NS_STYLE_FLOAT_LEFT) {
     237                 :         // A left float.
     238               0 :         nscoord rightEdge = fi.mRect.XMost();
     239               0 :         if (rightEdge > left) {
     240               0 :           left = rightEdge;
     241                 :           // Only set haveFloats to true if the float is inside our
     242                 :           // containing block.  This matches the spec for what some
     243                 :           // callers want and disagrees for other callers, so we should
     244                 :           // probably provide better information at some point.
     245               0 :           haveFloats = true;
     246                 :         }
     247                 :       } else {
     248                 :         // A right float.
     249               0 :         nscoord leftEdge = fi.mRect.x;
     250               0 :         if (leftEdge < right) {
     251               0 :           right = leftEdge;
     252                 :           // See above.
     253               0 :           haveFloats = true;
     254                 :         }
     255                 :       }
     256                 :     }
     257                 :   }
     258                 : 
     259               0 :   nscoord height = (bottom == nscoord_MAX) ? nscoord_MAX : (bottom - top);
     260               0 :   return nsFlowAreaRect(left - mX, top - mY, right - left, height, haveFloats);
     261                 : }
     262                 : 
     263                 : nsresult
     264               0 : nsFloatManager::AddFloat(nsIFrame* aFloatFrame, const nsRect& aMarginRect)
     265                 : {
     266               0 :   NS_ASSERTION(aMarginRect.width >= 0, "negative width!");
     267               0 :   NS_ASSERTION(aMarginRect.height >= 0, "negative height!");
     268                 : 
     269               0 :   FloatInfo info(aFloatFrame, aMarginRect + nsPoint(mX, mY));
     270                 : 
     271                 :   // Set mLeftYMost and mRightYMost.
     272               0 :   if (HasAnyFloats()) {
     273               0 :     FloatInfo &tail = mFloats[mFloats.Length() - 1];
     274               0 :     info.mLeftYMost = tail.mLeftYMost;
     275               0 :     info.mRightYMost = tail.mRightYMost;
     276                 :   } else {
     277               0 :     info.mLeftYMost = nscoord_MIN;
     278               0 :     info.mRightYMost = nscoord_MIN;
     279                 :   }
     280               0 :   PRUint8 floatStyle = aFloatFrame->GetStyleDisplay()->mFloats;
     281               0 :   NS_ASSERTION(floatStyle == NS_STYLE_FLOAT_LEFT ||
     282                 :                floatStyle == NS_STYLE_FLOAT_RIGHT, "unexpected float");
     283                 :   nscoord& sideYMost = (floatStyle == NS_STYLE_FLOAT_LEFT) ? info.mLeftYMost
     284               0 :                                                            : info.mRightYMost;
     285               0 :   nscoord thisYMost = info.mRect.YMost();
     286               0 :   if (thisYMost > sideYMost)
     287               0 :     sideYMost = thisYMost;
     288                 : 
     289               0 :   if (!mFloats.AppendElement(info))
     290               0 :     return NS_ERROR_OUT_OF_MEMORY;
     291                 : 
     292               0 :   return NS_OK;
     293                 : }
     294                 : 
     295                 : nsRect
     296               0 : nsFloatManager::CalculateRegionFor(nsIFrame*       aFloat,
     297                 :                                    const nsMargin& aMargin)
     298                 : {
     299               0 :   nsRect region = aFloat->GetRect();
     300                 : 
     301                 :   // Float region includes its margin
     302               0 :   region.Inflate(aMargin);
     303                 : 
     304                 :   // If the element is relatively positioned, then adjust x and y
     305                 :   // accordingly so that we consider relatively positioned frames
     306                 :   // at their original position.
     307               0 :   const nsStyleDisplay* display = aFloat->GetStyleDisplay();
     308               0 :   region -= aFloat->GetRelativeOffset(display);
     309                 : 
     310                 :   // Don't store rectangles with negative margin-box width or height in
     311                 :   // the float manager; it can't deal with them.
     312               0 :   if (region.width < 0) {
     313                 :     // Preserve the right margin-edge for left floats and the left
     314                 :     // margin-edge for right floats
     315               0 :     if (NS_STYLE_FLOAT_LEFT == display->mFloats) {
     316               0 :       region.x = region.XMost();
     317                 :     }
     318               0 :     region.width = 0;
     319                 :   }
     320               0 :   if (region.height < 0) {
     321               0 :     region.height = 0;
     322                 :   }
     323                 :   return region;
     324                 : }
     325                 : 
     326               0 : NS_DECLARE_FRAME_PROPERTY(FloatRegionProperty, nsIFrame::DestroyMargin)
     327                 : 
     328                 : nsRect
     329               0 : nsFloatManager::GetRegionFor(nsIFrame* aFloat)
     330                 : {
     331               0 :   nsRect region = aFloat->GetRect();
     332               0 :   void* storedRegion = aFloat->Properties().Get(FloatRegionProperty());
     333               0 :   if (storedRegion) {
     334               0 :     nsMargin margin = *static_cast<nsMargin*>(storedRegion);
     335               0 :     region.Inflate(margin);
     336                 :   }
     337                 :   return region;
     338                 : }
     339                 : 
     340                 : void
     341               0 : nsFloatManager::StoreRegionFor(nsIFrame* aFloat,
     342                 :                                nsRect&   aRegion)
     343                 : {
     344               0 :   nsRect rect = aFloat->GetRect();
     345               0 :   FrameProperties props = aFloat->Properties();
     346               0 :   if (aRegion.IsEqualEdges(rect)) {
     347               0 :     props.Delete(FloatRegionProperty());
     348                 :   }
     349                 :   else {
     350                 :     nsMargin* storedMargin = static_cast<nsMargin*>
     351               0 :       (props.Get(FloatRegionProperty()));
     352               0 :     if (!storedMargin) {
     353               0 :       storedMargin = new nsMargin();
     354               0 :       props.Set(FloatRegionProperty(), storedMargin);
     355                 :     }
     356               0 :     *storedMargin = aRegion - rect;
     357                 :   }
     358               0 : }
     359                 : 
     360                 : nsresult
     361               0 : nsFloatManager::RemoveTrailingRegions(nsIFrame* aFrameList)
     362                 : {
     363               0 :   if (!aFrameList) {
     364               0 :     return NS_OK;
     365                 :   }
     366                 :   // This could be a good bit simpler if we could guarantee that the
     367                 :   // floats given were at the end of our list, so we could just search
     368                 :   // for the head of aFrameList.  (But we can't;
     369                 :   // layout/reftests/bugs/421710-1.html crashes.)
     370               0 :   nsTHashtable<nsPtrHashKey<nsIFrame> > frameSet;
     371                 : 
     372               0 :   frameSet.Init(1);
     373               0 :   for (nsIFrame* f = aFrameList; f; f = f->GetNextSibling()) {
     374               0 :     frameSet.PutEntry(f);
     375                 :   }
     376                 : 
     377               0 :   PRUint32 newLength = mFloats.Length();
     378               0 :   while (newLength > 0) {
     379               0 :     if (!frameSet.Contains(mFloats[newLength - 1].mFrame)) {
     380               0 :       break;
     381                 :     }
     382               0 :     --newLength;
     383                 :   }
     384               0 :   mFloats.TruncateLength(newLength);
     385                 : 
     386                 : #ifdef DEBUG
     387               0 :   for (PRUint32 i = 0; i < mFloats.Length(); ++i) {
     388               0 :     NS_ASSERTION(!frameSet.Contains(mFloats[i].mFrame),
     389                 :                  "Frame region deletion was requested but we couldn't delete it");
     390                 :   }
     391                 : #endif
     392                 : 
     393               0 :   return NS_OK;
     394                 : }
     395                 : 
     396                 : void
     397               0 : nsFloatManager::PushState(SavedState* aState)
     398                 : {
     399               0 :   NS_PRECONDITION(aState, "Need a place to save state");
     400                 : 
     401                 :   // This is a cheap push implementation, which
     402                 :   // only saves the (x,y) and last frame in the mFrameInfoMap
     403                 :   // which is enough info to get us back to where we should be
     404                 :   // when pop is called.
     405                 :   //
     406                 :   // This push/pop mechanism is used to undo any
     407                 :   // floats that were added during the unconstrained reflow
     408                 :   // in nsBlockReflowContext::DoReflowBlock(). (See bug 96736)
     409                 :   //
     410                 :   // It should also be noted that the state for mFloatDamage is
     411                 :   // intentionally not saved or restored in PushState() and PopState(),
     412                 :   // since that could lead to bugs where damage is missed/dropped when
     413                 :   // we move from position A to B (during the intermediate incremental
     414                 :   // reflow mentioned above) and then from B to C during the subsequent
     415                 :   // reflow. In the typical case A and C will be the same, but not always.
     416                 :   // Allowing mFloatDamage to accumulate the damage incurred during both
     417                 :   // reflows ensures that nothing gets missed.
     418               0 :   aState->mX = mX;
     419               0 :   aState->mY = mY;
     420               0 :   aState->mPushedLeftFloatPastBreak = mPushedLeftFloatPastBreak;
     421               0 :   aState->mPushedRightFloatPastBreak = mPushedRightFloatPastBreak;
     422               0 :   aState->mSplitLeftFloatAcrossBreak = mSplitLeftFloatAcrossBreak;
     423               0 :   aState->mSplitRightFloatAcrossBreak = mSplitRightFloatAcrossBreak;
     424               0 :   aState->mFloatInfoCount = mFloats.Length();
     425               0 : }
     426                 : 
     427                 : void
     428               0 : nsFloatManager::PopState(SavedState* aState)
     429                 : {
     430               0 :   NS_PRECONDITION(aState, "No state to restore?");
     431                 : 
     432               0 :   mX = aState->mX;
     433               0 :   mY = aState->mY;
     434               0 :   mPushedLeftFloatPastBreak = aState->mPushedLeftFloatPastBreak;
     435               0 :   mPushedRightFloatPastBreak = aState->mPushedRightFloatPastBreak;
     436               0 :   mSplitLeftFloatAcrossBreak = aState->mSplitLeftFloatAcrossBreak;
     437               0 :   mSplitRightFloatAcrossBreak = aState->mSplitRightFloatAcrossBreak;
     438                 : 
     439               0 :   NS_ASSERTION(aState->mFloatInfoCount <= mFloats.Length(),
     440                 :                "somebody misused PushState/PopState");
     441               0 :   mFloats.TruncateLength(aState->mFloatInfoCount);
     442               0 : }
     443                 : 
     444                 : nscoord
     445               0 : nsFloatManager::GetLowestFloatTop() const
     446                 : {
     447               0 :   if (mPushedLeftFloatPastBreak || mPushedRightFloatPastBreak) {
     448               0 :     return nscoord_MAX;
     449                 :   }
     450               0 :   if (!HasAnyFloats()) {
     451               0 :     return nscoord_MIN;
     452                 :   }
     453               0 :   return mFloats[mFloats.Length() - 1].mRect.y - mY;
     454                 : }
     455                 : 
     456                 : #ifdef DEBUG
     457                 : void
     458               0 : DebugListFloatManager(const nsFloatManager *aFloatManager)
     459                 : {
     460               0 :   aFloatManager->List(stdout);
     461               0 : }
     462                 : 
     463                 : nsresult
     464               0 : nsFloatManager::List(FILE* out) const
     465                 : {
     466               0 :   if (!HasAnyFloats())
     467               0 :     return NS_OK;
     468                 : 
     469               0 :   for (PRUint32 i = 0; i < mFloats.Length(); ++i) {
     470               0 :     const FloatInfo &fi = mFloats[i];
     471                 :     printf("Float %u: frame=%p rect={%d,%d,%d,%d} ymost={l:%d, r:%d}\n",
     472                 :            i, static_cast<void*>(fi.mFrame),
     473                 :            fi.mRect.x, fi.mRect.y, fi.mRect.width, fi.mRect.height,
     474               0 :            fi.mLeftYMost, fi.mRightYMost);
     475                 :   }
     476               0 :   return NS_OK;
     477                 : }
     478                 : #endif
     479                 : 
     480                 : nscoord
     481               0 : nsFloatManager::ClearFloats(nscoord aY, PRUint8 aBreakType,
     482                 :                             PRUint32 aFlags) const
     483                 : {
     484               0 :   if (!(aFlags & DONT_CLEAR_PUSHED_FLOATS) && ClearContinues(aBreakType)) {
     485               0 :     return nscoord_MAX;
     486                 :   }
     487               0 :   if (!HasAnyFloats()) {
     488               0 :     return aY;
     489                 :   }
     490                 : 
     491               0 :   nscoord bottom = aY + mY;
     492                 : 
     493               0 :   const FloatInfo &tail = mFloats[mFloats.Length() - 1];
     494               0 :   switch (aBreakType) {
     495                 :     case NS_STYLE_CLEAR_LEFT_AND_RIGHT:
     496               0 :       bottom = NS_MAX(bottom, tail.mLeftYMost);
     497               0 :       bottom = NS_MAX(bottom, tail.mRightYMost);
     498               0 :       break;
     499                 :     case NS_STYLE_CLEAR_LEFT:
     500               0 :       bottom = NS_MAX(bottom, tail.mLeftYMost);
     501               0 :       break;
     502                 :     case NS_STYLE_CLEAR_RIGHT:
     503               0 :       bottom = NS_MAX(bottom, tail.mRightYMost);
     504               0 :       break;
     505                 :     default:
     506                 :       // Do nothing
     507               0 :       break;
     508                 :   }
     509                 : 
     510               0 :   bottom -= mY;
     511                 : 
     512               0 :   return bottom;
     513                 : }
     514                 : 
     515                 : bool
     516               0 : nsFloatManager::ClearContinues(PRUint8 aBreakType) const
     517                 : {
     518                 :   return ((mPushedLeftFloatPastBreak || mSplitLeftFloatAcrossBreak) &&
     519                 :           (aBreakType == NS_STYLE_CLEAR_LEFT_AND_RIGHT ||
     520                 :            aBreakType == NS_STYLE_CLEAR_LEFT)) ||
     521                 :          ((mPushedRightFloatPastBreak || mSplitRightFloatAcrossBreak) &&
     522                 :           (aBreakType == NS_STYLE_CLEAR_LEFT_AND_RIGHT ||
     523               0 :            aBreakType == NS_STYLE_CLEAR_RIGHT));
     524                 : }
     525                 : 
     526                 : /////////////////////////////////////////////////////////////////////////////
     527                 : // FloatInfo
     528                 : 
     529               0 : nsFloatManager::FloatInfo::FloatInfo(nsIFrame* aFrame, const nsRect& aRect)
     530               0 :   : mFrame(aFrame), mRect(aRect)
     531                 : {
     532               0 :   MOZ_COUNT_CTOR(nsFloatManager::FloatInfo);
     533               0 : }
     534                 : 
     535                 : #ifdef NS_BUILD_REFCNT_LOGGING
     536               0 : nsFloatManager::FloatInfo::FloatInfo(const FloatInfo& aOther)
     537                 :   : mFrame(aOther.mFrame),
     538                 :     mRect(aOther.mRect),
     539                 :     mLeftYMost(aOther.mLeftYMost),
     540               0 :     mRightYMost(aOther.mRightYMost)
     541                 : {
     542               0 :   MOZ_COUNT_CTOR(nsFloatManager::FloatInfo);
     543               0 : }
     544                 : 
     545               0 : nsFloatManager::FloatInfo::~FloatInfo()
     546                 : {
     547               0 :   MOZ_COUNT_DTOR(nsFloatManager::FloatInfo);
     548               0 : }
     549                 : #endif
     550                 : 
     551                 : //----------------------------------------------------------------------
     552                 : 
     553               0 : nsAutoFloatManager::~nsAutoFloatManager()
     554                 : {
     555                 :   // Restore the old float manager in the reflow state if necessary.
     556               0 :   if (mNew) {
     557                 : #ifdef NOISY_FLOATMANAGER
     558                 :     printf("restoring old float manager %p\n", mOld);
     559                 : #endif
     560                 : 
     561               0 :     mReflowState.mFloatManager = mOld;
     562                 : 
     563                 : #ifdef NOISY_FLOATMANAGER
     564                 :     if (mOld) {
     565                 :       static_cast<nsFrame *>(mReflowState.frame)->ListTag(stdout);
     566                 :       printf(": space-manager %p after reflow\n", mOld);
     567                 :       mOld->List(stdout);
     568                 :     }
     569                 : #endif
     570                 : 
     571               0 :     delete mNew;
     572                 :   }
     573               0 : }
     574                 : 
     575                 : nsresult
     576               0 : nsAutoFloatManager::CreateFloatManager(nsPresContext *aPresContext)
     577                 : {
     578                 :   // Create a new float manager and install it in the reflow
     579                 :   // state. `Remember' the old float manager so we can restore it
     580                 :   // later.
     581               0 :   mNew = new nsFloatManager(aPresContext->PresShell());
     582               0 :   if (! mNew)
     583               0 :     return NS_ERROR_OUT_OF_MEMORY;
     584                 : 
     585                 : #ifdef NOISY_FLOATMANAGER
     586                 :   printf("constructed new float manager %p (replacing %p)\n",
     587                 :          mNew, mReflowState.mFloatManager);
     588                 : #endif
     589                 : 
     590                 :   // Set the float manager in the existing reflow state
     591               0 :   mOld = mReflowState.mFloatManager;
     592               0 :   mReflowState.mFloatManager = mNew;
     593               0 :   return NS_OK;
     594                 : }

Generated by: LCOV version 1.7