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:
Jonathan Watt 2018-08-16 18:08:21 +01:00
Родитель b03fed78da
Коммит 7f62854eb1
4 изменённых файлов: 63 добавлений и 130 удалений

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

@ -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