Back to index

lightning-sunbird  0.9+nobinonly
Classes | Defines | Enumerations | Functions | Variables
nsHTMLReflowState.cpp File Reference
#include "nsCOMPtr.h"
#include "nsStyleConsts.h"
#include "nsCSSAnonBoxes.h"
#include "nsFrame.h"
#include "nsIContent.h"
#include "nsHTMLAtoms.h"
#include "nsPresContext.h"
#include "nsIPresShell.h"
#include "nsLayoutAtoms.h"
#include "nsIDeviceContext.h"
#include "nsIRenderingContext.h"
#include "nsIFontMetrics.h"
#include "nsBlockFrame.h"
#include "nsLineBox.h"
#include "nsImageFrame.h"
#include "nsIServiceManager.h"
#include "nsIPercentHeightObserver.h"
#include "nsContentUtils.h"
#include "nsLayoutUtils.h"

Go to the source code of this file.

Classes

struct  nsHypotheticalBox

Defines

#define NORMAL_LINE_HEIGHT_FACTOR   1.2f

Enumerations

enum  eNormalLineHeightControl { eUninitialized = -1, eNoExternalLeading = 0, eIncludeExternalLeading, eCompensateLeading }

Functions

static PRBool CheckNextInFlowParenthood (nsIFrame *aFrame, nsIFrame *aParent)
static nsIFrameGetNearestContainingBlock (nsIFrame *aFrame, nsMargin &aContentArea)
static PRBool GetIntrinsicSizeFor (nsIFrame *aFrame, nsSize &aIntrinsicSize)
static nsIFrameFindImmediateChildOf (nsIFrame *aParent, nsIFrame *aDescendantFrame)
static PRBool AreAllEarlierInFlowFramesEmpty (nsIFrame *aFrame, nsIFrame *aDescendant, PRBool *aFound)
 Returns PR_TRUE iff a pre-order traversal of the normal child frames rooted at aFrame finds no non-empty frame before aDescendant.
nscoord GetVerticalMarginBorderPadding (const nsHTMLReflowState *aReflowState)
nscoord CalcQuirkContainingBlockHeight (const nsHTMLReflowState &aReflowState)
 PrefsChanged (const char *aPrefName, void *instance)
static PRBool BlinkIsAllowed (void)
static nscoord GetNormalLineHeight (nsIFontMetrics *aFontMetrics)
static nscoord ComputeLineHeight (nsPresContext *aPresContext, nsIRenderingContext *aRenderingContext, nsStyleContext *aStyleContext)

Variables

static PRPackedBool sPrefIsLoaded = PR_FALSE
static PRPackedBool sBlinkIsAllowed = PR_TRUE

Define Documentation

Definition at line 2188 of file nsHTMLReflowState.cpp.


Enumeration Type Documentation

Enumerator:
eUninitialized 
eNoExternalLeading 
eIncludeExternalLeading 
eCompensateLeading 

Definition at line 70 of file nsHTMLReflowState.cpp.

                              {
  eUninitialized = -1,
  eNoExternalLeading = 0,   // does not include external leading 
  eIncludeExternalLeading,  // use whatever value font vendor provides
  eCompensateLeading        // compensate leading if leading provided by font vendor is not enough
};

Function Documentation

static PRBool AreAllEarlierInFlowFramesEmpty ( nsIFrame aFrame,
nsIFrame aDescendant,
PRBool aFound 
) [static]

Returns PR_TRUE iff a pre-order traversal of the normal child frames rooted at aFrame finds no non-empty frame before aDescendant.

Definition at line 794 of file nsHTMLReflowState.cpp.

                                         {
  if (aFrame == aDescendant) {
    *aFound = PR_TRUE;
    return PR_TRUE;
  }
  if (!aFrame->IsSelfEmpty()) {
    *aFound = PR_FALSE;
    return PR_FALSE;
  }
  for (nsIFrame* f = aFrame->GetFirstChild(nsnull); f; f = f->GetNextSibling()) {
    PRBool allEmpty = AreAllEarlierInFlowFramesEmpty(f, aDescendant, aFound);
    if (*aFound || !allEmpty) {
      return allEmpty;
    }
  }
  *aFound = PR_FALSE;
  return PR_TRUE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static PRBool BlinkIsAllowed ( void  ) [static]

Definition at line 1655 of file nsHTMLReflowState.cpp.

{
  if (!sPrefIsLoaded) {
    // Set up a listener and check the initial value
    nsContentUtils::RegisterPrefCallback("browser.blink_allowed", PrefsChanged,
                                         nsnull);
    PrefsChanged(nsnull, nsnull);
    sPrefIsLoaded = PR_TRUE;
  }
  return sBlinkIsAllowed;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1460 of file nsHTMLReflowState.cpp.

{
  nsHTMLReflowState* firstAncestorRS = nsnull; // a candidate for html frame
  nsHTMLReflowState* secondAncestorRS = nsnull; // a candidate for body frame
  
  // initialize the default to NS_AUTOHEIGHT as this is the containings block
  // computed height when this function is called. It is possible that we 
  // don't alter this height especially if we are restricted to one level
  nscoord result = NS_AUTOHEIGHT; 
                             
  const nsHTMLReflowState* rs = &aReflowState;
  for (; rs && rs->frame; rs = (nsHTMLReflowState *)(rs->parentReflowState)) { 
    nsIAtom* frameType = rs->frame->GetType();
    // if the ancestor is auto height then skip it and continue up if it 
    // is the first block/area frame and possibly the body/html
    if (nsLayoutAtoms::blockFrame == frameType ||
        nsLayoutAtoms::areaFrame == frameType ||
        nsLayoutAtoms::scrollFrame == frameType) {
      
      if (nsLayoutAtoms::areaFrame == frameType) {
        // Skip over scrolled-content area frames
        if (rs->frame->GetStyleContext()->GetPseudoType() ==
            nsCSSAnonBoxes::scrolledContent) {
          continue;
        }
      }

      secondAncestorRS = firstAncestorRS;
      firstAncestorRS = (nsHTMLReflowState*)rs;

      // If the current frame we're looking at is positioned, we don't want to
      // go any further (see bug 221784).  The behavior we want here is: 1) If
      // not auto-height, use this as the percentage base.  2) If auto-height,
      // keep looking, unless the frame is positioned.
      if (NS_AUTOHEIGHT == rs->mComputedHeight) {
        if (rs->frame->GetStyleDisplay()->IsAbsolutelyPositioned()) {
          break;
        } else {
          continue;
        }
      }
    }
    else if (nsLayoutAtoms::canvasFrame == frameType) {
      // Use scroll frames' computed height if we have one, this will
      // allow us to get viewport height for native scrollbars.
      nsHTMLReflowState* scrollState = (nsHTMLReflowState *)rs->parentReflowState;
      if (nsLayoutAtoms::scrollFrame == scrollState->frame->GetType()) {
        rs = scrollState;
      }
    }
    else if (nsLayoutAtoms::pageContentFrame == frameType) {
      nsIFrame* prevInFlow = rs->frame->GetPrevInFlow();
      // only use the page content frame for a height basis if it is the first in flow
      if (prevInFlow) 
        break;
    }
    else {
      break;
    }

    // if the ancestor is the page content frame then the percent base is 
    // the avail height, otherwise it is the computed height
    result = (nsLayoutAtoms::pageContentFrame == frameType)
             ? rs->availableHeight : rs->mComputedHeight;
    // if unconstrained - don't sutract borders - would result in huge height
    if (NS_AUTOHEIGHT == result) return result;

    // if we got to the canvas or page content frame, then subtract out 
    // margin/border/padding for the BODY and HTML elements
    if ((nsLayoutAtoms::canvasFrame == frameType) || 
        (nsLayoutAtoms::pageContentFrame == frameType)) {

      result -= GetVerticalMarginBorderPadding(firstAncestorRS); 
      result -= GetVerticalMarginBorderPadding(secondAncestorRS); 

#ifdef DEBUG
      // make sure the first ancestor is the HTML and the second is the BODY
      if (firstAncestorRS) {
        nsIContent* frameContent = firstAncestorRS->frame->GetContent();
        if (frameContent) {
          nsIAtom *contentTag = frameContent->Tag();
          NS_ASSERTION(contentTag == nsHTMLAtoms::html, "First ancestor is not HTML");
        }
      }
      if (secondAncestorRS) {
        nsIContent* frameContent = secondAncestorRS->frame->GetContent();
        if (frameContent) {
          nsIAtom *contentTag = frameContent->Tag();
          NS_ASSERTION(contentTag == nsHTMLAtoms::body, "Second ancestor is not BODY");
        }
      }
#endif
      
    }
    // if we got to the html frame, then subtract out 
    // margin/border/padding for the BODY element
    else if (nsLayoutAtoms::areaFrame == frameType) {
      // make sure it is the body
      if (nsLayoutAtoms::canvasFrame == rs->parentReflowState->frame->GetType()) {
        result -= GetVerticalMarginBorderPadding(secondAncestorRS);
      }
    }
    break;
  }

  // Make sure not to return a negative height here!
  return PR_MAX(result, 0);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static PRBool CheckNextInFlowParenthood ( nsIFrame aFrame,
nsIFrame aParent 
) [static]

Definition at line 162 of file nsHTMLReflowState.cpp.

{
  nsIFrame* frameNext = aFrame->GetNextInFlow();
  nsIFrame* parentNext = aParent->GetNextInFlow();
  return frameNext && parentNext && frameNext->GetParent() == parentNext;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static nscoord ComputeLineHeight ( nsPresContext aPresContext,
nsIRenderingContext aRenderingContext,
nsStyleContext aStyleContext 
) [static]

Definition at line 2230 of file nsHTMLReflowState.cpp.

{
  NS_PRECONDITION(nsnull != aRenderingContext, "no rendering context");

  nscoord lineHeight;

  const nsStyleFont* font = aStyleContext->GetStyleFont();
  const nsStyleCoord& lhCoord = aStyleContext->GetStyleText()->mLineHeight;
  
  nsStyleUnit unit = lhCoord.GetUnit();

  if (unit == eStyleUnit_Coord) {
    // For length values just use the pre-computed value
    lineHeight = lhCoord.GetCoordValue();
  } else if (unit == eStyleUnit_Factor) {
    // For factor units the computed value of the line-height property 
    // is found by multiplying the factor by the font's computed size
    // (adjusted for min-size prefs and text zoom).
    float factor = lhCoord.GetFactorValue();
    lineHeight = NSToCoordRound(factor * font->mFont.size);
  } else {
    NS_ASSERTION(eStyleUnit_Normal == unit, "bad unit");
    nsCOMPtr<nsIDeviceContext> deviceContext;
    aRenderingContext->GetDeviceContext(*getter_AddRefs(deviceContext));
    const nsStyleVisibility* vis = aStyleContext->GetStyleVisibility();
    nsCOMPtr<nsIFontMetrics> fm;
    deviceContext->GetMetricsFor(font->mFont, vis->mLangGroup,
                                 *getter_AddRefs(fm));
    lineHeight = GetNormalLineHeight(fm);
  }
  return lineHeight;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static nsIFrame* FindImmediateChildOf ( nsIFrame aParent,
nsIFrame aDescendantFrame 
) [static]

Definition at line 773 of file nsHTMLReflowState.cpp.

{
  nsIFrame* result = aDescendantFrame;

  while (result) {
    nsIFrame* parent = result->GetParent();
    if (parent == aParent) {
      break;
    }

    // The frame is not an immediate child of aParent so walk up another level
    result = parent;
  }

  return result;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static PRBool GetIntrinsicSizeFor ( nsIFrame aFrame,
nsSize aIntrinsicSize 
) [static]

Definition at line 706 of file nsHTMLReflowState.cpp.

{
  // See if it is an image frame
  PRBool    result = PR_FALSE;

  // Currently the only type of replaced frame that we can get the intrinsic
  // size for is an image frame
  // XXX We should add back the GetReflowMetrics() function and one of the
  // things should be the intrinsic size...
  if (aFrame->GetType() == nsLayoutAtoms::imageFrame) {
    nsImageFrame* imageFrame = (nsImageFrame*)aFrame;

    imageFrame->GetIntrinsicImageSize(aIntrinsicSize);
    result = (aIntrinsicSize != nsSize(0, 0));
  }
  return result;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static nsIFrame* GetNearestContainingBlock ( nsIFrame aFrame,
nsMargin aContentArea 
) [static]

Definition at line 658 of file nsHTMLReflowState.cpp.

{
  for (aFrame = aFrame->GetParent(); aFrame && !aFrame->IsContainingBlock();
       aFrame = aFrame->GetParent())
    /* do nothing */;

  if (aFrame) {
    nsSize  size = aFrame->GetSize();

    aContentArea.left = 0;
    aContentArea.top = 0;
    aContentArea.right = size.width;
    aContentArea.bottom = size.height;
  
    // Subtract off for border and padding. If it can't be computed because
    // it's percentage based (for example) then just ignore it
    nsStyleBorderPadding  bPad;
    nsMargin              borderPadding;
    nsStyleContext* styleContext = aFrame->GetStyleContext();
    styleContext->GetBorderPaddingFor(bPad);
    if (bPad.GetBorderPadding(borderPadding)) {
      aContentArea.left += borderPadding.left;
      aContentArea.top += borderPadding.top;
      aContentArea.right -= borderPadding.right;
      aContentArea.bottom -= borderPadding.bottom;
    }
  }

  return aFrame;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static nscoord GetNormalLineHeight ( nsIFontMetrics aFontMetrics) [static]

Definition at line 2198 of file nsHTMLReflowState.cpp.

{
  NS_PRECONDITION(nsnull != aFontMetrics, "no font metrics");

  nscoord normalLineHeight;

#ifdef FONT_LEADING_APIS_V2
  nscoord externalLeading, internalLeading, emHeight;
  aFontMetrics->GetExternalLeading(externalLeading);
  aFontMetrics->GetInternalLeading(internalLeading);
  aFontMetrics->GetEmHeight(emHeight);
  switch (GetNormalLineHeightCalcControl()) {
  case eIncludeExternalLeading:
    normalLineHeight = emHeight+ internalLeading + externalLeading;
    break;
  case eCompensateLeading:
    if (!internalLeading && !externalLeading)
      normalLineHeight = NSToCoordRound(emHeight * NORMAL_LINE_HEIGHT_FACTOR);
    else
      normalLineHeight = emHeight+ internalLeading + externalLeading;
    break;
  default:
    //case eNoExternalLeading:
    normalLineHeight = emHeight + internalLeading;
  }
#else
  aFontMetrics->GetNormalLineHeight(normalLineHeight);
#endif // FONT_LEADING_APIS_V2
  return normalLineHeight;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1432 of file nsHTMLReflowState.cpp.

{
  nscoord result = 0;
  if (!aReflowState) return result;

  // zero auto margins
  nsMargin margin = aReflowState->mComputedMargin;
  if (NS_AUTOMARGIN == margin.top) 
    margin.top = 0;
  if (NS_AUTOMARGIN == margin.bottom) 
    margin.bottom = 0;

  result += margin.top + margin.bottom;
  result += aReflowState->mComputedBorderPadding.top + 
            aReflowState->mComputedBorderPadding.bottom;

  return result;
}

Here is the caller graph for this function:

PrefsChanged ( const char *  aPrefName,
void instance 
)

Definition at line 1644 of file nsHTMLReflowState.cpp.

{
  sBlinkIsAllowed =
    nsContentUtils::GetBoolPref("browser.blink_allowed", sBlinkIsAllowed);

  return 0; /* PREF_OK */
}

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

Definition at line 68 of file nsHTMLReflowState.cpp.

Definition at line 67 of file nsHTMLReflowState.cpp.