mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-08 10:44:56 +00:00
Bug 397518. Wrap inline non-MathML children of MathML frames in anonymous blocks. r+sr=bzbarsky
This commit is contained in:
parent
75627082f2
commit
036806699a
@ -6744,8 +6744,67 @@ nsCSSFrameConstructor::ResolveStyleContext(nsIFrame* aParentFrame,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ReparentFrame(nsFrameManager* aFrameManager,
|
||||
nsIFrame* aNewParentFrame,
|
||||
nsIFrame* aFrame)
|
||||
{
|
||||
aFrame->SetParent(aNewParentFrame);
|
||||
aFrameManager->ReParentStyleContext(aFrame);
|
||||
if (aFrame->GetStateBits() &
|
||||
(NS_FRAME_HAS_VIEW | NS_FRAME_HAS_CHILD_WITH_VIEW)) {
|
||||
// No need to walk up the tree, since the bits are already set
|
||||
// right on the parent of aNewParentFrame.
|
||||
NS_ASSERTION(aNewParentFrame->GetParent()->GetStateBits() &
|
||||
NS_FRAME_HAS_CHILD_WITH_VIEW,
|
||||
"aNewParentFrame's parent should have this bit set!");
|
||||
aNewParentFrame->AddStateBits(NS_FRAME_HAS_CHILD_WITH_VIEW);
|
||||
}
|
||||
}
|
||||
|
||||
// MathML Mod - RBS
|
||||
#ifdef MOZ_MATHML
|
||||
nsresult
|
||||
nsCSSFrameConstructor::FlushAccumulatedBlock(nsFrameConstructorState& aState,
|
||||
nsIContent* aContent,
|
||||
nsIFrame* aParentFrame,
|
||||
nsFrameItems* aBlockItems,
|
||||
nsFrameItems* aNewItems)
|
||||
{
|
||||
if (!aBlockItems->childList) {
|
||||
// Nothing to do
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsStyleContext* parentContext =
|
||||
nsFrame::CorrectStyleParentFrame(aParentFrame,
|
||||
nsCSSAnonBoxes::mozMathMLAnonymousBlock)->GetStyleContext();
|
||||
nsStyleSet *styleSet = mPresShell->StyleSet();
|
||||
nsRefPtr<nsStyleContext> blockContext;
|
||||
blockContext = styleSet->ResolvePseudoStyleFor(aContent,
|
||||
nsCSSAnonBoxes::mozMathMLAnonymousBlock,
|
||||
parentContext);
|
||||
|
||||
// then, create a block frame that will wrap the child frames. Make it a
|
||||
// MathML frame so that Get(Absolute/Float)ContainingBlockFor know that this
|
||||
// is not a suitable block.
|
||||
nsIFrame* blockFrame = NS_NewMathMLmathBlockFrame(mPresShell, blockContext,
|
||||
NS_BLOCK_SPACE_MGR | NS_BLOCK_MARGIN_ROOT);
|
||||
if (NS_UNLIKELY(!blockFrame))
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
InitAndRestoreFrame(aState, aContent, aParentFrame, nsnull, blockFrame);
|
||||
for (nsIFrame* f = aBlockItems->childList; f; f = f->GetNextSibling()) {
|
||||
ReparentFrame(aState.mFrameManager, blockFrame, f);
|
||||
}
|
||||
// abs-pos and floats are disabled in MathML children so we don't have to
|
||||
// worry about messing up those.
|
||||
blockFrame->SetInitialChildList(nsnull, aBlockItems->childList);
|
||||
*aBlockItems = nsFrameItems();
|
||||
aNewItems->AddChild(blockFrame);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsCSSFrameConstructor::ConstructMathMLFrame(nsFrameConstructorState& aState,
|
||||
nsIContent* aContent,
|
||||
@ -6860,7 +6919,8 @@ nsCSSFrameConstructor::ConstructMathMLFrame(nsFrameConstructorState& aState,
|
||||
nsIFrame* blockFrame = NS_NewBlockFrame(mPresShell, blockContext,
|
||||
NS_BLOCK_SPACE_MGR |
|
||||
NS_BLOCK_MARGIN_ROOT);
|
||||
if (NS_UNLIKELY(!newFrame)) {
|
||||
if (NS_UNLIKELY(!blockFrame)) {
|
||||
newFrame->Destroy();
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
InitAndRestoreFrame(aState, aContent, newFrame, nsnull, blockFrame);
|
||||
@ -6967,6 +7027,37 @@ nsCSSFrameConstructor::ConstructMathMLFrame(nsFrameConstructorState& aState,
|
||||
CreateAnonymousFrames(aTag, aState, aContent, newFrame, PR_FALSE,
|
||||
childItems);
|
||||
|
||||
// Wrap runs of inline children in a block
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
nsFrameItems newItems;
|
||||
nsFrameItems currentBlock;
|
||||
nsIFrame* f;
|
||||
while ((f = childItems.childList) != nsnull) {
|
||||
PRBool wrapFrame = IsInlineFrame(f) || IsFrameSpecial(f);
|
||||
if (!wrapFrame) {
|
||||
rv = FlushAccumulatedBlock(aState, aContent, newFrame, ¤tBlock, &newItems);
|
||||
if (NS_FAILED(rv))
|
||||
break;
|
||||
}
|
||||
|
||||
childItems.RemoveChild(f, nsnull);
|
||||
if (wrapFrame) {
|
||||
currentBlock.AddChild(f);
|
||||
} else {
|
||||
newItems.AddChild(f);
|
||||
}
|
||||
}
|
||||
rv = FlushAccumulatedBlock(aState, aContent, newFrame, ¤tBlock, &newItems);
|
||||
|
||||
if (childItems.childList) {
|
||||
// an error must have occurred, delete unprocessed frames
|
||||
CleanupFrameReferences(aState.mFrameManager, childItems.childList);
|
||||
nsFrameList(childItems.childList).DestroyFrames();
|
||||
}
|
||||
|
||||
childItems = newItems;
|
||||
}
|
||||
|
||||
// Set the frame's initial child list
|
||||
newFrame->SetInitialChildList(nsnull, childItems.childList);
|
||||
|
||||
@ -8606,6 +8697,11 @@ nsCSSFrameConstructor::ContentAppended(nsIContent* aContainer,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
#ifdef MOZ_MATHML
|
||||
if (parentFrame->IsFrameOfType(nsIFrame::eMathML))
|
||||
return RecreateFramesForContent(parentFrame->GetContent());
|
||||
#endif
|
||||
|
||||
// If the frame we are manipulating is a ``special'' frame (that is, one
|
||||
// that's been created as a result of a block-in-inline situation) then we
|
||||
// need to append to the last special sibling, not to the frame itself.
|
||||
@ -8991,7 +9087,12 @@ nsCSSFrameConstructor::ContentInserted(nsIContent* aContainer,
|
||||
if (parentFrame->IsLeaf()) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
#ifdef MOZ_MATHML
|
||||
if (parentFrame->IsFrameOfType(nsIFrame::eMathML))
|
||||
return RecreateFramesForContent(parentFrame->GetContent());
|
||||
#endif
|
||||
|
||||
nsFrameConstructorState state(mPresShell, mFixedContainingBlock,
|
||||
GetAbsoluteContainingBlock(parentFrame),
|
||||
GetFloatContainingBlock(parentFrame),
|
||||
@ -9456,13 +9557,24 @@ nsCSSFrameConstructor::ContentRemoved(nsIContent* aContainer,
|
||||
|
||||
// Get the childFrame's parent frame
|
||||
nsIFrame* parentFrame = childFrame->GetParent();
|
||||
nsIAtom* parentType = parentFrame->GetType();
|
||||
|
||||
if (parentFrame->GetType() == nsGkAtoms::frameSetFrame &&
|
||||
if (parentType == nsGkAtoms::frameSetFrame &&
|
||||
IsSpecialFramesetChild(aChild)) {
|
||||
// Just reframe the parent, since framesets are weird like that.
|
||||
return RecreateFramesForContent(parentFrame->GetContent());
|
||||
}
|
||||
|
||||
#ifdef MOZ_MATHML
|
||||
// If we're a child of MathML, then we should reframe the MathML content.
|
||||
// If we're non-MathML, then we would be wrapped in a block so we need to
|
||||
// check our grandparent in that case.
|
||||
nsIFrame* possibleMathMLAncestor = parentType == nsGkAtoms::blockFrame ?
|
||||
parentFrame->GetParent() : parentFrame;
|
||||
if (possibleMathMLAncestor->IsFrameOfType(nsIFrame::eMathML))
|
||||
return RecreateFramesForContent(possibleMathMLAncestor->GetContent());
|
||||
#endif
|
||||
|
||||
// Examine the containing-block for the removed content and see if
|
||||
// :first-letter style applies.
|
||||
nsIFrame* containingBlock = GetFloatContainingBlock(parentFrame);
|
||||
@ -11114,6 +11226,18 @@ nsCSSFrameConstructor::RecreateFramesForContent(nsIContent* aContent)
|
||||
// containing block reframes, hence the code here.
|
||||
|
||||
nsIFrame* frame = mPresShell->GetPrimaryFrameFor(aContent);
|
||||
if (frame && frame->IsFrameOfType(nsIFrame::eMathML)) {
|
||||
// Reframe the topmost MathML element to prevent exponential blowup
|
||||
// (see bug 397518)
|
||||
while (PR_TRUE) {
|
||||
nsIContent* parentContent = aContent->GetParent();
|
||||
nsIFrame* parentContentFrame = mPresShell->GetPrimaryFrameFor(parentContent);
|
||||
if (!parentContentFrame || !parentContentFrame->IsFrameOfType(nsIFrame::eMathML))
|
||||
break;
|
||||
aContent = parentContent;
|
||||
frame = parentContentFrame;
|
||||
}
|
||||
}
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
@ -11331,24 +11455,6 @@ nsCSSFrameConstructor::ProcessChildren(nsFrameConstructorState& aState,
|
||||
|
||||
// Support for :first-line style
|
||||
|
||||
static void
|
||||
ReparentFrame(nsFrameManager* aFrameManager,
|
||||
nsIFrame* aNewParentFrame,
|
||||
nsIFrame* aFrame)
|
||||
{
|
||||
aFrame->SetParent(aNewParentFrame);
|
||||
aFrameManager->ReParentStyleContext(aFrame);
|
||||
if (aFrame->GetStateBits() &
|
||||
(NS_FRAME_HAS_VIEW | NS_FRAME_HAS_CHILD_WITH_VIEW)) {
|
||||
// No need to walk up the tree, since the bits are already set
|
||||
// right on the parent of aNewParentFrame.
|
||||
NS_ASSERTION(aNewParentFrame->GetParent()->GetStateBits() &
|
||||
NS_FRAME_HAS_CHILD_WITH_VIEW,
|
||||
"aNewParentFrame's parent should have this bit set!");
|
||||
aNewParentFrame->AddStateBits(NS_FRAME_HAS_CHILD_WITH_VIEW);
|
||||
}
|
||||
}
|
||||
|
||||
// Special routine to handle placing a list of frames into a block
|
||||
// frame that has first-line style. The routine ensures that the first
|
||||
// collection of inline frames end up in a first-line frame.
|
||||
|
@ -594,6 +594,17 @@ private:
|
||||
|
||||
//MathML Mod - RBS
|
||||
#ifdef MOZ_MATHML
|
||||
/**
|
||||
* Takes the frames in aBlockItems and wraps them in a new anonymous block
|
||||
* frame whose content is aContent and whose parent will be aParentFrame.
|
||||
* The anonymous block is added to aNewItems and aBlockItems is cleared.
|
||||
*/
|
||||
nsresult FlushAccumulatedBlock(nsFrameConstructorState& aState,
|
||||
nsIContent* aContent,
|
||||
nsIFrame* aParentFrame,
|
||||
nsFrameItems* aBlockItems,
|
||||
nsFrameItems* aNewItems);
|
||||
|
||||
nsresult ConstructMathMLFrame(nsFrameConstructorState& aState,
|
||||
nsIContent* aContent,
|
||||
nsIFrame* aParentFrame,
|
||||
|
@ -766,6 +766,15 @@ nsBlockFrame::GetPrefWidth(nsIRenderingContext *aRenderingContext)
|
||||
return mPrefWidth;
|
||||
}
|
||||
|
||||
nsRect
|
||||
nsBlockFrame::ComputeTightBounds(gfxContext* aContext) const
|
||||
{
|
||||
// be conservative
|
||||
if (GetStyleContext()->HasTextDecorations())
|
||||
return GetOverflowRect();
|
||||
return ComputeSimpleTightBounds(aContext);
|
||||
}
|
||||
|
||||
static nsSize
|
||||
CalculateContainingBlockSizeForAbsolutes(const nsHTMLReflowState& aReflowState,
|
||||
nsSize aFrameSize)
|
||||
|
@ -241,6 +241,8 @@ public:
|
||||
virtual nscoord GetMinWidth(nsIRenderingContext *aRenderingContext);
|
||||
virtual nscoord GetPrefWidth(nsIRenderingContext *aRenderingContext);
|
||||
|
||||
virtual nsRect ComputeTightBounds(gfxContext* aContext) const;
|
||||
|
||||
NS_IMETHOD Reflow(nsPresContext* aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
|
@ -881,9 +881,9 @@ nsIFrame::DisplayCaret(nsDisplayListBuilder* aBuilder,
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsFrame::HasBorder()
|
||||
nsFrame::HasBorder() const
|
||||
{
|
||||
return GetStyleBorder()->GetBorder() != nsMargin(0,0,0,0);
|
||||
return GetUsedBorder() != nsMargin(0,0,0,0);
|
||||
}
|
||||
|
||||
nsresult
|
||||
@ -3065,6 +3065,37 @@ nsFrame::ComputeSize(nsIRenderingContext *aRenderingContext,
|
||||
return result;
|
||||
}
|
||||
|
||||
nsRect
|
||||
nsIFrame::ComputeTightBounds(gfxContext* aContext) const
|
||||
{
|
||||
return GetOverflowRect();
|
||||
}
|
||||
|
||||
nsRect
|
||||
nsFrame::ComputeSimpleTightBounds(gfxContext* aContext) const
|
||||
{
|
||||
if (GetStyleOutline()->GetOutlineStyle() != NS_STYLE_BORDER_STYLE_NONE ||
|
||||
HasBorder() || !GetStyleBackground()->IsTransparent() ||
|
||||
GetStyleDisplay()->mAppearance) {
|
||||
// Not necessarily tight, due to clipping, negative
|
||||
// outline-offset, and lots of other issues, but that's OK
|
||||
return GetOverflowRect();
|
||||
}
|
||||
|
||||
nsRect r(0, 0, 0, 0);
|
||||
PRInt32 listIndex = 0;
|
||||
nsIAtom* childList = nsnull;
|
||||
do {
|
||||
nsIFrame* child = GetFirstChild(childList);
|
||||
while (child) {
|
||||
r.UnionRect(r, child->ComputeTightBounds(aContext) + child->GetPosition());
|
||||
child = child->GetNextSibling();
|
||||
}
|
||||
childList = GetAdditionalChildListName(listIndex++);
|
||||
} while (childList);
|
||||
return r;
|
||||
}
|
||||
|
||||
/* virtual */ nsSize
|
||||
nsFrame::ComputeAutoSize(nsIRenderingContext *aRenderingContext,
|
||||
nsSize aCBSize, nscoord aAvailableWidth,
|
||||
|
@ -288,6 +288,10 @@ public:
|
||||
nsSize aMargin, nsSize aBorder, nsSize aPadding,
|
||||
PRBool aShrinkWrap);
|
||||
|
||||
// Compute tight bounds assuming this frame honours its border, background
|
||||
// and outline, its children's tight bounds, and nothing else.
|
||||
nsRect ComputeSimpleTightBounds(gfxContext* aContext) const;
|
||||
|
||||
/**
|
||||
* A helper, used by |nsFrame::ComputeSize| (for frames that need to
|
||||
* override only this part of ComputeSize), that computes the size
|
||||
@ -539,7 +543,7 @@ protected:
|
||||
/**
|
||||
* @return PR_FALSE if this frame definitely has no borders at all
|
||||
*/
|
||||
PRBool HasBorder();
|
||||
PRBool HasBorder() const;
|
||||
|
||||
/**
|
||||
* To be called by |BuildDisplayLists| of this class or derived classes to add
|
||||
|
@ -92,6 +92,7 @@ class nsDisplayListSet;
|
||||
class nsDisplayList;
|
||||
class gfxSkipChars;
|
||||
class gfxSkipCharsIterator;
|
||||
class gfxContext;
|
||||
class nsLineList_iterator;
|
||||
|
||||
struct nsPeekOffsetStruct;
|
||||
@ -1305,6 +1306,16 @@ public:
|
||||
nsSize aMargin, nsSize aBorder, nsSize aPadding,
|
||||
PRBool aShrinkWrap) = 0;
|
||||
|
||||
/**
|
||||
* Compute a tight bounding rectangle for the frame. This is a rectangle
|
||||
* that encloses the pixels that are actually drawn. We're allowed to be
|
||||
* conservative and currently we don't try very hard. The rectangle is
|
||||
* in appunits and relative to the origin of this frame.
|
||||
* @param aContext a rendering context that can be used if we need
|
||||
* to do measurement
|
||||
*/
|
||||
virtual nsRect ComputeTightBounds(gfxContext* aContext) const;
|
||||
|
||||
/**
|
||||
* Pre-reflow hook. Before a frame is reflowed this method will be called.
|
||||
* This call will always be invoked at least once before a subsequent Reflow
|
||||
|
@ -225,6 +225,15 @@ nsInlineFrame::ComputeSize(nsIRenderingContext *aRenderingContext,
|
||||
return nsSize(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE);
|
||||
}
|
||||
|
||||
nsRect
|
||||
nsInlineFrame::ComputeTightBounds(gfxContext* aContext) const
|
||||
{
|
||||
// be conservative
|
||||
if (GetStyleContext()->HasTextDecorations())
|
||||
return GetOverflowRect();
|
||||
return ComputeSimpleTightBounds(aContext);
|
||||
}
|
||||
|
||||
void
|
||||
nsInlineFrame::ReparentFloatsForInlineChild(nsIFrame* aOurLineContainer,
|
||||
nsIFrame* aFrame,
|
||||
|
@ -118,6 +118,7 @@ public:
|
||||
nsSize aCBSize, nscoord aAvailableWidth,
|
||||
nsSize aMargin, nsSize aBorder, nsSize aPadding,
|
||||
PRBool aShrinkWrap);
|
||||
virtual nsRect ComputeTightBounds(gfxContext* aContext) const;
|
||||
NS_IMETHOD Reflow(nsPresContext* aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
|
@ -196,6 +196,7 @@ public:
|
||||
nsSize aCBSize, nscoord aAvailableWidth,
|
||||
nsSize aMargin, nsSize aBorder, nsSize aPadding,
|
||||
PRBool aShrinkWrap);
|
||||
virtual nsRect ComputeTightBounds(gfxContext* aContext) const;
|
||||
NS_IMETHOD Reflow(nsPresContext* aPresContext,
|
||||
nsHTMLReflowMetrics& aMetrics,
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
@ -294,7 +295,7 @@ public:
|
||||
* to offsets into the textrun; its initial offset is set to this frame's
|
||||
* content offset
|
||||
*/
|
||||
gfxSkipCharsIterator EnsureTextRun(nsIRenderingContext* aRC = nsnull,
|
||||
gfxSkipCharsIterator EnsureTextRun(gfxContext* aReferenceContext = nsnull,
|
||||
nsIFrame* aLineContainer = nsnull,
|
||||
const nsLineList::iterator* aLine = nsnull,
|
||||
PRUint32* aFlowEndInTextRun = nsnull);
|
||||
|
@ -807,7 +807,7 @@ BuildTextRunsScanner::FindBoundaries(nsIFrame* aFrame, FindBoundaryState* aState
|
||||
* out the block (slowly)
|
||||
*/
|
||||
static void
|
||||
BuildTextRuns(nsIRenderingContext* aRC, nsTextFrame* aForFrame,
|
||||
BuildTextRuns(gfxContext* aContext, nsTextFrame* aForFrame,
|
||||
nsIFrame* aLineContainer, const nsLineList::iterator* aForFrameLine)
|
||||
{
|
||||
if (!aLineContainer) {
|
||||
@ -817,9 +817,7 @@ BuildTextRuns(nsIRenderingContext* aRC, nsTextFrame* aForFrame,
|
||||
}
|
||||
|
||||
nsPresContext* presContext = aLineContainer->PresContext();
|
||||
gfxContext* ctx = static_cast<gfxContext*>
|
||||
(aRC->GetNativeGraphicData(nsIRenderingContext::NATIVE_THEBES_CONTEXT));
|
||||
BuildTextRunsScanner scanner(presContext, ctx, aLineContainer);
|
||||
BuildTextRunsScanner scanner(presContext, aContext, aLineContainer);
|
||||
|
||||
nsBlockFrame* block = nsnull;
|
||||
aLineContainer->QueryInterface(kBlockFrameCID, (void**)&block);
|
||||
@ -1213,18 +1211,37 @@ GetFontGroupForFrame(nsIFrame* aFrame)
|
||||
return fm->GetThebesFontGroup();
|
||||
}
|
||||
|
||||
static already_AddRefed<gfxContext>
|
||||
GetReferenceRenderingContext(nsTextFrame* aTextFrame, nsIRenderingContext* aRC)
|
||||
{
|
||||
nsCOMPtr<nsIRenderingContext> tmp = aRC;
|
||||
if (!tmp) {
|
||||
nsresult rv = aTextFrame->PresContext()->PresShell()->
|
||||
CreateRenderingContext(aTextFrame, getter_AddRefs(tmp));
|
||||
if (NS_FAILED(rv))
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
gfxContext* ctx = static_cast<gfxContext*>
|
||||
(tmp->GetNativeGraphicData(nsIRenderingContext::NATIVE_THEBES_CONTEXT));
|
||||
NS_ADDREF(ctx);
|
||||
return ctx;
|
||||
}
|
||||
|
||||
/**
|
||||
* The returned textrun must be released via gfxTextRunCache::ReleaseTextRun
|
||||
* or gfxTextRunCache::AutoTextRun.
|
||||
*/
|
||||
static gfxTextRun*
|
||||
GetHyphenTextRun(gfxTextRun* aTextRun, nsIRenderingContext* aRefContext)
|
||||
GetHyphenTextRun(gfxTextRun* aTextRun, gfxContext* aContext, nsTextFrame* aTextFrame)
|
||||
{
|
||||
if (NS_UNLIKELY(!aRefContext)) {
|
||||
return nsnull;
|
||||
nsRefPtr<gfxContext> ctx = aContext;
|
||||
if (!ctx) {
|
||||
ctx = GetReferenceRenderingContext(aTextFrame, nsnull);
|
||||
}
|
||||
gfxContext* ctx = static_cast<gfxContext*>
|
||||
(aRefContext->GetNativeGraphicData(nsIRenderingContext::NATIVE_THEBES_CONTEXT));
|
||||
if (!ctx)
|
||||
return nsnull;
|
||||
|
||||
gfxFontGroup* fontGroup = aTextRun->GetFontGroup();
|
||||
PRUint32 flags = gfxFontGroup::TEXT_IS_PERSISTENT;
|
||||
|
||||
@ -1685,24 +1702,8 @@ BuildTextRunsScanner::AssignTextRun(gfxTextRun* aTextRun)
|
||||
}
|
||||
}
|
||||
|
||||
static already_AddRefed<nsIRenderingContext>
|
||||
GetReferenceRenderingContext(nsTextFrame* aTextFrame, nsIRenderingContext* aRC)
|
||||
{
|
||||
if (aRC) {
|
||||
NS_ADDREF(aRC);
|
||||
return aRC;
|
||||
}
|
||||
|
||||
nsIRenderingContext* result;
|
||||
nsresult rv = aTextFrame->PresContext()->PresShell()->
|
||||
CreateRenderingContext(aTextFrame, &result);
|
||||
if (NS_FAILED(rv))
|
||||
return nsnull;
|
||||
return result;
|
||||
}
|
||||
|
||||
gfxSkipCharsIterator
|
||||
nsTextFrame::EnsureTextRun(nsIRenderingContext* aRC, nsIFrame* aLineContainer,
|
||||
nsTextFrame::EnsureTextRun(gfxContext* aReferenceContext, nsIFrame* aLineContainer,
|
||||
const nsLineList::iterator* aLine,
|
||||
PRUint32* aFlowEndInTextRun)
|
||||
{
|
||||
@ -1711,10 +1712,12 @@ nsTextFrame::EnsureTextRun(nsIRenderingContext* aRC, nsIFrame* aLineContainer,
|
||||
gTextRuns->MarkUsed(mTextRun);
|
||||
}
|
||||
} else {
|
||||
nsCOMPtr<nsIRenderingContext> rendContext =
|
||||
GetReferenceRenderingContext(this, aRC);
|
||||
if (rendContext) {
|
||||
BuildTextRuns(rendContext, this, aLineContainer, aLine);
|
||||
nsRefPtr<gfxContext> ctx = aReferenceContext;
|
||||
if (!ctx) {
|
||||
ctx = GetReferenceRenderingContext(this, nsnull);
|
||||
}
|
||||
if (ctx) {
|
||||
BuildTextRuns(ctx, this, aLineContainer, aLine);
|
||||
}
|
||||
if (!mTextRun) {
|
||||
// A text run was not constructed for this frame. This is bad. The caller
|
||||
@ -1858,9 +1861,6 @@ static void ClearMetrics(nsHTMLReflowMetrics& aMetrics)
|
||||
aMetrics.width = 0;
|
||||
aMetrics.height = 0;
|
||||
aMetrics.ascent = 0;
|
||||
#ifdef MOZ_MATHML
|
||||
aMetrics.mBoundingMetrics.Clear();
|
||||
#endif
|
||||
}
|
||||
|
||||
static PRInt32 FindChar(const nsTextFragment* frag,
|
||||
@ -2258,8 +2258,7 @@ gfxFloat
|
||||
PropertyProvider::GetHyphenWidth()
|
||||
{
|
||||
if (mHyphenWidth < 0) {
|
||||
nsCOMPtr<nsIRenderingContext> rc = GetReferenceRenderingContext(mFrame, nsnull);
|
||||
gfxTextRunCache::AutoTextRun hyphenTextRun(GetHyphenTextRun(mTextRun, rc));
|
||||
gfxTextRunCache::AutoTextRun hyphenTextRun(GetHyphenTextRun(mTextRun, nsnull, mFrame));
|
||||
mHyphenWidth = mLetterSpacing;
|
||||
if (hyphenTextRun.get()) {
|
||||
mHyphenWidth += hyphenTextRun->GetAdvanceWidth(0, hyphenTextRun->GetLength(), nsnull);
|
||||
@ -2369,8 +2368,7 @@ PropertyProvider::SetupJustificationSpacing()
|
||||
mTextRun->GetAdvanceWidth(mStart.GetSkippedOffset(),
|
||||
GetSkippedDistance(mStart, realEnd), this);
|
||||
if (mFrame->GetStateBits() & TEXT_HYPHEN_BREAK) {
|
||||
nsCOMPtr<nsIRenderingContext> rc = GetReferenceRenderingContext(mFrame, nsnull);
|
||||
gfxTextRunCache::AutoTextRun hyphenTextRun(GetHyphenTextRun(mTextRun, rc));
|
||||
gfxTextRunCache::AutoTextRun hyphenTextRun(GetHyphenTextRun(mTextRun, nsnull, mFrame));
|
||||
if (hyphenTextRun.get()) {
|
||||
naturalWidth +=
|
||||
hyphenTextRun->GetAdvanceWidth(0, hyphenTextRun->GetLength(), nsnull);
|
||||
@ -3863,8 +3861,7 @@ nsTextFrame::PaintTextWithSelectionColors(gfxContext* aCtx,
|
||||
gfxFloat hyphenBaselineX = aFramePt.x + xOffset + mTextRun->GetDirection()*advance;
|
||||
// Get a reference rendering context because aCtx might not have the
|
||||
// reference matrix currently set
|
||||
nsCOMPtr<nsIRenderingContext> rc = GetReferenceRenderingContext(this, nsnull);
|
||||
gfxTextRunCache::AutoTextRun hyphenTextRun(GetHyphenTextRun(mTextRun, rc));
|
||||
gfxTextRunCache::AutoTextRun hyphenTextRun(GetHyphenTextRun(mTextRun, nsnull, this));
|
||||
if (hyphenTextRun.get()) {
|
||||
hyphenTextRun->Draw(aCtx, gfxPoint(hyphenBaselineX, aTextBaselinePt.y),
|
||||
0, hyphenTextRun->GetLength(), &aDirtyRect, nsnull, nsnull);
|
||||
@ -3992,8 +3989,10 @@ void
|
||||
nsTextFrame::PaintText(nsIRenderingContext* aRenderingContext, nsPoint aPt,
|
||||
const nsRect& aDirtyRect)
|
||||
{
|
||||
// Don't pass in aRenderingContext here, because we need a *reference*
|
||||
// context and aRenderingContext might have some transform in it
|
||||
// XXX get the block and line passed to us somehow! This is slow!
|
||||
gfxSkipCharsIterator iter = EnsureTextRun(aRenderingContext);
|
||||
gfxSkipCharsIterator iter = EnsureTextRun();
|
||||
if (!mTextRun)
|
||||
return;
|
||||
|
||||
@ -4031,8 +4030,9 @@ nsTextFrame::PaintText(nsIRenderingContext* aRenderingContext, nsPoint aPt,
|
||||
&dirtyRect, &provider, needAdvanceWidth);
|
||||
if (GetStateBits() & TEXT_HYPHEN_BREAK) {
|
||||
gfxFloat hyphenBaselineX = textBaselinePt.x + mTextRun->GetDirection()*advanceWidth;
|
||||
nsCOMPtr<nsIRenderingContext> rc = GetReferenceRenderingContext(this, nsnull);
|
||||
gfxTextRunCache::AutoTextRun hyphenTextRun(GetHyphenTextRun(mTextRun, rc));
|
||||
// Don't use ctx as the context, because we need a reference context here,
|
||||
// ctx may be transformed.
|
||||
gfxTextRunCache::AutoTextRun hyphenTextRun(GetHyphenTextRun(mTextRun, nsnull, this));
|
||||
if (hyphenTextRun.get()) {
|
||||
hyphenTextRun->Draw(ctx, gfxPoint(hyphenBaselineX, textBaselinePt.y),
|
||||
0, hyphenTextRun->GetLength(), &dirtyRect, nsnull, nsnull);
|
||||
@ -4745,8 +4745,10 @@ nsTextFrame::AddInlineMinWidthForFlow(nsIRenderingContext *aRenderingContext,
|
||||
nsIFrame::InlineMinWidthData *aData)
|
||||
{
|
||||
PRUint32 flowEndInTextRun;
|
||||
gfxContext* ctx = static_cast<gfxContext*>
|
||||
(aRenderingContext->GetNativeGraphicData(nsIRenderingContext::NATIVE_THEBES_CONTEXT));
|
||||
gfxSkipCharsIterator iter =
|
||||
EnsureTextRun(aRenderingContext, nsnull, aData->line, &flowEndInTextRun);
|
||||
EnsureTextRun(ctx, nsnull, aData->line, &flowEndInTextRun);
|
||||
if (!mTextRun)
|
||||
return;
|
||||
|
||||
@ -4845,8 +4847,10 @@ nsTextFrame::AddInlinePrefWidthForFlow(nsIRenderingContext *aRenderingContext,
|
||||
nsIFrame::InlinePrefWidthData *aData)
|
||||
{
|
||||
PRUint32 flowEndInTextRun;
|
||||
gfxContext* ctx = static_cast<gfxContext*>
|
||||
(aRenderingContext->GetNativeGraphicData(nsIRenderingContext::NATIVE_THEBES_CONTEXT));
|
||||
gfxSkipCharsIterator iter =
|
||||
EnsureTextRun(aRenderingContext, nsnull, aData->line, &flowEndInTextRun);
|
||||
EnsureTextRun(ctx, nsnull, aData->line, &flowEndInTextRun);
|
||||
if (!mTextRun)
|
||||
return;
|
||||
|
||||
@ -4936,6 +4940,44 @@ nsTextFrame::ComputeSize(nsIRenderingContext *aRenderingContext,
|
||||
return nsSize(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE);
|
||||
}
|
||||
|
||||
static nsRect
|
||||
RoundOut(const gfxRect& aRect)
|
||||
{
|
||||
nsRect r;
|
||||
r.x = NSToCoordFloor(aRect.X());
|
||||
r.y = NSToCoordFloor(aRect.Y());
|
||||
r.width = NSToCoordCeil(aRect.XMost()) - r.x;
|
||||
r.height = NSToCoordCeil(aRect.YMost()) - r.y;
|
||||
return r;
|
||||
}
|
||||
|
||||
nsRect
|
||||
nsTextFrame::ComputeTightBounds(gfxContext* aContext) const
|
||||
{
|
||||
if ((GetStyleContext()->HasTextDecorations() &&
|
||||
eCompatibility_NavQuirks == PresContext()->CompatibilityMode()) ||
|
||||
(GetStateBits() & TEXT_HYPHEN_BREAK)) {
|
||||
// This is conservative, but OK.
|
||||
return GetOverflowRect();
|
||||
}
|
||||
|
||||
gfxSkipCharsIterator iter = const_cast<nsTextFrame*>(this)->EnsureTextRun();
|
||||
if (!mTextRun)
|
||||
return nsRect(0, 0, 0, 0);
|
||||
|
||||
PropertyProvider provider(const_cast<nsTextFrame*>(this), iter);
|
||||
// Trim trailing whitespace
|
||||
provider.InitializeForDisplay(PR_TRUE);
|
||||
|
||||
gfxTextRun::Metrics metrics =
|
||||
mTextRun->MeasureText(provider.GetStart().GetSkippedOffset(),
|
||||
ComputeTransformedLength(provider), PR_TRUE,
|
||||
aContext, &provider);
|
||||
// mAscent should be the same as metrics.mAscent, but it's what we use to
|
||||
// paint so that's the one we'll use.
|
||||
return RoundOut(metrics.mBoundingBox) + nsPoint(0, mAscent);
|
||||
}
|
||||
|
||||
static void
|
||||
AddCharToMetrics(gfxTextRun* aCharTextRun, gfxTextRun* aBaseTextRun,
|
||||
gfxTextRun::Metrics* aMetrics, PRBool aTightBoundingBox,
|
||||
@ -5111,9 +5153,10 @@ nsTextFrame::Reflow(nsPresContext* aPresContext,
|
||||
|
||||
PRUint32 flowEndInTextRun;
|
||||
nsIFrame* lineContainer = lineLayout.GetLineContainerFrame();
|
||||
gfxContext* ctx = static_cast<gfxContext*>
|
||||
(aReflowState.rendContext->GetNativeGraphicData(nsIRenderingContext::NATIVE_THEBES_CONTEXT));
|
||||
gfxSkipCharsIterator iter =
|
||||
EnsureTextRun(aReflowState.rendContext, lineContainer,
|
||||
lineLayout.GetLine(), &flowEndInTextRun);
|
||||
EnsureTextRun(ctx, lineContainer, lineLayout.GetLine(), &flowEndInTextRun);
|
||||
|
||||
PRInt32 skippedRunLength;
|
||||
if (mTextRun && mTextRun->GetLength() == iter.GetSkippedOffset() &&
|
||||
@ -5124,7 +5167,7 @@ nsTextFrame::Reflow(nsPresContext* aPresContext,
|
||||
// preformatted newline was encountered, and prev-in-flow frames have
|
||||
// consumed all the text of the textrun. We need a new textrun.
|
||||
ClearTextRun();
|
||||
iter = EnsureTextRun(aReflowState.rendContext, lineContainer,
|
||||
iter = EnsureTextRun(ctx, lineContainer,
|
||||
lineLayout.GetLine(), &flowEndInTextRun);
|
||||
}
|
||||
|
||||
@ -5161,9 +5204,8 @@ nsTextFrame::Reflow(nsPresContext* aPresContext,
|
||||
gfxTextRun::Metrics textMetrics;
|
||||
PRBool needTightBoundingBox = (GetStateBits() & TEXT_FIRST_LETTER) != 0;
|
||||
#ifdef MOZ_MATHML
|
||||
if (NS_REFLOW_CALC_BOUNDING_METRICS & aMetrics.mFlags) {
|
||||
needTightBoundingBox = PR_TRUE;
|
||||
}
|
||||
NS_ASSERTION(!(NS_REFLOW_CALC_BOUNDING_METRICS & aMetrics.mFlags),
|
||||
"We shouldn't be passed NS_REFLOW_CALC_BOUNDING_METRICS anymore");
|
||||
#endif
|
||||
PRBool suppressInitialBreak = !lineLayout.LineIsBreakable() ||
|
||||
!lineLayout.HasTrailingTextFrame();
|
||||
@ -5200,8 +5242,6 @@ nsTextFrame::Reflow(nsPresContext* aPresContext,
|
||||
gfxFloat availWidth = aReflowState.availableWidth;
|
||||
PRBool canTrimTrailingWhitespace = !textStyle->WhiteSpaceIsSignificant() &&
|
||||
textStyle->WhiteSpaceCanWrap();
|
||||
gfxContext* ctx = static_cast<gfxContext*>
|
||||
(aReflowState.rendContext->GetNativeGraphicData(nsIRenderingContext::NATIVE_THEBES_CONTEXT));
|
||||
PRUint32 transformedCharsFit =
|
||||
mTextRun->BreakAndMeasureText(transformedOffset, transformedLength,
|
||||
(GetStateBits() & TEXT_START_OF_LINE) != 0,
|
||||
@ -5236,7 +5276,7 @@ nsTextFrame::Reflow(nsPresContext* aPresContext,
|
||||
}
|
||||
if (usedHyphenation) {
|
||||
// Fix up metrics to include hyphen
|
||||
gfxTextRunCache::AutoTextRun hyphenTextRun(GetHyphenTextRun(mTextRun, aReflowState.rendContext));
|
||||
gfxTextRunCache::AutoTextRun hyphenTextRun(GetHyphenTextRun(mTextRun, ctx, this));
|
||||
if (hyphenTextRun.get()) {
|
||||
AddCharToMetrics(hyphenTextRun.get(),
|
||||
mTextRun, &textMetrics, needTightBoundingBox, ctx);
|
||||
@ -5294,21 +5334,6 @@ nsTextFrame::Reflow(nsPresContext* aPresContext,
|
||||
aMetrics.mOverflowArea.UnionRect(boundingBox,
|
||||
nsRect(0, 0, aMetrics.width, aMetrics.height));
|
||||
|
||||
#ifdef MOZ_MATHML
|
||||
// Store MathML bounding metrics. We've already calculated them above.
|
||||
if (needTightBoundingBox) {
|
||||
aMetrics.mBoundingMetrics.ascent =
|
||||
NSToCoordCeil(PR_MAX(0, -textMetrics.mBoundingBox.Y()));
|
||||
aMetrics.mBoundingMetrics.descent =
|
||||
NSToCoordCeil(PR_MAX(0, textMetrics.mBoundingBox.YMost()));
|
||||
aMetrics.mBoundingMetrics.leftBearing =
|
||||
NSToCoordFloor(textMetrics.mBoundingBox.X());
|
||||
aMetrics.mBoundingMetrics.rightBearing =
|
||||
NSToCoordCeil(textMetrics.mBoundingBox.XMost());
|
||||
aMetrics.mBoundingMetrics.width = aMetrics.width;
|
||||
}
|
||||
#endif
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
// Clean up, update state
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
@ -5400,7 +5425,9 @@ nsTextFrame::TrimTrailingWhiteSpace(nsPresContext* aPresContext,
|
||||
if (!contentLength)
|
||||
return NS_OK;
|
||||
|
||||
gfxSkipCharsIterator start = EnsureTextRun(&aRC);
|
||||
gfxContext* ctx = static_cast<gfxContext*>
|
||||
(aRC.GetNativeGraphicData(nsIRenderingContext::NATIVE_THEBES_CONTEXT));
|
||||
gfxSkipCharsIterator start = EnsureTextRun(ctx);
|
||||
if (!mTextRun)
|
||||
return NS_ERROR_FAILURE;
|
||||
PRUint32 trimmedStart = start.GetSkippedOffset();
|
||||
@ -5447,8 +5474,6 @@ nsTextFrame::TrimTrailingWhiteSpace(nsPresContext* aPresContext,
|
||||
}
|
||||
}
|
||||
|
||||
gfxContext* ctx = static_cast<gfxContext*>
|
||||
(aRC.GetNativeGraphicData(nsIRenderingContext::NATIVE_THEBES_CONTEXT));
|
||||
gfxFloat advanceDelta;
|
||||
mTextRun->SetLineBreaks(trimmedStart, trimmedEnd - trimmedStart,
|
||||
(GetStateBits() & TEXT_START_OF_LINE) != 0, PR_TRUE,
|
||||
|
@ -966,6 +966,15 @@ nsMathMLContainerFrame::AttributeChanged(PRInt32 aNameSpaceID,
|
||||
NS_FRAME_IS_DIRTY);
|
||||
}
|
||||
|
||||
static PRBool
|
||||
IsForeignChild(nsIFrame* aFrame)
|
||||
{
|
||||
// This counts nsMathMLmathBlockFrame as a foreign child, because it
|
||||
// uses block reflow
|
||||
return !(aFrame->IsFrameOfType(nsIFrame::eMathML)) ||
|
||||
aFrame->GetType() == nsGkAtoms::blockFrame;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsMathMLContainerFrame::ReflowChild(nsIFrame* aChildFrame,
|
||||
nsPresContext* aPresContext,
|
||||
@ -976,7 +985,12 @@ nsMathMLContainerFrame::ReflowChild(nsIFrame* aChildFrame,
|
||||
aDesiredSize.width = aDesiredSize.height = 0;
|
||||
aDesiredSize.ascent = 0;
|
||||
aDesiredSize.mBoundingMetrics.Clear();
|
||||
aDesiredSize.mFlags |= NS_REFLOW_CALC_BOUNDING_METRICS;
|
||||
PRBool isForeign = IsForeignChild(aChildFrame);
|
||||
if (!isForeign) {
|
||||
// We only do this for MathML frames now. Non-MathML frames support
|
||||
// ComputeTightBounds instead.
|
||||
aDesiredSize.mFlags |= NS_REFLOW_CALC_BOUNDING_METRICS;
|
||||
}
|
||||
|
||||
// Having foreign/hybrid children, e.g., from html markups, is not defined by
|
||||
// the MathML spec. But it can happen in practice, e.g., <html:img> allows us
|
||||
@ -988,50 +1002,32 @@ nsMathMLContainerFrame::ReflowChild(nsIFrame* aChildFrame,
|
||||
// them in the flow, if we can get their desired size. We observed that most
|
||||
// frames may be reflowed generically, but nsInlineFrames need extra care.
|
||||
|
||||
#ifdef DEBUG
|
||||
nsInlineFrame* inlineFrame;
|
||||
aChildFrame->QueryInterface(kInlineFrameCID, (void**)&inlineFrame);
|
||||
if (!inlineFrame)
|
||||
return nsHTMLContainerFrame::
|
||||
ReflowChild(aChildFrame, aPresContext, aDesiredSize, aReflowState,
|
||||
0, 0, NS_FRAME_NO_MOVE_FRAME, aStatus);
|
||||
|
||||
// extra care for an nsInlineFrame
|
||||
return ReflowForeignChild(aChildFrame, aPresContext, aDesiredSize, aReflowState, aStatus);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsMathMLContainerFrame::ReflowForeignChild(nsIFrame* aChildFrame,
|
||||
nsPresContext* aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus)
|
||||
{
|
||||
nsAutoSpaceManager autoSpaceManager(const_cast<nsHTMLReflowState &>(aReflowState));
|
||||
nsresult rv = autoSpaceManager.CreateSpaceManagerFor(aPresContext, this);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// provide a local, self-contained linelayout where to reflow the nsInlineFrame
|
||||
nsSize availSize(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE);
|
||||
nsLineLayout ll(aPresContext, aReflowState.mSpaceManager,
|
||||
aReflowState.parentReflowState, nsnull);
|
||||
ll.BeginLineReflow(0, 0, availSize.width, availSize.height, PR_FALSE, PR_FALSE);
|
||||
PRBool pushedFrame;
|
||||
ll.ReflowFrame(aChildFrame, aStatus, &aDesiredSize, pushedFrame);
|
||||
NS_ASSERTION(!pushedFrame, "unexpected");
|
||||
ll.EndLineReflow();
|
||||
|
||||
// make up the bounding metrics from the reflow metrics.
|
||||
aDesiredSize.mBoundingMetrics.ascent = aDesiredSize.ascent;
|
||||
aDesiredSize.mBoundingMetrics.descent = aDesiredSize.height - aDesiredSize.ascent;
|
||||
aDesiredSize.mBoundingMetrics.width = aDesiredSize.width;
|
||||
aDesiredSize.mBoundingMetrics.rightBearing = aDesiredSize.width;
|
||||
|
||||
// Note: MathML's vertical & horizontal alignments happen much later in
|
||||
// Place(), which is ultimately called from within FinalizeReflow().
|
||||
|
||||
aStatus = NS_FRAME_COMPLETE;
|
||||
NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize);
|
||||
return NS_OK;
|
||||
NS_ASSERTION(!inlineFrame, "Inline frames should be wrapped in blocks");
|
||||
#endif
|
||||
|
||||
// XXX should we do something here to compute good bounding metrics for
|
||||
// the child?
|
||||
|
||||
nsresult rv = nsHTMLContainerFrame::
|
||||
ReflowChild(aChildFrame, aPresContext, aDesiredSize, aReflowState,
|
||||
0, 0, NS_FRAME_NO_MOVE_FRAME, aStatus);
|
||||
if (isForeign) {
|
||||
// use ComputeTightBounds API instead
|
||||
gfxContext* ctx = static_cast<gfxContext*>
|
||||
(aReflowState.rendContext->GetNativeGraphicData(nsIRenderingContext::NATIVE_THEBES_CONTEXT));
|
||||
nsRect r = aChildFrame->ComputeTightBounds(ctx);
|
||||
aDesiredSize.mBoundingMetrics.leftBearing = r.x;
|
||||
aDesiredSize.mBoundingMetrics.rightBearing = r.XMost();
|
||||
nscoord frameAscent = aDesiredSize.ascent == nsHTMLReflowMetrics::ASK_FOR_BASELINE
|
||||
? aChildFrame->GetBaseline() : aDesiredSize.ascent;
|
||||
aDesiredSize.mBoundingMetrics.ascent = frameAscent - r.y;
|
||||
aDesiredSize.mBoundingMetrics.descent = r.YMost() - frameAscent;
|
||||
aDesiredSize.mBoundingMetrics.width = aDesiredSize.width;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -1051,8 +1047,7 @@ nsMathMLContainerFrame::Reflow(nsPresContext* aPresContext,
|
||||
|
||||
nsReflowStatus childStatus;
|
||||
nsSize availSize(aReflowState.ComputedWidth(), aReflowState.ComputedHeight());
|
||||
nsHTMLReflowMetrics childDesiredSize(
|
||||
aDesiredSize.mFlags | NS_REFLOW_CALC_BOUNDING_METRICS);
|
||||
nsHTMLReflowMetrics childDesiredSize(aDesiredSize.mFlags);
|
||||
nsIFrame* childFrame = mFrames.FirstChild();
|
||||
while (childFrame) {
|
||||
nsHTMLReflowState childReflowState(aPresContext, aReflowState,
|
||||
@ -1443,13 +1438,16 @@ nsMathMLContainerFrame::DidReflowChildren(nsIFrame* aFirst, nsIFrame* aStop)
|
||||
//==========================
|
||||
|
||||
nsIFrame*
|
||||
NS_NewMathMLmathBlockFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
|
||||
NS_NewMathMLmathBlockFrame(nsIPresShell* aPresShell, nsStyleContext* aContext,
|
||||
PRUint32 aFlags)
|
||||
{
|
||||
return new (aPresShell) nsMathMLmathBlockFrame(aContext);
|
||||
nsMathMLmathBlockFrame* it = new (aPresShell) nsMathMLmathBlockFrame(aContext);
|
||||
if (it) {
|
||||
it->SetFlags(aFlags);
|
||||
}
|
||||
return it;
|
||||
}
|
||||
|
||||
//==========================
|
||||
|
||||
nsIFrame*
|
||||
NS_NewMathMLmathInlineFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
|
||||
{
|
||||
|
@ -120,7 +120,8 @@ public:
|
||||
|
||||
virtual PRBool IsFrameOfType(PRUint32 aFlags) const
|
||||
{
|
||||
return nsHTMLContainerFrame::IsFrameOfType(aFlags & ~(nsIFrame::eMathML));
|
||||
return !(aFlags & nsIFrame::eLineParticipant) &&
|
||||
nsHTMLContainerFrame::IsFrameOfType(aFlags & ~(nsIFrame::eMathML));
|
||||
}
|
||||
|
||||
NS_IMETHOD
|
||||
@ -222,13 +223,6 @@ public:
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus);
|
||||
|
||||
nsresult
|
||||
ReflowForeignChild(nsIFrame* aKidFrame,
|
||||
nsPresContext* aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus);
|
||||
|
||||
// helper to add the inter-spacing when <math> is the immediate parent.
|
||||
// Since we don't (yet) handle the root <math> element ourselves, we need to
|
||||
// take special care of the inter-frame spacing on elements for which <math>
|
||||
@ -330,7 +324,8 @@ protected:
|
||||
// Issues: If/when mathml becomes a pluggable component, the separation will be needed.
|
||||
class nsMathMLmathBlockFrame : public nsBlockFrame {
|
||||
public:
|
||||
friend nsIFrame* NS_NewMathMLmathBlockFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
|
||||
friend nsIFrame* NS_NewMathMLmathBlockFrame(nsIPresShell* aPresShell,
|
||||
nsStyleContext* aContext, PRUint32 aFlags);
|
||||
|
||||
// beware, mFrames is not set by nsBlockFrame
|
||||
// cannot use mFrames{.FirstChild()|.etc} since the block code doesn't set mFrames
|
||||
|
@ -70,12 +70,12 @@ nsIFrame* NS_NewMathMLmsqrtFrame(nsIPresShell* aPresShell, nsStyleContext* aCont
|
||||
nsIFrame* NS_NewMathMLmrootFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
|
||||
nsIFrame* NS_NewMathMLmactionFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
|
||||
|
||||
nsIFrame* NS_NewMathMLmathBlockFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
|
||||
nsIFrame* NS_NewMathMLmathBlockFrame(nsIPresShell* aPresShell, nsStyleContext* aContext, PRUint32 aFlags);
|
||||
nsIFrame* NS_NewMathMLmathInlineFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
|
||||
inline nsIFrame* NS_NewMathMLmathFrame(nsIPresShell* aPresShell, PRBool aIsBlock, nsStyleContext* aContext)
|
||||
{
|
||||
return (aIsBlock)
|
||||
? NS_NewMathMLmathBlockFrame(aPresShell, aContext)
|
||||
? NS_NewMathMLmathBlockFrame(aPresShell, aContext, 0)
|
||||
: NS_NewMathMLmathInlineFrame(aPresShell, aContext);
|
||||
}
|
||||
#endif /* nsMathMLParts_h___ */
|
||||
|
Loading…
Reference in New Issue
Block a user