Add a frame state bit for whether a frame is a container for font size inflation (Bug 706609, patch 1) r=roc

This moves the logic currently in
nsLayoutUtils::IsContainerForFontSizeInflation into frame initialization
so that we can (later, for bug 706193) make that logic more complicated.
This commit is contained in:
L. David Baron 2012-01-24 17:21:28 -08:00
parent 0509f68014
commit 06fe8e9788
4 changed files with 78 additions and 51 deletions

View File

@ -4681,54 +4681,6 @@ nsLayoutUtils::FontSizeInflationInner(const nsIFrame *aFrame,
return (1.0f / ratio) + (1.0f / 3.0f);
}
/* static */ bool
nsLayoutUtils::IsContainerForFontSizeInflation(const nsIFrame *aFrame)
{
/*
* Font size inflation is build around the idea that we're inflating
* the fonts for a pan-and-zoom UI so that when the user scales up a
* block or other container to fill the width of the device, the fonts
* will be readable. To do this, we need to pick what counts as a
* container.
*
* From a code perspective, the only hard requirement is that frames
* that are line participants
* (nsIFrame::IsFrameOfType(nsIFrame::eLineParticipant)) are never
* containers, since line layout assumes that the inflation is
* consistent within a line.
*
* This is not an imposition, since we obviously want a bunch of text
* (possibly with inline elements) flowing within a block to count the
* block (or higher) as its container.
*
* We also want form controls, including the text in the anonymous
* content inside of them, to match each other and the text next to
* them, so they and their anonymous content should also not be a
* container.
*
* However, because we can't reliably compute sizes across XUL during
* reflow, any XUL frame with a XUL parent is always a container.
*
* There are contexts where it would be nice if some blocks didn't
* count as a container, so that, for example, an indented quotation
* didn't end up with a smaller font size. However, it's hard to
* distinguish these situations where we really do want the indented
* thing to count as a container, so we don't try, and blocks are
* always containers.
*/
bool isInline = (aFrame->GetStyleDisplay()->mDisplay ==
NS_STYLE_DISPLAY_INLINE ||
(aFrame->GetContent() &&
aFrame->GetContent()->IsInNativeAnonymousSubtree())) &&
!(aFrame->IsBoxFrame() && aFrame->GetParent() &&
aFrame->GetParent()->IsBoxFrame());
NS_ASSERTION(!aFrame->IsFrameOfType(nsIFrame::eLineParticipant) || isInline,
"line participants must not be containers");
NS_ASSERTION(aFrame->GetType() != nsGkAtoms::bulletFrame || isInline,
"bullets should not be containers");
return !isInline;
}
static bool
ShouldInflateFontsForContainer(const nsIFrame *aFrame)
{

View File

@ -1507,7 +1507,10 @@ public:
* Return whether this is a frame whose width is used when computing
* the font size inflation of its descendants.
*/
static bool IsContainerForFontSizeInflation(const nsIFrame *aFrame);
static bool IsContainerForFontSizeInflation(const nsIFrame *aFrame)
{
return aFrame->GetStateBits() & NS_FRAME_FONT_INFLATION_CONTAINER;
}
/**
* Return the font size inflation *ratio* for a given frame. This is

View File

@ -424,6 +424,60 @@ NS_QUERYFRAME_TAIL_INHERITANCE_ROOT
/////////////////////////////////////////////////////////////////////////////
// nsIFrame
static bool
IsFontSizeInflationContainer(nsIFrame* aFrame,
const nsStyleDisplay* aStyleDisplay)
{
/*
* Font size inflation is built around the idea that we're inflating
* the fonts for a pan-and-zoom UI so that when the user scales up a
* block or other container to fill the width of the device, the fonts
* will be readable. To do this, we need to pick what counts as a
* container.
*
* From a code perspective, the only hard requirement is that frames
* that are line participants
* (nsIFrame::IsFrameOfType(nsIFrame::eLineParticipant)) are never
* containers, since line layout assumes that the inflation is
* consistent within a line.
*
* This is not an imposition, since we obviously want a bunch of text
* (possibly with inline elements) flowing within a block to count the
* block (or higher) as its container.
*
* We also want form controls, including the text in the anonymous
* content inside of them, to match each other and the text next to
* them, so they and their anonymous content should also not be a
* container.
*
* However, because we can't reliably compute sizes across XUL during
* reflow, any XUL frame with a XUL parent is always a container.
*
* There are contexts where it would be nice if some blocks didn't
* count as a container, so that, for example, an indented quotation
* didn't end up with a smaller font size. However, it's hard to
* distinguish these situations where we really do want the indented
* thing to count as a container, so we don't try, and blocks are
* always containers.
*/
bool isInline = (aStyleDisplay->mDisplay == NS_STYLE_DISPLAY_INLINE ||
(aFrame->GetContent() &&
aFrame->GetContent()->IsInNativeAnonymousSubtree())) &&
!(aFrame->IsBoxFrame() && aFrame->GetParent() &&
aFrame->GetParent()->IsBoxFrame());
NS_ASSERTION(!aFrame->IsFrameOfType(nsIFrame::eLineParticipant) ||
isInline ||
// br frames and mathml frames report being line
// participants even when their position or display is
// set
aFrame->GetType() == nsGkAtoms::brFrame ||
aFrame->IsFrameOfType(nsIFrame::eMathML),
"line participants must not be containers");
NS_ASSERTION(aFrame->GetType() != nsGkAtoms::bulletFrame || isInline,
"bullets should not be containers");
return !isInline;
}
NS_IMETHODIMP
nsFrame::Init(nsIContent* aContent,
nsIFrame* aParent,
@ -457,12 +511,25 @@ nsFrame::Init(nsIContent* aContent,
mState |= state & (NS_FRAME_INDEPENDENT_SELECTION |
NS_FRAME_GENERATED_CONTENT);
}
if (GetStyleDisplay()->HasTransform()) {
const nsStyleDisplay *disp = GetStyleDisplay();
if (disp->HasTransform()) {
// The frame gets reconstructed if we toggle the -moz-transform
// property, so we can set this bit here and then ignore it.
mState |= NS_FRAME_MAY_BE_TRANSFORMED;
}
if (nsLayoutUtils::FontSizeInflationEnabled(PresContext())
#ifdef DEBUG
// We have assertions that check inflation invariants even when
// font size inflation is not enabled.
|| true
#endif
) {
if (IsFontSizeInflationContainer(this, disp)) {
mState |= NS_FRAME_FONT_INFLATION_CONTAINER;
}
}
DidSetStyleContext(nsnull);
if (IsBoxWrapped())

View File

@ -298,6 +298,11 @@ typedef PRUint64 nsFrameState;
// This is only set during painting
#define NS_FRAME_FORCE_DISPLAY_LIST_DESCEND_INTO NS_FRAME_STATE_BIT(40)
// Is this frame a container for font size inflation, i.e., is it a
// frame whose width is used to determine the inflation factor for
// everything whose nearest ancestor container for this frame?
#define NS_FRAME_FONT_INFLATION_CONTAINER NS_FRAME_STATE_BIT(41)
// Box layout bits
#define NS_STATE_IS_HORIZONTAL NS_FRAME_STATE_BIT(22)
#define NS_STATE_IS_DIRECTION_NORMAL NS_FRAME_STATE_BIT(31)