Bug 655877 - Part 45: Fixes for DLBI. r=roc,jwatt

This commit is contained in:
Cameron McCormack 2013-02-11 17:22:20 +11:00
Родитель 78f3f08de3
Коммит 2885f1362f
10 изменённых файлов: 124 добавлений и 18 удалений

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

@ -487,6 +487,30 @@ nsBlockFrame::GetType() const
return nsGkAtoms::blockFrame;
}
void
nsBlockFrame::InvalidateFrame(uint32_t aDisplayItemKey)
{
if (IsSVGText()) {
NS_ASSERTION(GetParent()->GetType() == nsGkAtoms::svgTextFrame2,
"unexpected block frame in SVG text");
GetParent()->InvalidateFrame();
return;
}
nsBlockFrameSuper::InvalidateFrame(aDisplayItemKey);
}
void
nsBlockFrame::InvalidateFrameWithRect(const nsRect& aRect, uint32_t aDisplayItemKey)
{
if (IsSVGText()) {
NS_ASSERTION(GetParent()->GetType() == nsGkAtoms::svgTextFrame2,
"unexpected block frame in SVG text");
GetParent()->InvalidateFrame();
return;
}
nsBlockFrameSuper::InvalidateFrameWithRect(aRect, aDisplayItemKey);
}
nscoord
nsBlockFrame::GetBaseline() const
{

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

@ -165,6 +165,9 @@ public:
nsIFrame::eBlockFrame));
}
virtual void InvalidateFrame(uint32_t aDisplayItemKey = 0);
virtual void InvalidateFrameWithRect(const nsRect& aRect, uint32_t aDisplayItemKey = 0);
#ifdef DEBUG
NS_IMETHOD List(FILE* out, int32_t aIndent, uint32_t aFlags = 0) const;
NS_IMETHOD_(nsFrameState) GetDebugStateBits() const;

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

@ -59,6 +59,32 @@ nsInlineFrame::GetType() const
return nsGkAtoms::inlineFrame;
}
void
nsInlineFrame::InvalidateFrame(uint32_t aDisplayItemKey)
{
if (IsSVGText()) {
nsIFrame* svgTextFrame =
nsLayoutUtils::GetClosestFrameOfType(GetParent(),
nsGkAtoms::svgTextFrame2);
svgTextFrame->InvalidateFrame();
return;
}
nsInlineFrameBase::InvalidateFrame(aDisplayItemKey);
}
void
nsInlineFrame::InvalidateFrameWithRect(const nsRect& aRect, uint32_t aDisplayItemKey)
{
if (IsSVGText()) {
nsIFrame* svgTextFrame =
nsLayoutUtils::GetClosestFrameOfType(GetParent(),
nsGkAtoms::svgTextFrame2);
svgTextFrame->InvalidateFrame();
return;
}
nsInlineFrameBase::InvalidateFrameWithRect(aRect, aDisplayItemKey);
}
static inline bool
IsMarginZero(const nsStyleCoord &aCoord)
{

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

@ -24,13 +24,15 @@ class nsLineLayout;
#define NS_INLINE_FRAME_BIDI_VISUAL_IS_RIGHT_MOST NS_FRAME_STATE_BIT(23)
typedef nsContainerFrame nsInlineFrameBase;
/**
* Inline frame class.
*
* This class manages a list of child frames that are inline frames. Working with
* nsLineLayout, the class will reflow and place inline frames on a line.
*/
class nsInlineFrame : public nsContainerFrame
class nsInlineFrame : public nsInlineFrameBase
{
public:
NS_DECL_QUERYFRAME_TARGET(nsInlineFrame)
@ -62,6 +64,9 @@ public:
~(nsIFrame::eBidiInlineContainer | nsIFrame::eLineParticipant));
}
virtual void InvalidateFrame(uint32_t aDisplayItemKey = 0);
virtual void InvalidateFrameWithRect(const nsRect& aRect, uint32_t aDisplayItemKey = 0);
virtual bool IsEmpty() MOZ_OVERRIDE;
virtual bool IsSelfEmpty() MOZ_OVERRIDE;

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

@ -118,6 +118,9 @@ public:
nsIFrame::eLineParticipant));
}
virtual void InvalidateFrame(uint32_t aDisplayItemKey = 0);
virtual void InvalidateFrameWithRect(const nsRect& aRect, uint32_t aDisplayItemKey = 0);
#ifdef DEBUG
NS_IMETHOD List(FILE* out, int32_t aIndent, uint32_t aFlags = 0) const;
NS_IMETHOD GetFrameName(nsAString& aResult) const;

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

@ -4308,6 +4308,7 @@ nsTextFrame::GetLastInFlow() const
NS_POSTCONDITION(lastInFlow, "illegal state in flow chain.");
return lastInFlow;
}
nsIFrame*
nsTextFrame::GetLastContinuation() const
{
@ -4319,6 +4320,32 @@ nsTextFrame::GetLastContinuation() const
return lastInFlow;
}
void
nsTextFrame::InvalidateFrame(uint32_t aDisplayItemKey)
{
if (IsSVGText()) {
nsIFrame* svgTextFrame =
nsLayoutUtils::GetClosestFrameOfType(GetParent(),
nsGkAtoms::svgTextFrame2);
svgTextFrame->InvalidateFrame();
return;
}
nsTextFrameBase::InvalidateFrame(aDisplayItemKey);
}
void
nsTextFrame::InvalidateFrameWithRect(const nsRect& aRect, uint32_t aDisplayItemKey)
{
if (IsSVGText()) {
nsIFrame* svgTextFrame =
nsLayoutUtils::GetClosestFrameOfType(GetParent(),
nsGkAtoms::svgTextFrame2);
svgTextFrame->InvalidateFrame();
return;
}
nsTextFrameBase::InvalidateFrameWithRect(aRect, aDisplayItemKey);
}
gfxTextRun*
nsTextFrame::GetUninflatedTextRun()
{

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

@ -288,6 +288,13 @@ nsSVGMarkerProperty::DoUpdate()
mFrame->GetContent()->AsElement(), nsRestyleHint(0), changeHint);
}
bool
nsSVGTextPathProperty::TargetIsValid()
{
Element* target = GetTarget();
return target && target->IsSVG(nsGkAtoms::path);
}
void
nsSVGTextPathProperty::DoUpdate()
{
@ -298,6 +305,23 @@ nsSVGTextPathProperty::DoUpdate()
NS_ASSERTION(mFrame->IsFrameOfType(nsIFrame::eSVG) || mFrame->IsSVGText(),
"SVG frame expected");
// Avoid getting into an infinite loop of reflows if the <textPath> is
// pointing to one of its ancestors. TargetIsValid returns true iff
// the target element is a <path> element, and we would not have this
// nsSVGTextPathProperty if this <textPath> were a descendant of the
// target <path>.
//
// Note that we still have to post the restyle event when we
// change from being valid to invalid, so that mPositions on the
// nsSVGTextFrame2 gets updated, skipping the <textPath>, ensuring
// that nothing gets painted for that element.
bool nowValid = TargetIsValid();
if (!mValid && !nowValid) {
// Just return if we were previously invalid, and are still invalid.
return;
}
mValid = nowValid;
// Repaint asynchronously in case the path frame is being torn down
nsChangeHint changeHint =
nsChangeHint(nsChangeHint_RepaintFrame | nsChangeHint_UpdateTextPath);

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

@ -141,7 +141,7 @@ protected:
SourceReference mElement;
// The frame that this property is attached to
nsIFrame *mFrame;
nsIFrame *mFrame;
// When a presshell is torn down, we don't delete the properties for
// each frame until after the frames are destroyed. So here we remember
// the presshell for the frames we care about and, before we use the frame,
@ -185,12 +185,21 @@ protected:
class nsSVGTextPathProperty : public nsSVGIDRenderingObserver {
public:
nsSVGTextPathProperty(nsIURI *aURI, nsIFrame *aFrame, bool aReferenceImage)
: nsSVGIDRenderingObserver(aURI, aFrame, aReferenceImage) {}
: nsSVGIDRenderingObserver(aURI, aFrame, aReferenceImage)
, mValid(true) {}
virtual bool ObservesReflow() MOZ_OVERRIDE { return false; }
protected:
virtual void DoUpdate() MOZ_OVERRIDE;
private:
/**
* Returns true if the target of the textPath is the frame of a 'path' element.
*/
bool TargetIsValid();
bool mValid;
};
class nsSVGPaintingProperty : public nsSVGIDRenderingObserver {

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

@ -2942,17 +2942,6 @@ nsSVGTextFrame2::Reflow(nsPresContext* aPresContext,
return NS_OK;
}
void
nsSVGTextFrame2::InvalidateInternal(const nsRect& aDamageRect,
nscoord aX, nscoord aY,
nsIFrame* aForChild, uint32_t aFlags)
{
// This is called by our descendants when they change.
// We just invalidate our entire area for now.
nsSVGUtils::InvalidateBounds
(this, nsSVGUtils::OuterSVGIsCallingReflowSVG(this), nullptr, aFlags);
}
void
nsSVGTextFrame2::FindCloserFrameForSelection(
nsPoint aPoint,

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

@ -211,10 +211,6 @@ public:
}
#endif
virtual void InvalidateInternal(const nsRect& aDamageRect,
nscoord aX, nscoord aY, nsIFrame* aForChild,
uint32_t aFlags);
/**
* Finds the nsTextFrame for the closest rendered run to the specified point.
*/