Add a font inflation data structure per block formatting context. (Bug 706193, patch 2) r=roc

This structure is per block formatting context because we have to make a
single inflation decision for things like consecutive runs of paragraphs
of text.  Inflating some paragraphs and not others (within the same
sequence of adjacent paragraphs) based on the amount of text in each one
would be disastrous.  Otherwise it's ideal for the units to be as small
as possible as long as they merge such sequences; therefore this uses a
definition corresponding to CSS's idea of elements that establish new
block formatting contexts.
This commit is contained in:
L. David Baron 2012-04-16 15:32:12 -07:00
Родитель 7d84450b95
Коммит ad38f45fcd
13 изменённых файлов: 212 добавлений и 2 удалений

Просмотреть файл

@ -87,6 +87,7 @@ CPPSRCS = \
nsContainerFrame.cpp \
nsFirstLetterFrame.cpp \
nsFloatManager.cpp \
nsFontInflationData.cpp \
nsFrame.cpp \
nsFrameList.cpp \
nsFrameSetFrame.cpp \

Просмотреть файл

@ -6510,6 +6510,12 @@ nsBlockFrame::Init(nsIContent* aContent,
aPrevInFlow->GetStateBits() & NS_BLOCK_NEEDS_BIDI_RESOLUTION)
AddStateBits(NS_BLOCK_NEEDS_BIDI_RESOLUTION);
if ((GetStateBits() &
(NS_FRAME_FONT_INFLATION_CONTAINER | NS_BLOCK_FLOAT_MGR)) ==
(NS_FRAME_FONT_INFLATION_CONTAINER | NS_BLOCK_FLOAT_MGR)) {
AddStateBits(NS_FRAME_FONT_INFLATION_FLOW_ROOT);
}
return rv;
}

Просмотреть файл

@ -0,0 +1,61 @@
/* vim: set shiftwidth=2 tabstop=8 autoindent cindent expandtab: */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is the font size inflation manager.
*
* The Initial Developer of the Original Code is the Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2012
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* L. David Baron <dbaron@dbaron.org>, Mozilla Corporation (original author)
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/* Per-block-formatting-context manager of font size inflation for pan and zoom UI. */
#include "nsFontInflationData.h"
#include "FramePropertyTable.h"
using namespace mozilla;
static void
DestroyFontInflationData(void *aPropertyValue)
{
delete static_cast<nsFontInflationData*>(aPropertyValue);
}
NS_DECLARE_FRAME_PROPERTY(FontInflationDataProperty, DestroyFontInflationData);
/* static */ nsFontInflationData*
nsFontInflationData::FindFontInflationDataFor(const nsIFrame *aFrame)
{
// We have one set of font inflation data per block formatting context.
const nsIFrame *bfc = FlowRootFor(aFrame);
return static_cast<nsFontInflationData*>(
bfc->Properties().Get(FontInflationDataProperty()));
}

Просмотреть файл

@ -0,0 +1,65 @@
/* vim: set shiftwidth=2 tabstop=8 autoindent cindent expandtab: */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is the font size inflation manager.
*
* The Initial Developer of the Original Code is the Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2012
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* L. David Baron <dbaron@dbaron.org>, Mozilla Corporation (original author)
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/* Per-block-formatting-context manager of font size inflation for pan and zoom UI. */
#ifndef nsFontInflationData_h_
#define nsFontInflationData_h_
#include "nsIFrame.h"
#include "nsLayoutUtils.h"
#include "nsBlockFrame.h"
class nsFontInflationData
{
public:
static nsFontInflationData* FindFontInflationDataFor(const nsIFrame *aFrame);
private:
static const nsIFrame* FlowRootFor(const nsIFrame *aFrame)
{
while (!(aFrame->GetStateBits() & NS_FRAME_FONT_INFLATION_FLOW_ROOT)) {
aFrame = aFrame->GetParent();
}
return aFrame;
}
};
#endif /* !defined(nsFontInflationData_h_) */

Просмотреть файл

@ -121,6 +121,7 @@
#include "nsSVGEffects.h"
#include "nsChangeHint.h"
#include "nsDeckFrame.h"
#include "nsTableFrame.h"
#include "gfxContext.h"
#include "nsRenderingContext.h"
@ -536,8 +537,16 @@ nsFrame::Init(nsIContent* aContent,
#endif
) {
if (IsFontSizeInflationContainer(this, disp)) {
mState |= NS_FRAME_FONT_INFLATION_CONTAINER;
AddStateBits(NS_FRAME_FONT_INFLATION_CONTAINER);
if (!GetParent() ||
// I'd use NS_FRAME_OUT_OF_FLOW, but it's not set yet.
disp->IsFloating() || disp->IsAbsolutelyPositioned()) {
AddStateBits(NS_FRAME_FONT_INFLATION_FLOW_ROOT);
}
}
NS_ASSERTION(GetParent() ||
(GetStateBits() & NS_FRAME_FONT_INFLATION_CONTAINER),
"root frame should always be a container");
}
DidSetStyleContext(nsnull);

Просмотреть файл

@ -127,6 +127,16 @@ nsHTMLScrollFrame::DestroyFrom(nsIFrame* aDestructRoot)
nsContainerFrame::DestroyFrom(aDestructRoot);
}
NS_IMETHODIMP
nsHTMLScrollFrame::Init(nsIContent* aContent,
nsIFrame* aParent,
nsIFrame* aPrevInFlow)
{
nsresult rv = nsContainerFrame::Init(aContent, aParent, aPrevInFlow);
mInner.Init();
return rv;
}
NS_IMETHODIMP
nsHTMLScrollFrame::SetInitialChildList(ChildListID aListID,
nsFrameList& aChildList)
@ -1062,6 +1072,16 @@ nsXULScrollFrame::DestroyFrom(nsIFrame* aDestructRoot)
nsBoxFrame::DestroyFrom(aDestructRoot);
}
NS_IMETHODIMP
nsXULScrollFrame::Init(nsIContent* aContent,
nsIFrame* aParent,
nsIFrame* aPrevInFlow)
{
nsresult rv = nsBoxFrame::Init(aContent, aParent, aPrevInFlow);
mInner.Init();
return rv;
}
NS_IMETHODIMP
nsXULScrollFrame::SetInitialChildList(ChildListID aListID,
nsFrameList& aChildList)
@ -1604,6 +1624,14 @@ nsGfxScrollFrameInner::~nsGfxScrollFrameInner()
}
}
void
nsGfxScrollFrameInner::Init()
{
if (mOuter->GetStateBits() & NS_FRAME_FONT_INFLATION_CONTAINER) {
mOuter->AddStateBits(NS_FRAME_FONT_INFLATION_FLOW_ROOT);
}
}
static nscoord
Clamp(nscoord aLower, nscoord aVal, nscoord aUpper)
{

Просмотреть файл

@ -77,6 +77,8 @@ public:
nsGfxScrollFrameInner(nsContainerFrame* aOuter, bool aIsRoot);
~nsGfxScrollFrameInner();
void Init();
typedef nsIScrollableFrame::ScrollbarStyles ScrollbarStyles;
ScrollbarStyles GetScrollbarStylesFromFrame() const;
@ -370,6 +372,9 @@ public:
// Called to set the child frames. We typically have three: the scroll area,
// the vertical scrollbar, and the horizontal scrollbar.
NS_IMETHOD Init(nsIContent* aContent,
nsIFrame* aParent,
nsIFrame* aPrevInFlow);
NS_IMETHOD SetInitialChildList(ChildListID aListID,
nsFrameList& aChildList);
@ -598,6 +603,9 @@ public:
// Called to set the child frames. We typically have three: the scroll area,
// the vertical scrollbar, and the horizontal scrollbar.
NS_IMETHOD Init(nsIContent* aContent,
nsIFrame* aParent,
nsIFrame* aPrevInFlow);
NS_IMETHOD SetInitialChildList(ChildListID aListID,
nsFrameList& aChildList);

Просмотреть файл

@ -306,6 +306,11 @@ typedef PRUint64 nsFrameState;
// everything whose nearest ancestor container for this frame?
#define NS_FRAME_FONT_INFLATION_CONTAINER NS_FRAME_STATE_BIT(41)
// Does this frame manage a region in which we do font size inflation,
// i.e., roughly, is it an element establishing a new block formatting
// context?
#define NS_FRAME_FONT_INFLATION_FLOW_ROOT NS_FRAME_STATE_BIT(42)
// Box layout bits
#define NS_STATE_IS_HORIZONTAL NS_FRAME_STATE_BIT(22)
#define NS_STATE_IS_DIRECTION_NORMAL NS_FRAME_STATE_BIT(31)

Просмотреть файл

@ -53,6 +53,9 @@
#include "nsSVGForeignObjectElement.h"
#include "nsSVGOuterSVGFrame.h"
#include "nsSVGUtils.h"
#include "mozilla/AutoRestore.h"
using namespace mozilla;
//----------------------------------------------------------------------
// Implementation
@ -93,6 +96,8 @@ nsSVGForeignObjectFrame::Init(nsIContent* aContent,
nsresult rv = nsSVGForeignObjectFrameBase::Init(aContent, aParent, aPrevInFlow);
AddStateBits(aParent->GetStateBits() &
(NS_STATE_SVG_NONDISPLAY_CHILD | NS_STATE_SVG_CLIPPATH_CHILD));
AddStateBits(NS_FRAME_FONT_INFLATION_CONTAINER |
NS_FRAME_FONT_INFLATION_FLOW_ROOT);
return rv;
}
@ -575,6 +580,14 @@ nsSVGForeignObjectFrame::DoReflow()
if (!renderingContext)
return;
AutoRestore<nsIFrame*> restoreCurrentInflationContainer(
presContext->mCurrentInflationContainer);
AutoRestore<nscoord> restoreCurrentInflationContainerWidth(
presContext->mCurrentInflationContainerWidth);
presContext->mCurrentInflationContainer = this;
presContext->mCurrentInflationContainerWidth = mRect.width;
mInReflow = true;
nsHTMLReflowState reflowState(presContext, kid,

Просмотреть файл

@ -158,7 +158,9 @@ nsSVGOuterSVGFrame::Init(nsIContent* aContent,
NS_ASSERTION(svgElement, "Content is not an SVG 'svg' element!");
#endif
AddStateBits(NS_STATE_IS_OUTER_SVG);
AddStateBits(NS_STATE_IS_OUTER_SVG |
NS_FRAME_FONT_INFLATION_CONTAINER |
NS_FRAME_FONT_INFLATION_FLOW_ROOT);
// Check for conditional processing attributes here rather than in
// nsCSSFrameConstructor::FindSVGData because we want to avoid

Просмотреть файл

@ -107,6 +107,10 @@ nsTableCellFrame::Init(nsIContent* aContent,
// Let the base class do its initialization
nsresult rv = nsContainerFrame::Init(aContent, aParent, aPrevInFlow);
if (GetStateBits() & NS_FRAME_FONT_INFLATION_CONTAINER) {
AddStateBits(NS_FRAME_FONT_INFLATION_FLOW_ROOT);
}
if (aPrevInFlow) {
// Set the column index
nsTableCellFrame* cellFrame = (nsTableCellFrame*)aPrevInFlow;

Просмотреть файл

@ -200,6 +200,10 @@ nsBoxFrame::Init(nsIContent* aContent,
nsresult rv = nsContainerFrame::Init(aContent, aParent, aPrevInFlow);
NS_ENSURE_SUCCESS(rv, rv);
if (GetStateBits() & NS_FRAME_FONT_INFLATION_CONTAINER) {
AddStateBits(NS_FRAME_FONT_INFLATION_FLOW_ROOT);
}
MarkIntrinsicWidthsDirty();
CacheAttributes();

Просмотреть файл

@ -95,6 +95,10 @@ nsLeafBoxFrame::Init(
nsresult rv = nsLeafFrame::Init(aContent, aParent, aPrevInFlow);
NS_ENSURE_SUCCESS(rv, rv);
if (GetStateBits() & NS_FRAME_FONT_INFLATION_CONTAINER) {
AddStateBits(NS_FRAME_FONT_INFLATION_FLOW_ROOT);
}
UpdateMouseThrough();
return rv;