mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-22 17:55:50 +00:00
148bb081ca
I did many change in many files in this patch. But the goal is pretty simple: To pass the return value of nsSVGPatternFrame::PaintPattern back to the caller (nsDisplaySVGGeometry). My suggestion is to review this patch right from nsSVGPatternFrame.cpp. I made two mistakes in bug 1258510 1. We should not return directly at [1]. RemoveStateBits at l418 will be skip. 2. nsSVGPatternFrame::PaintPattern should return both SourceSurface and draw result, so that we can update UpdateDrawResult in display item. All the other changes are to 1. make sure the return value of nsSVGPatternFrame::PaintPattern goes back to nsDisplaySVGGeometry::Paint correctly. 2. Since the return value of nsSVGPatternFrame::PaintPattern change, we need modify all existed callers. I also filed bug 1346124 for handle the returning value of PaintMarkers. [1] https://hg.mozilla.org/mozilla-central/file/c0700bedb4f7/layout/svg/nsSVGPatternFrame.cpp#l415 MozReview-Commit-ID: Iq9RPQ6Omz0 --HG-- extra : rebase_source : ca7a35bb9f5e27880d5dc62e03feb91b6ac3435d
210 lines
7.3 KiB
C++
210 lines
7.3 KiB
C++
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
#ifndef __NS_SVGGRADIENTFRAME_H__
|
|
#define __NS_SVGGRADIENTFRAME_H__
|
|
|
|
#include "mozilla/Attributes.h"
|
|
#include "gfxMatrix.h"
|
|
#include "nsCOMPtr.h"
|
|
#include "nsFrame.h"
|
|
#include "nsLiteralString.h"
|
|
#include "nsSVGPaintServerFrame.h"
|
|
|
|
class gfxPattern;
|
|
class nsIAtom;
|
|
class nsIContent;
|
|
class nsIFrame;
|
|
class nsIPresShell;
|
|
class nsStyleContext;
|
|
|
|
struct gfxRect;
|
|
|
|
namespace mozilla {
|
|
class nsSVGAnimatedTransformList;
|
|
|
|
namespace dom {
|
|
class SVGLinearGradientElement;
|
|
class SVGRadialGradientElement;
|
|
} // namespace dom
|
|
} // namespace mozilla
|
|
|
|
/**
|
|
* Gradients can refer to other gradients. We create an nsSVGPaintingProperty
|
|
* with property type nsGkAtoms::href to track the referenced gradient.
|
|
*/
|
|
class nsSVGGradientFrame : public nsSVGPaintServerFrame
|
|
{
|
|
typedef mozilla::gfx::ExtendMode ExtendMode;
|
|
|
|
protected:
|
|
explicit nsSVGGradientFrame(nsStyleContext* aContext);
|
|
|
|
public:
|
|
NS_DECL_ABSTRACT_FRAME(nsSVGGradientFrame)
|
|
|
|
// nsSVGPaintServerFrame methods:
|
|
virtual mozilla::Pair<DrawResult, RefPtr<gfxPattern>>
|
|
GetPaintServerPattern(nsIFrame* aSource,
|
|
const DrawTarget* aDrawTarget,
|
|
const gfxMatrix& aContextMatrix,
|
|
nsStyleSVGPaint nsStyleSVG::*aFillOrStroke,
|
|
float aGraphicOpacity,
|
|
const gfxRect* aOverrideBounds) override;
|
|
|
|
// nsIFrame interface:
|
|
virtual nsresult AttributeChanged(int32_t aNameSpaceID,
|
|
nsIAtom* aAttribute,
|
|
int32_t aModType) override;
|
|
|
|
#ifdef DEBUG_FRAME_DUMP
|
|
virtual nsresult GetFrameName(nsAString& aResult) const override
|
|
{
|
|
return MakeFrameName(NS_LITERAL_STRING("SVGGradient"), aResult);
|
|
}
|
|
#endif // DEBUG
|
|
|
|
private:
|
|
|
|
// Parse our xlink:href and set up our nsSVGPaintingProperty if we
|
|
// reference another gradient and we don't have a property. Return
|
|
// the referenced gradient's frame if available, null otherwise.
|
|
nsSVGGradientFrame* GetReferencedGradient();
|
|
|
|
// Optionally get a stop frame (returns stop index/count)
|
|
void GetStopFrames(nsTArray<nsIFrame*>* aStopFrames);
|
|
|
|
const mozilla::nsSVGAnimatedTransformList* GetGradientTransformList(
|
|
nsIContent* aDefault);
|
|
// Will be singular for gradientUnits="objectBoundingBox" with an empty bbox.
|
|
gfxMatrix GetGradientTransform(nsIFrame *aSource,
|
|
const gfxRect *aOverrideBounds);
|
|
|
|
protected:
|
|
virtual bool GradientVectorLengthIsZero() = 0;
|
|
virtual already_AddRefed<gfxPattern> CreateGradient() = 0;
|
|
|
|
// Accessors to lookup gradient attributes
|
|
uint16_t GetEnumValue(uint32_t aIndex, nsIContent *aDefault);
|
|
uint16_t GetEnumValue(uint32_t aIndex)
|
|
{
|
|
return GetEnumValue(aIndex, mContent);
|
|
}
|
|
uint16_t GetGradientUnits();
|
|
uint16_t GetSpreadMethod();
|
|
|
|
// Gradient-type-specific lookups since the length values differ between
|
|
// linear and radial gradients
|
|
virtual mozilla::dom::SVGLinearGradientElement * GetLinearGradientWithLength(
|
|
uint32_t aIndex, mozilla::dom::SVGLinearGradientElement* aDefault);
|
|
virtual mozilla::dom::SVGRadialGradientElement * GetRadialGradientWithLength(
|
|
uint32_t aIndex, mozilla::dom::SVGRadialGradientElement* aDefault);
|
|
|
|
// The frame our gradient is (currently) being applied to
|
|
nsIFrame* mSource;
|
|
|
|
private:
|
|
// Flag to mark this frame as "in use" during recursive calls along our
|
|
// gradient's reference chain so we can detect reference loops. See:
|
|
// http://www.w3.org/TR/SVG11/pservers.html#LinearGradientElementHrefAttribute
|
|
bool mLoopFlag;
|
|
// Gradients often don't reference other gradients, so here we cache
|
|
// the fact that that isn't happening.
|
|
bool mNoHRefURI;
|
|
};
|
|
|
|
|
|
// -------------------------------------------------------------------------
|
|
// Linear Gradients
|
|
// -------------------------------------------------------------------------
|
|
|
|
class nsSVGLinearGradientFrame : public nsSVGGradientFrame
|
|
{
|
|
friend nsIFrame* NS_NewSVGLinearGradientFrame(nsIPresShell* aPresShell,
|
|
nsStyleContext* aContext);
|
|
protected:
|
|
explicit nsSVGLinearGradientFrame(nsStyleContext* aContext)
|
|
: nsSVGGradientFrame(aContext) {}
|
|
|
|
public:
|
|
NS_DECL_FRAMEARENA_HELPERS
|
|
|
|
// nsIFrame interface:
|
|
#ifdef DEBUG
|
|
virtual void Init(nsIContent* aContent,
|
|
nsContainerFrame* aParent,
|
|
nsIFrame* aPrevInFlow) override;
|
|
#endif
|
|
|
|
virtual nsIAtom* GetType() const override; // frame type: nsGkAtoms::svgLinearGradientFrame
|
|
|
|
virtual nsresult AttributeChanged(int32_t aNameSpaceID,
|
|
nsIAtom* aAttribute,
|
|
int32_t aModType) override;
|
|
|
|
#ifdef DEBUG_FRAME_DUMP
|
|
virtual nsresult GetFrameName(nsAString& aResult) const override
|
|
{
|
|
return MakeFrameName(NS_LITERAL_STRING("SVGLinearGradient"), aResult);
|
|
}
|
|
#endif // DEBUG
|
|
|
|
protected:
|
|
float GetLengthValue(uint32_t aIndex);
|
|
virtual mozilla::dom::SVGLinearGradientElement* GetLinearGradientWithLength(
|
|
uint32_t aIndex, mozilla::dom::SVGLinearGradientElement* aDefault) override;
|
|
virtual bool GradientVectorLengthIsZero() override;
|
|
virtual already_AddRefed<gfxPattern> CreateGradient() override;
|
|
};
|
|
|
|
// -------------------------------------------------------------------------
|
|
// Radial Gradients
|
|
// -------------------------------------------------------------------------
|
|
|
|
class nsSVGRadialGradientFrame : public nsSVGGradientFrame
|
|
{
|
|
friend nsIFrame* NS_NewSVGRadialGradientFrame(nsIPresShell* aPresShell,
|
|
nsStyleContext* aContext);
|
|
protected:
|
|
explicit nsSVGRadialGradientFrame(nsStyleContext* aContext)
|
|
: nsSVGGradientFrame(aContext) {}
|
|
|
|
public:
|
|
NS_DECL_FRAMEARENA_HELPERS
|
|
|
|
// nsIFrame interface:
|
|
#ifdef DEBUG
|
|
virtual void Init(nsIContent* aContent,
|
|
nsContainerFrame* aParent,
|
|
nsIFrame* aPrevInFlow) override;
|
|
#endif
|
|
|
|
virtual nsIAtom* GetType() const override; // frame type: nsGkAtoms::svgRadialGradientFrame
|
|
|
|
virtual nsresult AttributeChanged(int32_t aNameSpaceID,
|
|
nsIAtom* aAttribute,
|
|
int32_t aModType) override;
|
|
|
|
#ifdef DEBUG_FRAME_DUMP
|
|
virtual nsresult GetFrameName(nsAString& aResult) const override
|
|
{
|
|
return MakeFrameName(NS_LITERAL_STRING("SVGRadialGradient"), aResult);
|
|
}
|
|
#endif // DEBUG
|
|
|
|
protected:
|
|
float GetLengthValue(uint32_t aIndex);
|
|
float GetLengthValue(uint32_t aIndex, float aDefaultValue);
|
|
float GetLengthValueFromElement(uint32_t aIndex,
|
|
mozilla::dom::SVGRadialGradientElement& aElement);
|
|
virtual mozilla::dom::SVGRadialGradientElement* GetRadialGradientWithLength(
|
|
uint32_t aIndex, mozilla::dom::SVGRadialGradientElement* aDefault) override;
|
|
virtual bool GradientVectorLengthIsZero() override;
|
|
virtual already_AddRefed<gfxPattern> CreateGradient() override;
|
|
};
|
|
|
|
#endif // __NS_SVGGRADIENTFRAME_H__
|
|
|