Back to index

lightning-sunbird  0.9+nobinonly
Defines | Functions | Variables
nsBlockFrame.cpp File Reference
#include "nsCOMPtr.h"
#include "nsBlockFrame.h"
#include "nsBlockReflowContext.h"
#include "nsBlockReflowState.h"
#include "nsBlockBandData.h"
#include "nsBulletFrame.h"
#include "nsLineBox.h"
#include "nsInlineFrame.h"
#include "nsLineLayout.h"
#include "nsPlaceholderFrame.h"
#include "nsStyleConsts.h"
#include "nsFrameManager.h"
#include "nsPresContext.h"
#include "nsIPresShell.h"
#include "nsReflowPath.h"
#include "nsStyleContext.h"
#include "nsIView.h"
#include "nsIFontMetrics.h"
#include "nsHTMLParts.h"
#include "nsHTMLAtoms.h"
#include "nsIDOMEvent.h"
#include "nsGenericHTMLElement.h"
#include "prprf.h"
#include "nsLayoutAtoms.h"
#include "nsITextContent.h"
#include "nsStyleChangeList.h"
#include "nsIFrameSelection.h"
#include "nsSpaceManager.h"
#include "nsIntervalSet.h"
#include "prenv.h"
#include "plstr.h"
#include "nsGUIEvent.h"
#include "nsLayoutErrors.h"
#include "nsAutoPtr.h"
#include "nsIServiceManager.h"
#include "nsIScrollableFrame.h"
#include "nsLayoutUtils.h"
#include "nsBoxLayoutState.h"
#include "nsCSSAnonBoxes.h"
#include "nsIDOMHTMLBodyElement.h"
#include "nsIDOMHTMLHtmlElement.h"

Go to the source code of this file.

Defines

#define MAX_DEPTH_FOR_LIST_RENUMBERING   200
#define LINE_REFLOW_OK   0
#define LINE_REFLOW_STOP   1
#define LINE_REFLOW_REDO   2
#define LINE_REFLOW_TRUNCATED   3

Functions

nsresult NS_NewBlockFrame (nsIPresShell *aPresShell, nsIFrame **aNewFrame, PRUint32 aFlags)
static PRBool IsContinuationPlaceholder (nsIFrame *aFrame)
static void ReparentFrame (nsIFrame *aFrame, nsIFrame *aOldParent, nsIFrame *aNewParent)
static nsSize CalculateContainingBlockSizeForAbsolutes (const nsHTMLReflowState &aReflowState, nsSize aFrameSize)
static PRBool HaveAutoWidth (const nsHTMLReflowState &aReflowState)
static PRBool IsPercentageAwareChild (const nsIFrame *aFrame)
static void DirtyLinesWithDirtyContinuations (const nsLineList::iterator &aLineStart, const nsLineList::iterator &aLineEnd)
static void PlaceFrameView (nsIFrame *aFrame)
static PRBool LineHasClear (nsLineBox *aLine)
static void DumpLine (const nsBlockReflowState &aState, nsLineBox *aLine, nscoord aDeltaY, PRInt32 aDeltaIndent)
static void GetRectDifferenceStrips (const nsRect &aR1, const nsRect &aR2, nsRect *aHStrip, nsRect *aVStrip)
 Takes two rectangles whose origins must be the same, and computes the difference between their union and their intersection as two rectangles.
PRBool IsPaddingZero (nsStyleUnit aUnit, nsStyleCoord &aCoord)
PRBool IsMarginZero (nsStyleUnit aUnit, nsStyleCoord &aCoord)
static void DestroyOverflowLines (void *aFrame, nsIAtom *aPropertyName, void *aPropertyValue, void *aDtorData)
static PRBool ShouldPutNextSiblingOnNewLine (nsIFrame *aLastFrame)
static void MarkAllDescendantLinesDirty (nsBlockFrame *aBlock)
static void MarkSameSpaceManagerLinesDirty (nsBlockFrame *aBlock)
static PRBool BlockHasAnyFloats (nsIFrame *aFrame)
 Returns PR_TRUE if aFrame is a block that has one or more float children.
static nsresult RemoveBlockChild (nsIFrame *aFrame, PRBool aDestroyFrames)
static void PaintLine (const nsRect &aLineArea, const nsRect &aDirtyRect, nsBlockFrame::line_iterator &aLine, PRInt32 aDepth, PRInt32 &aDrawnLines, nsPresContext *aPresContext, nsIRenderingContext &aRenderingContext, nsFramePaintLayer aWhichLayer, nsBlockFrame *aFrame)
static void GetFrameFromLine (const nsRect &aLineArea, const nsPoint &aTmp, nsBlockFrame::line_iterator &aLine, nsFramePaintLayer aWhichLayer, nsIFrame **aFrame)

Variables

static const int MIN_LINES_NEEDING_CURSOR = 20
const nsIID kBlockFrameCID = NS_BLOCK_FRAME_CID

Define Documentation

Definition at line 3742 of file nsBlockFrame.cpp.

Definition at line 3744 of file nsBlockFrame.cpp.

Definition at line 3743 of file nsBlockFrame.cpp.

Definition at line 3746 of file nsBlockFrame.cpp.

Definition at line 187 of file nsBlockFrame.cpp.


Function Documentation

static PRBool BlockHasAnyFloats ( nsIFrame aFrame) [static]

Returns PR_TRUE if aFrame is a block that has one or more float children.

Definition at line 5563 of file nsBlockFrame.cpp.

{
  void* bf;
  if (NS_FAILED(aFrame->QueryInterface(kBlockFrameCID, &bf)))
    return PR_FALSE;
  nsBlockFrame* block = NS_STATIC_CAST(nsBlockFrame*, aFrame);
  if (block->GetFirstChild(nsLayoutAtoms::floatList))
    return PR_TRUE;
    
  nsLineList::iterator line = block->begin_lines();
  nsLineList::iterator endLine = block->end_lines();
  while (line != endLine) {
    if (line->IsBlock() && BlockHasAnyFloats(line->mFirstChild))
      return PR_TRUE;
    ++line;
  }
  return PR_FALSE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static nsSize CalculateContainingBlockSizeForAbsolutes ( const nsHTMLReflowState aReflowState,
nsSize  aFrameSize 
) [static]

Definition at line 576 of file nsBlockFrame.cpp.

{
  // The issue here is that for a 'height' of 'auto' the reflow state
  // code won't know how to calculate the containing block height
  // because it's calculated bottom up. So we use our own computed
  // size as the dimensions. We don't really want to do this for the
  // initial containing block
  nsIFrame* frame = aReflowState.frame;
  if (nsLayoutUtils::IsInitialContainingBlock(frame)) {
    return nsSize(-1, -1);
  }

  nsSize cbSize(aFrameSize);
    // Containing block is relative to the padding edge
  const nsMargin& border = aReflowState.mStyleBorder->GetBorder();
  cbSize.width -= border.left + border.right;
  cbSize.height -= border.top + border.bottom;

  if (frame->GetParent()->GetContent() == frame->GetContent()) {
    // We are a wrapped frame for the content. Use the container's
    // dimensions, if they have been precomputed.
    // XXX This is a hack! We really should be waiting until the outermost
    // frame is fully reflowed and using the resulting dimensions, even
    // if they're intrinsic.
    // In fact we should be attaching absolute children to the outermost
    // frame and not always sticking them in block frames.

    // First, find the reflow state for the outermost frame for this
    // content.
    const nsHTMLReflowState* aLastRS = &aReflowState;
    const nsHTMLReflowState* lastButOneRS = &aReflowState;
    while (aLastRS->parentReflowState &&
           aLastRS->parentReflowState->frame->GetContent() == frame->GetContent()) {
      lastButOneRS = aLastRS;
      aLastRS = aLastRS->parentReflowState;
    }
    if (aLastRS != &aReflowState) {
      // The wrapper frame should be block-level. If it isn't, how the
      // heck did it end up wrapping this block frame?
      NS_ASSERTION(aLastRS->frame->GetStyleDisplay()->IsBlockLevel(),
                   "Wrapping frame should be block-level");
      // Scrollbars need to be specifically excluded, if present, because they are outside the
      // padding-edge. We need better APIs for getting the various boxes from a frame.
      nsIScrollableFrame* scrollFrame;
      CallQueryInterface(aLastRS->frame, &scrollFrame);
      nsMargin scrollbars(0,0,0,0);
      if (scrollFrame) {
        nsBoxLayoutState dummyState(aLastRS->frame->GetPresContext());
        scrollbars = scrollFrame->GetDesiredScrollbarSizes(&dummyState);
        // XXX We should account for the horizontal scrollbar too --- but currently
        // nsGfxScrollFrame assumes nothing depends on the presence (or absence) of
        // a horizontal scrollbar, so accounting for it would create incremental
        // reflow bugs.
        //if (!lastButOneRS->mFlags.mAssumingHScrollbar) {
          scrollbars.top = scrollbars.bottom = 0;
        //}
        if (!lastButOneRS->mFlags.mAssumingVScrollbar) {
          scrollbars.left = scrollbars.right = 0;
        }
      }
      // We found a reflow state for the outermost wrapping frame, so use
      // its computed metrics if available
      if (aLastRS->mComputedWidth != NS_UNCONSTRAINEDSIZE) {
        cbSize.width = PR_MAX(0,
          aLastRS->mComputedWidth + aLastRS->mComputedPadding.LeftRight() - scrollbars.LeftRight());
      }
      if (aLastRS->mComputedHeight != NS_UNCONSTRAINEDSIZE) {
        cbSize.height = PR_MAX(0,
          aLastRS->mComputedHeight + aLastRS->mComputedPadding.TopBottom() - scrollbars.TopBottom());
      }
    }
  }

  return cbSize;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void DestroyOverflowLines ( void aFrame,
nsIAtom aPropertyName,
void aPropertyValue,
void aDtorData 
) [static]

Definition at line 5186 of file nsBlockFrame.cpp.

{
  if (aPropertyValue) {
    nsLineList* lines = NS_STATIC_CAST(nsLineList*, aPropertyValue);
    nsPresContext *context = NS_STATIC_CAST(nsPresContext*, aDtorData);
    nsLineBox::DeleteLineList(context, *lines);
    delete lines;
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void DirtyLinesWithDirtyContinuations ( const nsLineList::iterator aLineStart,
const nsLineList::iterator aLineEnd 
) [static]

Definition at line 2067 of file nsBlockFrame.cpp.

{
  // The line we're looking at right now
  nsLineList::iterator line(aLineEnd);

  // Whether the line following the current one is dirty
  PRBool nextLineDirty = PR_FALSE;
  
  while (line != aLineStart) {
    --line;

    if (nextLineDirty && line->IsInline() && line->IsLineWrapped()) {
      line->MarkDirty();
      // Note that nextLineDirty is already true and |line| will be the "next
      // line" next time through this loop, and we just marked it dirty, so
      // just leave nextLineDirty as true.
    } else {
      nextLineDirty = line->IsDirty();
    }
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void DumpLine ( const nsBlockReflowState aState,
nsLineBox aLine,
nscoord  aDeltaY,
PRInt32  aDeltaIndent 
) [static]

Definition at line 2118 of file nsBlockFrame.cpp.

                                                            {
#ifdef DEBUG
  if (nsBlockFrame::gNoisyReflow) {
    nsRect lca(aLine->GetCombinedArea());
    nsBlockFrame::IndentBy(stdout, nsBlockFrame::gNoiseIndent + aDeltaIndent);
    printf("line=%p mY=%d dirty=%s oldBounds={%d,%d,%d,%d} oldCombinedArea={%d,%d,%d,%d} deltaY=%d mPrevBottomMargin=%d childCount=%d\n",
           NS_STATIC_CAST(void*, aLine), aState.mY,
           aLine->IsDirty() ? "yes" : "no",
           aLine->mBounds.x, aLine->mBounds.y,
           aLine->mBounds.width, aLine->mBounds.height,
           lca.x, lca.y, lca.width, lca.height,
           aDeltaY, aState.mPrevBottomMargin.get(), aLine->GetChildCount());
  }
#endif
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void GetFrameFromLine ( const nsRect aLineArea,
const nsPoint aTmp,
nsBlockFrame::line_iterator aLine,
nsFramePaintLayer  aWhichLayer,
nsIFrame **  aFrame 
) [inline, static]

Definition at line 6890 of file nsBlockFrame.cpp.

                                                                   {
  if (aLineArea.Contains(aTmp)) {
    nsIFrame* kid = aLine->mFirstChild;
    PRInt32 n = aLine->GetChildCount();
    while (--n >= 0) {
      nsIFrame *hit;
      nsresult rv = kid->GetFrameForPoint(aTmp, aWhichLayer, &hit);
      
      if (NS_SUCCEEDED(rv) && hit) {
        *aFrame = hit;
      }
      kid = kid->GetNextSibling();
    }
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void GetRectDifferenceStrips ( const nsRect aR1,
const nsRect aR2,
nsRect aHStrip,
nsRect aVStrip 
) [static]

Takes two rectangles whose origins must be the same, and computes the difference between their union and their intersection as two rectangles.

(This difference is a superset of the difference between the two rectangles.)

Definition at line 2612 of file nsBlockFrame.cpp.

                                                                      {
  NS_ASSERTION(aR1.TopLeft() == aR2.TopLeft(),
               "expected rects at the same position");
  nsRect unionRect(aR1.x, aR1.y, PR_MAX(aR1.width, aR2.width),
                   PR_MAX(aR1.height, aR2.height));
  nscoord VStripStart = PR_MIN(aR1.width, aR2.width);
  nscoord HStripStart = PR_MIN(aR1.height, aR2.height);
  *aVStrip = unionRect;
  aVStrip->x += VStripStart;
  aVStrip->width -= VStripStart;
  *aHStrip = unionRect;
  aHStrip->y += HStripStart;
  aHStrip->height -= HStripStart;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static PRBool HaveAutoWidth ( const nsHTMLReflowState aReflowState) [static]

Definition at line 1166 of file nsBlockFrame.cpp.

{
  return NS_UNCONSTRAINEDSIZE == aReflowState.mComputedWidth ||
         eStyleUnit_Auto == aReflowState.mStylePosition->mWidth.GetUnit();
}

Here is the call graph for this function:

Here is the caller graph for this function:

static PRBool IsContinuationPlaceholder ( nsIFrame aFrame) [static]

Definition at line 550 of file nsBlockFrame.cpp.

{
  return aFrame->GetPrevInFlow() &&
    nsLayoutAtoms::placeholderFrame == aFrame->GetType();
}

Here is the call graph for this function:

Here is the caller graph for this function:

PRBool IsMarginZero ( nsStyleUnit  aUnit,
nsStyleCoord aCoord 
) [inline]

Definition at line 3109 of file nsBlockFrame.cpp.

{
    return (aUnit == eStyleUnit_Null ||
            aUnit == eStyleUnit_Auto ||
            (aUnit == eStyleUnit_Coord && aCoord.GetCoordValue() == 0) ||
            (aUnit == eStyleUnit_Percent && aCoord.GetPercentValue() == 0.0));
}

Here is the call graph for this function:

Here is the caller graph for this function:

PRBool IsPaddingZero ( nsStyleUnit  aUnit,
nsStyleCoord aCoord 
) [inline]

Definition at line 3101 of file nsBlockFrame.cpp.

{
    return (aUnit == eStyleUnit_Null ||
            (aUnit == eStyleUnit_Coord && aCoord.GetCoordValue() == 0) ||
            (aUnit == eStyleUnit_Percent && aCoord.GetPercentValue() == 0.0));
}

Here is the call graph for this function:

Here is the caller graph for this function:

static PRBool IsPercentageAwareChild ( const nsIFrame aFrame) [static]

Definition at line 1176 of file nsBlockFrame.cpp.

{
  NS_ASSERTION(aFrame, "null frame is not allowed");

  const nsStyleMargin* margin = aFrame->GetStyleMargin();
  if (nsLineLayout::IsPercentageUnitSides(&margin->mMargin)) {
    return PR_TRUE;
  }

  const nsStylePadding* padding = aFrame->GetStylePadding();
  if (nsLineLayout::IsPercentageUnitSides(&padding->mPadding)) {
    return PR_TRUE;
  }

  // Note that borders can't be aware of percentages

  const nsStylePosition* pos = aFrame->GetStylePosition();

  if (eStyleUnit_Percent == pos->mWidth.GetUnit()
    || eStyleUnit_Percent == pos->mMaxWidth.GetUnit()
    || eStyleUnit_Percent == pos->mMinWidth.GetUnit()
    || eStyleUnit_Percent == pos->mHeight.GetUnit()
    || eStyleUnit_Percent == pos->mMinHeight.GetUnit()
    || eStyleUnit_Percent == pos->mMaxHeight.GetUnit()
    || nsLineLayout::IsPercentageUnitSides(&pos->mOffset)) { // XXX need more here!!!
    return PR_TRUE;
  }

  return PR_FALSE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static PRBool LineHasClear ( nsLineBox aLine) [static]

Definition at line 2092 of file nsBlockFrame.cpp.

                                             {
  return aLine->GetBreakTypeBefore() || aLine->HasFloatBreakAfter()
    || (aLine->IsBlock() && (aLine->mFirstChild->GetStateBits() & NS_BLOCK_HAS_CLEAR_CHILDREN));
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void MarkAllDescendantLinesDirty ( nsBlockFrame aBlock) [static]

Definition at line 5524 of file nsBlockFrame.cpp.

{
  nsLineList::iterator line = aBlock->begin_lines();
  nsLineList::iterator endLine = aBlock->end_lines();
  while (line != endLine) {
    if (line->IsBlock()) {
      nsIFrame* f = line->mFirstChild;
      void* bf;
      if (NS_SUCCEEDED(f->QueryInterface(kBlockFrameCID, &bf))) {
        MarkAllDescendantLinesDirty(NS_STATIC_CAST(nsBlockFrame*, f));
      }
    }
    line->MarkDirty();
    ++line;
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void MarkSameSpaceManagerLinesDirty ( nsBlockFrame aBlock) [static]

Definition at line 5541 of file nsBlockFrame.cpp.

{
  nsBlockFrame* blockWithSpaceMgr = aBlock;
  while (!(blockWithSpaceMgr->GetStateBits() & NS_BLOCK_SPACE_MGR)) {
    void* bf;
    if (NS_FAILED(blockWithSpaceMgr->GetParent()->
                  QueryInterface(kBlockFrameCID, &bf))) {
      break;
    }
    blockWithSpaceMgr = NS_STATIC_CAST(nsBlockFrame*, blockWithSpaceMgr->GetParent());
  }
    
  // Mark every line at and below the line where the float was
  // dirty, and mark their lines dirty too. We could probably do
  // something more efficient --- e.g., just dirty the lines that intersect
  // the float vertically.
  MarkAllDescendantLinesDirty(blockWithSpaceMgr);
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult NS_NewBlockFrame ( nsIPresShell aPresShell,
nsIFrame **  aNewFrame,
PRUint32  aFlags 
)

Definition at line 265 of file nsBlockFrame.cpp.

{
  NS_PRECONDITION(aNewFrame, "null OUT ptr");
  if (nsnull == aNewFrame) {
    return NS_ERROR_NULL_POINTER;
  }
  nsBlockFrame* it = new (aPresShell) nsBlockFrame;
  if (nsnull == it) {
    return NS_ERROR_OUT_OF_MEMORY;
  }
  it->SetFlags(aFlags);
  *aNewFrame = it;
  return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void PaintLine ( const nsRect aLineArea,
const nsRect aDirtyRect,
nsBlockFrame::line_iterator aLine,
PRInt32  aDepth,
PRInt32 aDrawnLines,
nsPresContext aPresContext,
nsIRenderingContext aRenderingContext,
nsFramePaintLayer  aWhichLayer,
nsBlockFrame aFrame 
) [inline, static]

Definition at line 6464 of file nsBlockFrame.cpp.

                                                               {
  // If the line's combined area (which includes child frames that
  // stick outside of the line's bounding box or our bounding box)
  // intersects the dirty rect then paint the line.
  if (aLineArea.Intersects(aDirtyRect)) {
#ifdef DEBUG
    DebugOutputDrawLine(aWhichLayer, aDepth, aLine.get(), PR_TRUE);
    if (nsBlockFrame::gLamePaintMetrics) {
      aDrawnLines++;
    }
#endif
    nsIFrame* kid = aLine->mFirstChild;
    PRInt32 n = aLine->GetChildCount();
    while (--n >= 0) {
      aFrame->PaintChild(aPresContext, aRenderingContext, aDirtyRect, kid,
                         aWhichLayer);
      kid = kid->GetNextSibling();
    }
  }
#ifdef DEBUG
  else {
    DebugOutputDrawLine(aWhichLayer, aDepth, aLine.get(), PR_FALSE);
  }
#endif  
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void PlaceFrameView ( nsIFrame aFrame) [static]

Definition at line 2991 of file nsBlockFrame.cpp.

Here is the call graph for this function:

Here is the caller graph for this function:

static nsresult RemoveBlockChild ( nsIFrame aFrame,
PRBool  aDestroyFrames 
) [static]

Definition at line 5672 of file nsBlockFrame.cpp.

{
  if (!aFrame)
    return NS_OK;

  nsBlockFrame* nextBlock = NS_STATIC_CAST(nsBlockFrame*, aFrame->GetParent());
  NS_ASSERTION(nextBlock->GetType() == nsLayoutAtoms::blockFrame ||
               nextBlock->GetType() == nsLayoutAtoms::areaFrame,
               "Our child's continuation's parent is not a block?");
  return nextBlock->DoRemoveFrame(aFrame, aDestroyFrames);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void ReparentFrame ( nsIFrame aFrame,
nsIFrame aOldParent,
nsIFrame aNewParent 
) [static]

Definition at line 556 of file nsBlockFrame.cpp.

                                                {
  NS_ASSERTION(aOldParent == aFrame->GetParent(),
               "Parent not consistent with exepectations");

  aFrame->SetParent(aNewParent);

  // When pushing and pulling frames we need to check for whether any
  // views need to be reparented
  nsHTMLContainerFrame::ReparentFrameView(aFrame->GetPresContext(), aFrame,
                                          aOldParent, aNewParent);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static PRBool ShouldPutNextSiblingOnNewLine ( nsIFrame aLastFrame) [static]

Definition at line 5360 of file nsBlockFrame.cpp.

{
  nsIAtom* type = aLastFrame->GetType();
  if (type == nsLayoutAtoms::brFrame)
    return PR_TRUE;
  if (type == nsLayoutAtoms::placeholderFrame)
    return IsContinuationPlaceholder(aLastFrame);
  return PR_FALSE;
}

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

Definition at line 262 of file nsBlockFrame.cpp.

Definition at line 93 of file nsBlockFrame.cpp.