Back to index

lightning-sunbird  0.9+nobinonly
Public Types | Public Member Functions | Protected Attributes
IncrementalReflow Class Reference

Used to build and maintain the incremental reflow tree, and dispatch incremental reflows to individual reflow roots. More...

List of all members.

Public Types

enum  AddCommandResult { eEnqueued, eTryLater, eCancel, eOOM }
 Add a reflow command to the set of commands that are to be dispatched in the incremental reflow. More...

Public Member Functions

 ~IncrementalReflow ()
AddCommandResult AddCommand (nsPresContext *aPresContext, nsHTMLReflowCommand *aCommand)
void Dispatch (nsPresContext *aPresContext, nsHTMLReflowMetrics &aDesiredSize, const nsSize &aMaxSize, nsIRenderingContext &aRendContext)
 Dispatch the incremental reflow.

Protected Attributes

nsAutoVoidArray mRoots
 The set of incremental reflow roots.

Detailed Description

Used to build and maintain the incremental reflow tree, and dispatch incremental reflows to individual reflow roots.

Definition at line 846 of file nsPresShell.cpp.


Member Enumeration Documentation

Add a reflow command to the set of commands that are to be dispatched in the incremental reflow.

Enumerator:
eEnqueued 
eTryLater 
eCancel 
eOOM 

Definition at line 855 of file nsPresShell.cpp.

                        {
    eEnqueued, // the command was successfully added
    eTryLater, // the command could not be added; try again
    eCancel,   // the command was not added; delete it
    eOOM       // Out of memory.
  };

Constructor & Destructor Documentation

Definition at line 889 of file nsPresShell.cpp.

{
  for (PRInt32 i = mRoots.Count() - 1; i >= 0; --i)
    delete NS_STATIC_CAST(nsReflowPath *, mRoots[i]);
}

Member Function Documentation

Definition at line 944 of file nsPresShell.cpp.

{
  nsIFrame *frame;
  aCommand->GetTarget(frame);
  NS_ASSERTION(frame != nsnull, "reflow command with no target");

  // Construct the reflow path by walking up the through the frames'
  // parent chain until we reach either a `reflow root' or the root
  // frame in the frame hierarchy.
  nsAutoVoidArray path;
  do {
    path.AppendElement(frame);
  } while (!(frame->GetStateBits() & NS_FRAME_REFLOW_ROOT) &&
           (frame = frame->GetParent()) != nsnull);

  // Pop off the root, add it to the set if it's not there already.
  PRInt32 lastIndex = path.Count() - 1;
  nsIFrame *rootFrame = NS_STATIC_CAST(nsIFrame *, path[lastIndex]);
  path.RemoveElementAt(lastIndex);

  // Prevent an incremental reflow from being posted inside a reflow
  // root if the reflow root's container has not yet been reflowed.
  // This can cause problems like bug 228156.
  if (rootFrame->GetParent() &&
      (rootFrame->GetParent()->GetStateBits() & NS_FRAME_FIRST_REFLOW)) {
    return eCancel;
  }

  nsReflowPath *root = nsnull;

  PRInt32 i;
  for (i = mRoots.Count() - 1; i >= 0; --i) {
    nsReflowPath *r = NS_STATIC_CAST(nsReflowPath *, mRoots[i]);
    if (r->mFrame == rootFrame) {
      root = r;
      break;
    }
  }

  if (! root) {
    root = new nsReflowPath(rootFrame);
    if (! root)
      return eOOM;

    root->mReflowCommand = nsnull;
    mRoots.AppendElement(root);
  }

  // Now walk the path from the root to the leaf, adding to the reflow
  // tree as necessary.
  nsReflowPath *target = root;
  for (i = path.Count() - 1; i >= 0; --i) {
    nsIFrame *f = NS_STATIC_CAST(nsIFrame *, path[i]);
    target = target->EnsureSubtreeFor(f);

    // Out of memory. Ugh.
    if (! target)
      return eOOM;
  }

  // Place the reflow command in the leaf, if one isn't there already.
  if (target->mReflowCommand) {
    // XXXwaterson it's probably possible to have some notion of
    // `promotion' here that would avoid any re-queuing; for example,
    // promote a dirty reflow to a style changed. For now, let's punt
    // and not worry about it.
#ifdef NS_DEBUG
    if (gVerifyReflowFlags & VERIFY_REFLOW_NOISY_RC)
      printf("requeuing command %p because %p was already scheduled "
             "for the same frame",
             (void*)aCommand, (void*)target->mReflowCommand);
#endif

    return eTryLater;
  }

  target->mReflowCommand = aCommand;
  return eEnqueued;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void IncrementalReflow::Dispatch ( nsPresContext aPresContext,
nsHTMLReflowMetrics aDesiredSize,
const nsSize aMaxSize,
nsIRenderingContext aRendContext 
)

Dispatch the incremental reflow.

Definition at line 896 of file nsPresShell.cpp.

{
  for (PRInt32 i = mRoots.Count() - 1; i >= 0; --i) {
    // Send an incremental reflow notification to the first frame in the
    // path.
    nsReflowPath *path = NS_STATIC_CAST(nsReflowPath *, mRoots[i]);
    nsIFrame *first = path->mFrame;

    nsIFrame* root = aPresContext->PresShell()->FrameManager()->GetRootFrame();

    first->WillReflow(aPresContext);
    nsContainerFrame::PositionFrameView(first);

    // If the first frame in the path is the root of the frame
    // hierarchy, then use all the available space. If it's simply a
    // `reflow root', then use the first frame's size as the available
    // space.
    nsSize size;
    if (first == root)
      size = aMaxSize;
    else
      size = first->GetSize();

    nsHTMLReflowState reflowState(aPresContext, first, path,
                                  &aRendContext, size);

    nsReflowStatus status;
    first->Reflow(aPresContext, aDesiredSize, reflowState, status);

    // If an incremental reflow is initiated at a frame other than the
    // root frame, then its desired size had better not change!
    NS_ASSERTION(first == root ||
                 (aDesiredSize.width == size.width && aDesiredSize.height == size.height),
                 "non-root frame's desired size changed during an incremental reflow");

    first->SetSize(nsSize(aDesiredSize.width, aDesiredSize.height));

    nsContainerFrame::SyncFrameViewAfterReflow(aPresContext, first, first->GetView(),
                                               &aDesiredSize.mOverflowArea);

    first->DidReflow(aPresContext, nsnull, NS_FRAME_REFLOW_FINISHED);
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:


Member Data Documentation

nsAutoVoidArray IncrementalReflow::mRoots [protected]

The set of incremental reflow roots.

Definition at line 886 of file nsPresShell.cpp.


The documentation for this class was generated from the following file: