mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 21:31:04 +00:00
Bug 1388614 - Make sure MathML display items are unique. r=karlt
FrameLayerBuilder requires the the (frame,per-frame-key) for each display item is unique. It only enforces this in certain situations though, so there's cases where we've gotten away without this. Retained display lists introduces more situations where we rely on this, so I've found a few. MathML nsDisplayNotation and nsDisplayMathMLBar are the two fixed by this patch.
This commit is contained in:
parent
95f2e31f88
commit
f47c170811
@ -328,8 +328,8 @@ nsMathMLFrame::DisplayBoundingMetrics(nsDisplayListBuilder* aBuilder,
|
||||
class nsDisplayMathMLBar : public nsDisplayItem {
|
||||
public:
|
||||
nsDisplayMathMLBar(nsDisplayListBuilder* aBuilder,
|
||||
nsIFrame* aFrame, const nsRect& aRect)
|
||||
: nsDisplayItem(aBuilder, aFrame), mRect(aRect) {
|
||||
nsIFrame* aFrame, const nsRect& aRect, uint32_t aIndex)
|
||||
: nsDisplayItem(aBuilder, aFrame), mRect(aRect), mIndex(aIndex) {
|
||||
MOZ_COUNT_CTOR(nsDisplayMathMLBar);
|
||||
}
|
||||
#ifdef NS_BUILD_REFCNT_LOGGING
|
||||
@ -338,11 +338,16 @@ public:
|
||||
}
|
||||
#endif
|
||||
|
||||
virtual uint32_t GetPerFrameKey() override {
|
||||
return (mIndex << TYPE_BITS) | nsDisplayItem::GetPerFrameKey();
|
||||
}
|
||||
|
||||
virtual void Paint(nsDisplayListBuilder* aBuilder,
|
||||
gfxContext* aCtx) override;
|
||||
NS_DISPLAY_DECL_NAME("MathMLBar", TYPE_MATHML_BAR)
|
||||
private:
|
||||
nsRect mRect;
|
||||
uint32_t mIndex;
|
||||
};
|
||||
|
||||
void nsDisplayMathMLBar::Paint(nsDisplayListBuilder* aBuilder,
|
||||
@ -362,12 +367,13 @@ void nsDisplayMathMLBar::Paint(nsDisplayListBuilder* aBuilder,
|
||||
void
|
||||
nsMathMLFrame::DisplayBar(nsDisplayListBuilder* aBuilder,
|
||||
nsIFrame* aFrame, const nsRect& aRect,
|
||||
const nsDisplayListSet& aLists) {
|
||||
const nsDisplayListSet& aLists,
|
||||
uint32_t aIndex) {
|
||||
if (!aFrame->StyleVisibility()->IsVisible() || aRect.IsEmpty())
|
||||
return;
|
||||
|
||||
aLists.Content()->AppendNewToTop(new (aBuilder)
|
||||
nsDisplayMathMLBar(aBuilder, aFrame, aRect));
|
||||
nsDisplayMathMLBar(aBuilder, aFrame, aRect, aIndex));
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -363,7 +363,8 @@ protected:
|
||||
*/
|
||||
void DisplayBar(nsDisplayListBuilder* aBuilder,
|
||||
nsIFrame* aFrame, const nsRect& aRect,
|
||||
const nsDisplayListSet& aLists);
|
||||
const nsDisplayListSet& aLists,
|
||||
uint32_t aIndex = 0);
|
||||
|
||||
// information about the presentation policy of the frame
|
||||
nsPresentationData mPresentationData;
|
||||
|
@ -47,7 +47,7 @@ NS_NewMathMLmencloseFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
|
||||
NS_IMPL_FRAMEARENA_HELPERS(nsMathMLmencloseFrame)
|
||||
|
||||
nsMathMLmencloseFrame::nsMathMLmencloseFrame(nsStyleContext* aContext, ClassID aID) :
|
||||
nsMathMLContainerFrame(aContext, aID), mNotationsToDraw(0),
|
||||
nsMathMLContainerFrame(aContext, aID),
|
||||
mRuleThickness(0), mRadicalRuleThickness(0),
|
||||
mLongDivCharIndex(-1), mRadicalCharIndex(-1), mContentWidth(0)
|
||||
{
|
||||
@ -99,42 +99,47 @@ nsresult nsMathMLmencloseFrame::AddNotation(const nsAString& aNotation)
|
||||
if (aNotation.EqualsLiteral("longdiv")) {
|
||||
rv = AllocateMathMLChar(NOTATION_LONGDIV);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
mNotationsToDraw |= NOTATION_LONGDIV;
|
||||
mNotationsToDraw += NOTATION_LONGDIV;
|
||||
} else if (aNotation.EqualsLiteral("actuarial")) {
|
||||
mNotationsToDraw |= (NOTATION_RIGHT | NOTATION_TOP);
|
||||
mNotationsToDraw += NOTATION_RIGHT;
|
||||
mNotationsToDraw += NOTATION_TOP;
|
||||
} else if (aNotation.EqualsLiteral("radical")) {
|
||||
rv = AllocateMathMLChar(NOTATION_RADICAL);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
mNotationsToDraw |= NOTATION_RADICAL;
|
||||
mNotationsToDraw += NOTATION_RADICAL;
|
||||
} else if (aNotation.EqualsLiteral("box")) {
|
||||
mNotationsToDraw |= (NOTATION_LEFT | NOTATION_RIGHT |
|
||||
NOTATION_TOP | NOTATION_BOTTOM);
|
||||
mNotationsToDraw += NOTATION_LEFT;
|
||||
mNotationsToDraw += NOTATION_RIGHT;
|
||||
mNotationsToDraw += NOTATION_TOP;
|
||||
mNotationsToDraw += NOTATION_BOTTOM;
|
||||
} else if (aNotation.EqualsLiteral("roundedbox")) {
|
||||
mNotationsToDraw |= NOTATION_ROUNDEDBOX;
|
||||
mNotationsToDraw += NOTATION_ROUNDEDBOX;
|
||||
} else if (aNotation.EqualsLiteral("circle")) {
|
||||
mNotationsToDraw |= NOTATION_CIRCLE;
|
||||
mNotationsToDraw += NOTATION_CIRCLE;
|
||||
} else if (aNotation.EqualsLiteral("left")) {
|
||||
mNotationsToDraw |= NOTATION_LEFT;
|
||||
mNotationsToDraw += NOTATION_LEFT;
|
||||
} else if (aNotation.EqualsLiteral("right")) {
|
||||
mNotationsToDraw |= NOTATION_RIGHT;
|
||||
mNotationsToDraw += NOTATION_RIGHT;
|
||||
} else if (aNotation.EqualsLiteral("top")) {
|
||||
mNotationsToDraw |= NOTATION_TOP;
|
||||
mNotationsToDraw += NOTATION_TOP;
|
||||
} else if (aNotation.EqualsLiteral("bottom")) {
|
||||
mNotationsToDraw |= NOTATION_BOTTOM;
|
||||
mNotationsToDraw += NOTATION_BOTTOM;
|
||||
} else if (aNotation.EqualsLiteral("updiagonalstrike")) {
|
||||
mNotationsToDraw |= NOTATION_UPDIAGONALSTRIKE;
|
||||
mNotationsToDraw += NOTATION_UPDIAGONALSTRIKE;
|
||||
} else if (aNotation.EqualsLiteral("updiagonalarrow")) {
|
||||
mNotationsToDraw |= NOTATION_UPDIAGONALARROW;
|
||||
mNotationsToDraw += NOTATION_UPDIAGONALARROW;
|
||||
} else if (aNotation.EqualsLiteral("downdiagonalstrike")) {
|
||||
mNotationsToDraw |= NOTATION_DOWNDIAGONALSTRIKE;
|
||||
mNotationsToDraw += NOTATION_DOWNDIAGONALSTRIKE;
|
||||
} else if (aNotation.EqualsLiteral("verticalstrike")) {
|
||||
mNotationsToDraw |= NOTATION_VERTICALSTRIKE;
|
||||
mNotationsToDraw += NOTATION_VERTICALSTRIKE;
|
||||
} else if (aNotation.EqualsLiteral("horizontalstrike")) {
|
||||
mNotationsToDraw |= NOTATION_HORIZONTALSTRIKE;
|
||||
mNotationsToDraw += NOTATION_HORIZONTALSTRIKE;
|
||||
} else if (aNotation.EqualsLiteral("madruwb")) {
|
||||
mNotationsToDraw |= (NOTATION_RIGHT | NOTATION_BOTTOM);
|
||||
mNotationsToDraw += NOTATION_RIGHT;
|
||||
mNotationsToDraw += NOTATION_BOTTOM;
|
||||
} else if (aNotation.EqualsLiteral("phasorangle")) {
|
||||
mNotationsToDraw |= (NOTATION_BOTTOM | NOTATION_PHASORANGLE);
|
||||
mNotationsToDraw += NOTATION_BOTTOM;
|
||||
mNotationsToDraw += NOTATION_PHASORANGLE;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
@ -145,7 +150,7 @@ nsresult nsMathMLmencloseFrame::AddNotation(const nsAString& aNotation)
|
||||
*/
|
||||
void nsMathMLmencloseFrame::InitNotations()
|
||||
{
|
||||
mNotationsToDraw = 0;
|
||||
mNotationsToDraw.clear();
|
||||
mLongDivCharIndex = mRadicalCharIndex = -1;
|
||||
mMathMLChar.Clear();
|
||||
|
||||
@ -163,13 +168,13 @@ void nsMathMLmencloseFrame::InitNotations()
|
||||
// the two notations are drawn then the strike line may cause the point of
|
||||
// the arrow to be too wide. Hence we will only draw the updiagonalarrow
|
||||
// and the arrow shaft may be thought to be the updiagonalstrike.
|
||||
mNotationsToDraw &= ~NOTATION_UPDIAGONALSTRIKE;
|
||||
mNotationsToDraw -= NOTATION_UPDIAGONALSTRIKE;
|
||||
}
|
||||
} else {
|
||||
// default: longdiv
|
||||
if (NS_FAILED(AllocateMathMLChar(NOTATION_LONGDIV)))
|
||||
return;
|
||||
mNotationsToDraw = NOTATION_LONGDIV;
|
||||
mNotationsToDraw += NOTATION_LONGDIV;
|
||||
}
|
||||
}
|
||||
|
||||
@ -220,7 +225,7 @@ nsMathMLmencloseFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
||||
mMathMLChar[mRadicalCharIndex].GetRect(rect);
|
||||
rect.MoveBy(StyleVisibility()->mDirection ? -mContentWidth : rect.width, 0);
|
||||
rect.SizeTo(mContentWidth, mRadicalRuleThickness);
|
||||
DisplayBar(aBuilder, this, rect, aLists);
|
||||
DisplayBar(aBuilder, this, rect, aLists, NOTATION_RADICAL);
|
||||
}
|
||||
|
||||
if (IsToDraw(NOTATION_PHASORANGLE)) {
|
||||
@ -234,29 +239,29 @@ nsMathMLmencloseFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
||||
nsRect rect;
|
||||
mMathMLChar[mLongDivCharIndex].GetRect(rect);
|
||||
rect.SizeTo(rect.width + mContentWidth, mRuleThickness);
|
||||
DisplayBar(aBuilder, this, rect, aLists);
|
||||
DisplayBar(aBuilder, this, rect, aLists, NOTATION_LONGDIV);
|
||||
}
|
||||
|
||||
if (IsToDraw(NOTATION_TOP)) {
|
||||
nsRect rect(0, 0, mencloseRect.width, mRuleThickness);
|
||||
DisplayBar(aBuilder, this, rect, aLists);
|
||||
DisplayBar(aBuilder, this, rect, aLists, NOTATION_TOP);
|
||||
}
|
||||
|
||||
if (IsToDraw(NOTATION_BOTTOM)) {
|
||||
nsRect rect(0, mencloseRect.height - mRuleThickness,
|
||||
mencloseRect.width, mRuleThickness);
|
||||
DisplayBar(aBuilder, this, rect, aLists);
|
||||
DisplayBar(aBuilder, this, rect, aLists, NOTATION_BOTTOM);
|
||||
}
|
||||
|
||||
if (IsToDraw(NOTATION_LEFT)) {
|
||||
nsRect rect(0, 0, mRuleThickness, mencloseRect.height);
|
||||
DisplayBar(aBuilder, this, rect, aLists);
|
||||
DisplayBar(aBuilder, this, rect, aLists, NOTATION_LEFT);
|
||||
}
|
||||
|
||||
if (IsToDraw(NOTATION_RIGHT)) {
|
||||
nsRect rect(mencloseRect.width - mRuleThickness, 0,
|
||||
mRuleThickness, mencloseRect.height);
|
||||
DisplayBar(aBuilder, this, rect, aLists);
|
||||
DisplayBar(aBuilder, this, rect, aLists, NOTATION_RIGHT);
|
||||
}
|
||||
|
||||
if (IsToDraw(NOTATION_ROUNDEDBOX)) {
|
||||
@ -287,13 +292,13 @@ nsMathMLmencloseFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
||||
if (IsToDraw(NOTATION_HORIZONTALSTRIKE)) {
|
||||
nsRect rect(0, mencloseRect.height / 2 - mRuleThickness / 2,
|
||||
mencloseRect.width, mRuleThickness);
|
||||
DisplayBar(aBuilder, this, rect, aLists);
|
||||
DisplayBar(aBuilder, this, rect, aLists, NOTATION_HORIZONTALSTRIKE);
|
||||
}
|
||||
|
||||
if (IsToDraw(NOTATION_VERTICALSTRIKE)) {
|
||||
nsRect rect(mencloseRect.width / 2 - mRuleThickness / 2, 0,
|
||||
mRuleThickness, mencloseRect.height);
|
||||
DisplayBar(aBuilder, this, rect, aLists);
|
||||
DisplayBar(aBuilder, this, rect, aLists, NOTATION_VERTICALSTRIKE);
|
||||
}
|
||||
}
|
||||
|
||||
@ -756,6 +761,10 @@ public:
|
||||
}
|
||||
#endif
|
||||
|
||||
virtual uint32_t GetPerFrameKey() override {
|
||||
return (mType << TYPE_BITS) | nsDisplayItem::GetPerFrameKey();
|
||||
}
|
||||
|
||||
virtual void Paint(nsDisplayListBuilder* aBuilder,
|
||||
gfxContext* aCtx) override;
|
||||
NS_DISPLAY_DECL_NAME("MathMLMencloseNotation", TYPE_MATHML_MENCLOSE_NOTATION)
|
||||
|
@ -8,6 +8,7 @@
|
||||
#define nsMathMLmencloseFrame_h___
|
||||
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/EnumSet.h"
|
||||
#include "nsMathMLContainerFrame.h"
|
||||
|
||||
//
|
||||
@ -26,20 +27,20 @@
|
||||
|
||||
enum nsMencloseNotation
|
||||
{
|
||||
NOTATION_LONGDIV = 0x1,
|
||||
NOTATION_RADICAL = 0x2,
|
||||
NOTATION_ROUNDEDBOX = 0x4,
|
||||
NOTATION_CIRCLE = 0x8,
|
||||
NOTATION_LEFT = 0x10,
|
||||
NOTATION_RIGHT = 0x20,
|
||||
NOTATION_TOP = 0x40,
|
||||
NOTATION_BOTTOM = 0x80,
|
||||
NOTATION_UPDIAGONALSTRIKE = 0x100,
|
||||
NOTATION_DOWNDIAGONALSTRIKE = 0x200,
|
||||
NOTATION_VERTICALSTRIKE = 0x400,
|
||||
NOTATION_HORIZONTALSTRIKE = 0x800,
|
||||
NOTATION_UPDIAGONALARROW = 0x1000,
|
||||
NOTATION_PHASORANGLE = 0x2000
|
||||
NOTATION_LONGDIV,
|
||||
NOTATION_RADICAL,
|
||||
NOTATION_ROUNDEDBOX,
|
||||
NOTATION_CIRCLE,
|
||||
NOTATION_LEFT,
|
||||
NOTATION_RIGHT,
|
||||
NOTATION_TOP,
|
||||
NOTATION_BOTTOM,
|
||||
NOTATION_UPDIAGONALSTRIKE,
|
||||
NOTATION_DOWNDIAGONALSTRIKE,
|
||||
NOTATION_VERTICALSTRIKE,
|
||||
NOTATION_HORIZONTALSTRIKE,
|
||||
NOTATION_UPDIAGONALARROW,
|
||||
NOTATION_PHASORANGLE
|
||||
};
|
||||
|
||||
class nsMathMLmencloseFrame : public nsMathMLContainerFrame {
|
||||
@ -101,10 +102,10 @@ protected:
|
||||
void InitNotations();
|
||||
|
||||
// Description of the notations to draw
|
||||
uint32_t mNotationsToDraw;
|
||||
bool IsToDraw(nsMencloseNotation mask)
|
||||
mozilla::EnumSet<nsMencloseNotation> mNotationsToDraw;
|
||||
bool IsToDraw(nsMencloseNotation notation)
|
||||
{
|
||||
return mask & mNotationsToDraw;
|
||||
return mNotationsToDraw.contains(notation);
|
||||
}
|
||||
|
||||
nscoord mRuleThickness;
|
||||
|
@ -34,7 +34,7 @@ nsMathMLmsqrtFrame::Init(nsIContent* aContent,
|
||||
{
|
||||
nsMathMLContainerFrame::Init(aContent, aParent, aPrevInFlow);
|
||||
AllocateMathMLChar(NOTATION_RADICAL);
|
||||
mNotationsToDraw |= NOTATION_RADICAL;
|
||||
mNotationsToDraw += NOTATION_RADICAL;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
Loading…
Reference in New Issue
Block a user