forked from mirrors/gecko-dev
		
	 e3ebda1914
			
		
	
	
		e3ebda1914
		
	
	
	
	
		
			
			CLOSED TREE
We don't need these macros anymore, for two reasons:
1. We have static analysis to provide the same sort of checks via `MOZ_RAII`
   and friends.
2. clang now warns for the "temporary that should have been a declaration" case.
The extra requirements on class construction also show up during debug tests
as performance problems.
This change was automated by using the following sed script:
```
# Remove declarations in classes.
/MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER/d
/MOZ_GUARD_OBJECT_NOTIFIER_INIT/d
# Remove individual macros, carefully.
{
  # We don't have to worry about substrings here because the closing
  # parenthesis "anchors" the match.
  s/MOZ_GUARD_OBJECT_NOTIFIER_PARAM)/)/g;
  s/MOZ_GUARD_OBJECT_NOTIFIER_PARAM_TO_PARENT)/)/g;
  s/MOZ_GUARD_OBJECT_NOTIFIER_PARAM_IN_IMPL)/)/g;
  s/MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM_IN_IMPL)/)/g;
  # Remove the longer identifier first.
  s/MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM_TO_PARENT//g;
  s/MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM//g;
}
# Remove the actual include.
\@# *include "mozilla/GuardObjects.h"@d
```
and running:
```
find . -name \*.cpp -o -name \*.h | grep -v 'GuardObjects.h' |xargs sed -i -f script 2>/dev/null
mach clang-format
```
Differential Revision: https://phabricator.services.mozilla.com/D85168
		
	
			
		
			
				
	
	
		
			240 lines
		
	
	
	
		
			8.1 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			240 lines
		
	
	
	
		
			8.1 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 | |
| /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 | |
| /* 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/. */
 | |
| 
 | |
| // Main header first:
 | |
| #include "SVGMarkerFrame.h"
 | |
| 
 | |
| // Keep others in (case-insensitive) order:
 | |
| #include "gfxContext.h"
 | |
| #include "mozilla/PresShell.h"
 | |
| #include "mozilla/SVGGeometryFrame.h"
 | |
| #include "mozilla/SVGObserverUtils.h"
 | |
| #include "mozilla/SVGUtils.h"
 | |
| #include "mozilla/dom/SVGGeometryElement.h"
 | |
| #include "mozilla/dom/SVGMarkerElement.h"
 | |
| 
 | |
| using namespace mozilla::dom;
 | |
| using namespace mozilla::gfx;
 | |
| using namespace mozilla::image;
 | |
| 
 | |
| nsContainerFrame* NS_NewSVGMarkerFrame(mozilla::PresShell* aPresShell,
 | |
|                                        mozilla::ComputedStyle* aStyle) {
 | |
|   return new (aPresShell)
 | |
|       mozilla::SVGMarkerFrame(aStyle, aPresShell->GetPresContext());
 | |
| }
 | |
| 
 | |
| namespace mozilla {
 | |
| 
 | |
| NS_IMPL_FRAMEARENA_HELPERS(SVGMarkerFrame)
 | |
| 
 | |
| //----------------------------------------------------------------------
 | |
| // nsIFrame methods:
 | |
| 
 | |
| nsresult SVGMarkerFrame::AttributeChanged(int32_t aNameSpaceID,
 | |
|                                           nsAtom* aAttribute,
 | |
|                                           int32_t aModType) {
 | |
|   if (aNameSpaceID == kNameSpaceID_None &&
 | |
|       (aAttribute == nsGkAtoms::markerUnits || aAttribute == nsGkAtoms::refX ||
 | |
|        aAttribute == nsGkAtoms::refY || aAttribute == nsGkAtoms::markerWidth ||
 | |
|        aAttribute == nsGkAtoms::markerHeight ||
 | |
|        aAttribute == nsGkAtoms::orient ||
 | |
|        aAttribute == nsGkAtoms::preserveAspectRatio ||
 | |
|        aAttribute == nsGkAtoms::viewBox)) {
 | |
|     SVGObserverUtils::InvalidateDirectRenderingObservers(this);
 | |
|   }
 | |
| 
 | |
|   return SVGContainerFrame::AttributeChanged(aNameSpaceID, aAttribute,
 | |
|                                              aModType);
 | |
| }
 | |
| 
 | |
| #ifdef DEBUG
 | |
| void SVGMarkerFrame::Init(nsIContent* aContent, nsContainerFrame* aParent,
 | |
|                           nsIFrame* aPrevInFlow) {
 | |
|   NS_ASSERTION(aContent->IsSVGElement(nsGkAtoms::marker),
 | |
|                "Content is not an SVG marker");
 | |
| 
 | |
|   SVGContainerFrame::Init(aContent, aParent, aPrevInFlow);
 | |
| }
 | |
| #endif /* DEBUG */
 | |
| 
 | |
| //----------------------------------------------------------------------
 | |
| // SVGContainerFrame methods:
 | |
| 
 | |
| gfxMatrix SVGMarkerFrame::GetCanvasTM() {
 | |
|   NS_ASSERTION(mMarkedFrame, "null SVGGeometry frame");
 | |
| 
 | |
|   if (mInUse2) {
 | |
|     // We're going to be bailing drawing the marker, so return an identity.
 | |
|     return gfxMatrix();
 | |
|   }
 | |
| 
 | |
|   SVGMarkerElement* content = static_cast<SVGMarkerElement*>(GetContent());
 | |
| 
 | |
|   mInUse2 = true;
 | |
|   gfxMatrix markedTM = mMarkedFrame->GetCanvasTM();
 | |
|   mInUse2 = false;
 | |
| 
 | |
|   Matrix viewBoxTM = content->GetViewBoxTransform();
 | |
| 
 | |
|   return ThebesMatrix(viewBoxTM * mMarkerTM) * markedTM;
 | |
| }
 | |
| 
 | |
| static nsIFrame* GetAnonymousChildFrame(nsIFrame* aFrame) {
 | |
|   nsIFrame* kid = aFrame->PrincipalChildList().FirstChild();
 | |
|   MOZ_ASSERT(kid && kid->IsSVGMarkerAnonChildFrame(),
 | |
|              "expected to find anonymous child of marker frame");
 | |
|   return kid;
 | |
| }
 | |
| 
 | |
| void SVGMarkerFrame::PaintMark(gfxContext& aContext,
 | |
|                                const gfxMatrix& aToMarkedFrameUserSpace,
 | |
|                                SVGGeometryFrame* aMarkedFrame,
 | |
|                                const SVGMark& aMark, float aStrokeWidth,
 | |
|                                imgDrawingParams& aImgParams) {
 | |
|   // If the flag is set when we get here, it means this marker frame
 | |
|   // has already been used painting the current mark, and the document
 | |
|   // has a marker reference loop.
 | |
|   if (mInUse) {
 | |
|     return;
 | |
|   }
 | |
| 
 | |
|   AutoMarkerReferencer markerRef(this, aMarkedFrame);
 | |
| 
 | |
|   SVGMarkerElement* marker = static_cast<SVGMarkerElement*>(GetContent());
 | |
|   if (!marker->HasValidDimensions()) {
 | |
|     return;
 | |
|   }
 | |
| 
 | |
|   const SVGViewBox viewBox = marker->GetViewBox();
 | |
| 
 | |
|   if (viewBox.width <= 0.0f || viewBox.height <= 0.0f) {
 | |
|     // We must disable rendering if the viewBox width or height are zero.
 | |
|     return;
 | |
|   }
 | |
| 
 | |
|   Matrix viewBoxTM = marker->GetViewBoxTransform();
 | |
| 
 | |
|   mMarkerTM = marker->GetMarkerTransform(aStrokeWidth, aMark);
 | |
| 
 | |
|   gfxMatrix markTM = ThebesMatrix(viewBoxTM) * ThebesMatrix(mMarkerTM) *
 | |
|                      aToMarkedFrameUserSpace;
 | |
| 
 | |
|   if (StyleDisplay()->IsScrollableOverflow()) {
 | |
|     aContext.Save();
 | |
|     gfxRect clipRect = SVGUtils::GetClipRectForFrame(
 | |
|         this, viewBox.x, viewBox.y, viewBox.width, viewBox.height);
 | |
|     SVGUtils::SetClipRect(&aContext, markTM, clipRect);
 | |
|   }
 | |
| 
 | |
|   nsIFrame* kid = GetAnonymousChildFrame(this);
 | |
|   ISVGDisplayableFrame* SVGFrame = do_QueryFrame(kid);
 | |
|   // The CTM of each frame referencing us may be different.
 | |
|   SVGFrame->NotifySVGChanged(ISVGDisplayableFrame::TRANSFORM_CHANGED);
 | |
|   SVGUtils::PaintFrameWithEffects(kid, aContext, markTM, aImgParams);
 | |
| 
 | |
|   if (StyleDisplay()->IsScrollableOverflow()) aContext.Restore();
 | |
| }
 | |
| 
 | |
| SVGBBox SVGMarkerFrame::GetMarkBBoxContribution(const Matrix& aToBBoxUserspace,
 | |
|                                                 uint32_t aFlags,
 | |
|                                                 SVGGeometryFrame* aMarkedFrame,
 | |
|                                                 const SVGMark& aMark,
 | |
|                                                 float aStrokeWidth) {
 | |
|   SVGBBox bbox;
 | |
| 
 | |
|   // If the flag is set when we get here, it means this marker frame
 | |
|   // has already been used in calculating the current mark bbox, and
 | |
|   // the document has a marker reference loop.
 | |
|   if (mInUse) {
 | |
|     return bbox;
 | |
|   }
 | |
| 
 | |
|   AutoMarkerReferencer markerRef(this, aMarkedFrame);
 | |
| 
 | |
|   SVGMarkerElement* content = static_cast<SVGMarkerElement*>(GetContent());
 | |
|   if (!content->HasValidDimensions()) {
 | |
|     return bbox;
 | |
|   }
 | |
| 
 | |
|   const SVGViewBox viewBox = content->GetViewBox();
 | |
| 
 | |
|   if (viewBox.width <= 0.0f || viewBox.height <= 0.0f) {
 | |
|     return bbox;
 | |
|   }
 | |
| 
 | |
|   mMarkerTM = content->GetMarkerTransform(aStrokeWidth, aMark);
 | |
|   Matrix viewBoxTM = content->GetViewBoxTransform();
 | |
| 
 | |
|   Matrix tm = viewBoxTM * mMarkerTM * aToBBoxUserspace;
 | |
| 
 | |
|   ISVGDisplayableFrame* child = do_QueryFrame(GetAnonymousChildFrame(this));
 | |
|   // When we're being called to obtain the invalidation area, we need to
 | |
|   // pass down all the flags so that stroke is included. However, once DOM
 | |
|   // getBBox() accepts flags, maybe we should strip some of those here?
 | |
| 
 | |
|   // We need to include zero width/height vertical/horizontal lines, so we have
 | |
|   // to use UnionEdges.
 | |
|   bbox.UnionEdges(child->GetBBoxContribution(tm, aFlags));
 | |
| 
 | |
|   return bbox;
 | |
| }
 | |
| 
 | |
| void SVGMarkerFrame::SetParentCoordCtxProvider(SVGViewportElement* aContext) {
 | |
|   SVGMarkerElement* marker = static_cast<SVGMarkerElement*>(GetContent());
 | |
|   marker->SetParentCoordCtxProvider(aContext);
 | |
| }
 | |
| 
 | |
| void SVGMarkerFrame::AppendDirectlyOwnedAnonBoxes(
 | |
|     nsTArray<OwnedAnonBox>& aResult) {
 | |
|   aResult.AppendElement(OwnedAnonBox(GetAnonymousChildFrame(this)));
 | |
| }
 | |
| 
 | |
| //----------------------------------------------------------------------
 | |
| // helper class
 | |
| 
 | |
| SVGMarkerFrame::AutoMarkerReferencer::AutoMarkerReferencer(
 | |
|     SVGMarkerFrame* aFrame, SVGGeometryFrame* aMarkedFrame)
 | |
|     : mFrame(aFrame) {
 | |
|   mFrame->mInUse = true;
 | |
|   mFrame->mMarkedFrame = aMarkedFrame;
 | |
| 
 | |
|   SVGViewportElement* ctx =
 | |
|       static_cast<SVGElement*>(aMarkedFrame->GetContent())->GetCtx();
 | |
|   mFrame->SetParentCoordCtxProvider(ctx);
 | |
| }
 | |
| 
 | |
| SVGMarkerFrame::AutoMarkerReferencer::~AutoMarkerReferencer() {
 | |
|   mFrame->SetParentCoordCtxProvider(nullptr);
 | |
| 
 | |
|   mFrame->mMarkedFrame = nullptr;
 | |
|   mFrame->mInUse = false;
 | |
| }
 | |
| 
 | |
| }  // namespace mozilla
 | |
| 
 | |
| //----------------------------------------------------------------------
 | |
| // Implementation of SVGMarkerAnonChildFrame
 | |
| 
 | |
| nsContainerFrame* NS_NewSVGMarkerAnonChildFrame(
 | |
|     mozilla::PresShell* aPresShell, mozilla::ComputedStyle* aStyle) {
 | |
|   return new (aPresShell)
 | |
|       mozilla::SVGMarkerAnonChildFrame(aStyle, aPresShell->GetPresContext());
 | |
| }
 | |
| 
 | |
| namespace mozilla {
 | |
| 
 | |
| NS_IMPL_FRAMEARENA_HELPERS(SVGMarkerAnonChildFrame)
 | |
| 
 | |
| #ifdef DEBUG
 | |
| void SVGMarkerAnonChildFrame::Init(nsIContent* aContent,
 | |
|                                    nsContainerFrame* aParent,
 | |
|                                    nsIFrame* aPrevInFlow) {
 | |
|   MOZ_ASSERT(aParent->IsSVGMarkerFrame(), "Unexpected parent");
 | |
|   SVGDisplayContainerFrame::Init(aContent, aParent, aPrevInFlow);
 | |
| }
 | |
| #endif
 | |
| 
 | |
| }  // namespace mozilla
 |