зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1492883 p2. Hide the implementation details of SVG rendering observers for markers. r=longsonr
Differential Revision: https://phabricator.services.mozilla.com/D6411 --HG-- extra : rebase_source : d4f1b8ce33809c4664ea2ebe593462bae31db58d
This commit is contained in:
Родитель
b03fed78da
Коммит
7f62854eb1
|
@ -641,34 +641,23 @@ SVGGeometryFrame::GetBBoxContribution(const Matrix &aToBBoxUserspace,
|
|||
|
||||
// Account for markers:
|
||||
if ((aFlags & nsSVGUtils::eBBoxIncludeMarkers) != 0 &&
|
||||
static_cast<SVGGeometryElement*>(GetContent())->IsMarkable()) {
|
||||
|
||||
float strokeWidth = nsSVGUtils::GetStrokeWidth(this);
|
||||
MarkerProperties properties = GetMarkerProperties(this);
|
||||
|
||||
if (properties.MarkersExist()) {
|
||||
element->IsMarkable()) {
|
||||
nsSVGMarkerFrame* markerFrames[nsSVGMark::eTypeCount];
|
||||
if (SVGObserverUtils::GetMarkerFrames(this, &markerFrames)) {
|
||||
nsTArray<nsSVGMark> marks;
|
||||
static_cast<SVGGeometryElement*>(GetContent())->GetMarkPoints(&marks);
|
||||
uint32_t num = marks.Length();
|
||||
|
||||
// These are in the same order as the nsSVGMark::Type constants.
|
||||
nsSVGMarkerFrame* markerFrames[] = {
|
||||
properties.GetMarkerStartFrame(),
|
||||
properties.GetMarkerMidFrame(),
|
||||
properties.GetMarkerEndFrame(),
|
||||
};
|
||||
static_assert(MOZ_ARRAY_LENGTH(markerFrames) == nsSVGMark::eTypeCount,
|
||||
"Number of Marker frames should be equal to eTypeCount");
|
||||
|
||||
for (uint32_t i = 0; i < num; i++) {
|
||||
const nsSVGMark& mark = marks[i];
|
||||
nsSVGMarkerFrame* frame = markerFrames[mark.type];
|
||||
if (frame) {
|
||||
SVGBBox mbbox =
|
||||
frame->GetMarkBBoxContribution(aToBBoxUserspace, aFlags, this,
|
||||
mark, strokeWidth);
|
||||
MOZ_ASSERT(mbbox.IsFinite(), "bbox is about to go bad");
|
||||
bbox.UnionEdges(mbbox);
|
||||
element->GetMarkPoints(&marks);
|
||||
if (uint32_t num = marks.Length()) {
|
||||
float strokeWidth = nsSVGUtils::GetStrokeWidth(this);
|
||||
for (uint32_t i = 0; i < num; i++) {
|
||||
const nsSVGMark& mark = marks[i];
|
||||
nsSVGMarkerFrame* frame = markerFrames[mark.type];
|
||||
if (frame) {
|
||||
SVGBBox mbbox =
|
||||
frame->GetMarkBBoxContribution(aToBBoxUserspace, aFlags, this,
|
||||
mark, strokeWidth);
|
||||
MOZ_ASSERT(mbbox.IsFinite(), "bbox is about to go bad");
|
||||
bbox.UnionEdges(mbbox);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -691,57 +680,6 @@ SVGGeometryFrame::GetCanvasTM()
|
|||
return content->PrependLocalTransformsTo(parent->GetCanvasTM());
|
||||
}
|
||||
|
||||
SVGGeometryFrame::MarkerProperties
|
||||
SVGGeometryFrame::GetMarkerProperties(SVGGeometryFrame *aFrame)
|
||||
{
|
||||
NS_ASSERTION(!aFrame->GetPrevContinuation(), "aFrame should be first continuation");
|
||||
|
||||
MarkerProperties result;
|
||||
RefPtr<URLAndReferrerInfo> markerURL =
|
||||
SVGObserverUtils::GetMarkerURI(aFrame, &nsStyleSVG::mMarkerStart);
|
||||
result.mMarkerStart =
|
||||
SVGObserverUtils::GetMarkerProperty(markerURL, aFrame,
|
||||
SVGObserverUtils::MarkerStartProperty());
|
||||
|
||||
markerURL = SVGObserverUtils::GetMarkerURI(aFrame, &nsStyleSVG::mMarkerMid);
|
||||
result.mMarkerMid =
|
||||
SVGObserverUtils::GetMarkerProperty(markerURL, aFrame,
|
||||
SVGObserverUtils::MarkerMidProperty());
|
||||
|
||||
markerURL = SVGObserverUtils::GetMarkerURI(aFrame, &nsStyleSVG::mMarkerEnd);
|
||||
result.mMarkerEnd =
|
||||
SVGObserverUtils::GetMarkerProperty(markerURL, aFrame,
|
||||
SVGObserverUtils::MarkerEndProperty());
|
||||
return result;
|
||||
}
|
||||
|
||||
nsSVGMarkerFrame *
|
||||
SVGGeometryFrame::MarkerProperties::GetMarkerStartFrame()
|
||||
{
|
||||
if (!mMarkerStart)
|
||||
return nullptr;
|
||||
return static_cast<nsSVGMarkerFrame*>(
|
||||
mMarkerStart->GetReferencedFrame(LayoutFrameType::SVGMarker, nullptr));
|
||||
}
|
||||
|
||||
nsSVGMarkerFrame *
|
||||
SVGGeometryFrame::MarkerProperties::GetMarkerMidFrame()
|
||||
{
|
||||
if (!mMarkerMid)
|
||||
return nullptr;
|
||||
return static_cast<nsSVGMarkerFrame*>(
|
||||
mMarkerMid->GetReferencedFrame(LayoutFrameType::SVGMarker, nullptr));
|
||||
}
|
||||
|
||||
nsSVGMarkerFrame *
|
||||
SVGGeometryFrame::MarkerProperties::GetMarkerEndFrame()
|
||||
{
|
||||
if (!mMarkerEnd)
|
||||
return nullptr;
|
||||
return static_cast<nsSVGMarkerFrame*>(
|
||||
mMarkerEnd->GetReferencedFrame(LayoutFrameType::SVGMarker, nullptr));
|
||||
}
|
||||
|
||||
void
|
||||
SVGGeometryFrame::Render(gfxContext* aContext,
|
||||
uint32_t aRenderComponents,
|
||||
|
@ -866,28 +804,17 @@ SVGGeometryFrame::PaintMarkers(gfxContext& aContext,
|
|||
const gfxMatrix& aTransform,
|
||||
imgDrawingParams& aImgParams)
|
||||
{
|
||||
SVGContextPaint* contextPaint = SVGContextPaint::GetContextPaint(GetContent());
|
||||
if (static_cast<SVGGeometryElement*>(GetContent())->IsMarkable()) {
|
||||
MarkerProperties properties = GetMarkerProperties(this);
|
||||
|
||||
if (properties.MarkersExist()) {
|
||||
float strokeWidth = nsSVGUtils::GetStrokeWidth(this, contextPaint);
|
||||
auto element = static_cast<SVGGeometryElement*>(GetContent());
|
||||
|
||||
if (element->IsMarkable()) {
|
||||
nsSVGMarkerFrame* markerFrames[nsSVGMark::eTypeCount];
|
||||
if (SVGObserverUtils::GetMarkerFrames(this, &markerFrames)) {
|
||||
nsTArray<nsSVGMark> marks;
|
||||
static_cast<SVGGeometryElement*>
|
||||
(GetContent())->GetMarkPoints(&marks);
|
||||
|
||||
uint32_t num = marks.Length();
|
||||
if (num) {
|
||||
// These are in the same order as the nsSVGMark::Type constants.
|
||||
nsSVGMarkerFrame* markerFrames[] = {
|
||||
properties.GetMarkerStartFrame(),
|
||||
properties.GetMarkerMidFrame(),
|
||||
properties.GetMarkerEndFrame(),
|
||||
};
|
||||
static_assert(MOZ_ARRAY_LENGTH(markerFrames) == nsSVGMark::eTypeCount,
|
||||
"Number of Marker frames should be equal to eTypeCount");
|
||||
|
||||
element->GetMarkPoints(&marks);
|
||||
if (uint32_t num = marks.Length()) {
|
||||
SVGContextPaint* contextPaint =
|
||||
SVGContextPaint::GetContextPaint(GetContent());
|
||||
float strokeWidth = nsSVGUtils::GetStrokeWidth(this, contextPaint);
|
||||
for (uint32_t i = 0; i < num; i++) {
|
||||
const nsSVGMark& mark = marks[i];
|
||||
nsSVGMarkerFrame* frame = markerFrames[mark.type];
|
||||
|
|
|
@ -129,25 +129,6 @@ private:
|
|||
*/
|
||||
void PaintMarkers(gfxContext& aContext, const gfxMatrix& aMatrix,
|
||||
imgDrawingParams& aImgParams);
|
||||
|
||||
struct MarkerProperties {
|
||||
SVGMarkerObserver* mMarkerStart;
|
||||
SVGMarkerObserver* mMarkerMid;
|
||||
SVGMarkerObserver* mMarkerEnd;
|
||||
|
||||
bool MarkersExist() const {
|
||||
return mMarkerStart || mMarkerMid || mMarkerEnd;
|
||||
}
|
||||
|
||||
nsSVGMarkerFrame *GetMarkerStartFrame();
|
||||
nsSVGMarkerFrame *GetMarkerMidFrame();
|
||||
nsSVGMarkerFrame *GetMarkerEndFrame();
|
||||
};
|
||||
|
||||
/**
|
||||
* @param aFrame should be the first continuation
|
||||
*/
|
||||
static MarkerProperties GetMarkerProperties(SVGGeometryFrame *aFrame);
|
||||
};
|
||||
} // namespace mozilla
|
||||
|
||||
|
|
|
@ -572,14 +572,37 @@ GetEffectProperty(URLAndReferrerInfo* aURI, nsIFrame* aFrame,
|
|||
return prop;
|
||||
}
|
||||
|
||||
SVGMarkerObserver*
|
||||
SVGObserverUtils::GetMarkerProperty(URLAndReferrerInfo* aURI, nsIFrame* aFrame,
|
||||
const mozilla::FramePropertyDescriptor<SVGMarkerObserver>* aProperty)
|
||||
bool
|
||||
SVGObserverUtils::GetMarkerFrames(nsIFrame* aMarkedFrame,
|
||||
nsSVGMarkerFrame*(*aFrames)[3])
|
||||
{
|
||||
MOZ_ASSERT(aFrame->IsSVGGeometryFrame() &&
|
||||
static_cast<SVGGeometryElement*>(aFrame->GetContent())->IsMarkable(),
|
||||
MOZ_ASSERT(!aMarkedFrame->GetPrevContinuation() &&
|
||||
aMarkedFrame->IsSVGGeometryFrame() &&
|
||||
static_cast<SVGGeometryElement*>(aMarkedFrame->GetContent())->IsMarkable(),
|
||||
"Bad frame");
|
||||
return GetEffectProperty(aURI, aFrame, aProperty);
|
||||
|
||||
bool foundMarker = false;
|
||||
RefPtr<URLAndReferrerInfo> markerURL;
|
||||
SVGMarkerObserver* observer;
|
||||
nsIFrame* marker;
|
||||
|
||||
#define GET_MARKER(type) \
|
||||
markerURL = GetMarkerURI(aMarkedFrame, &nsStyleSVG::mMarker##type); \
|
||||
observer = GetEffectProperty(markerURL, aMarkedFrame, \
|
||||
SVGObserverUtils::Marker##type##Property()); \
|
||||
marker = observer ? \
|
||||
observer->GetReferencedFrame(LayoutFrameType::SVGMarker, nullptr) :\
|
||||
nullptr; \
|
||||
foundMarker = foundMarker || bool(marker); \
|
||||
(*aFrames)[nsSVGMark::e##type] = static_cast<nsSVGMarkerFrame*>(marker);
|
||||
|
||||
GET_MARKER(Start)
|
||||
GET_MARKER(Mid)
|
||||
GET_MARKER(End)
|
||||
|
||||
#undef GET_MARKER
|
||||
|
||||
return foundMarker;
|
||||
}
|
||||
|
||||
SVGGeometryElement*
|
||||
|
@ -833,11 +856,11 @@ SVGObserverUtils::UpdateEffects(nsIFrame* aFrame)
|
|||
// Set marker properties here to avoid reference loops
|
||||
RefPtr<URLAndReferrerInfo> markerURL =
|
||||
GetMarkerURI(aFrame, &nsStyleSVG::mMarkerStart);
|
||||
GetMarkerProperty(markerURL, aFrame, MarkerStartProperty());
|
||||
GetEffectProperty(markerURL, aFrame, MarkerStartProperty());
|
||||
markerURL = GetMarkerURI(aFrame, &nsStyleSVG::mMarkerMid);
|
||||
GetMarkerProperty(markerURL, aFrame, MarkerMidProperty());
|
||||
GetEffectProperty(markerURL, aFrame, MarkerMidProperty());
|
||||
markerURL = GetMarkerURI(aFrame, &nsStyleSVG::mMarkerEnd);
|
||||
GetMarkerProperty(markerURL, aFrame, MarkerEndProperty());
|
||||
GetEffectProperty(markerURL, aFrame, MarkerEndProperty());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@ class nsAtom;
|
|||
class nsIPresShell;
|
||||
class nsIURI;
|
||||
class nsSVGClipPathFrame;
|
||||
class nsSVGMarkerFrame;
|
||||
class nsSVGPaintServerFrame;
|
||||
class nsSVGFilterFrame;
|
||||
class nsSVGMaskFrame;
|
||||
|
@ -688,11 +689,12 @@ public:
|
|||
nsStyleSVGPaint nsStyleSVG::* aPaint);
|
||||
|
||||
/**
|
||||
* Get an SVGMarkerObserver for the frame, creating a fresh one if necessary
|
||||
* Get the start/mid/end-markers for the given frame, and add the frame as
|
||||
* an observer to those markers. Returns true if at least one marker type is
|
||||
* found, false otherwise.
|
||||
*/
|
||||
static SVGMarkerObserver *
|
||||
GetMarkerProperty(URLAndReferrerInfo* aURI, nsIFrame* aFrame,
|
||||
const mozilla::FramePropertyDescriptor<SVGMarkerObserver>* aProperty);
|
||||
static bool
|
||||
GetMarkerFrames(nsIFrame* aMarkedFrame, nsSVGMarkerFrame*(*aFrames)[3]);
|
||||
|
||||
/**
|
||||
* Get the SVGGeometryElement that is referenced by aTextPathFrame, and make
|
||||
|
|
Загрузка…
Ссылка в новой задаче