1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 /* rendering object that goes directly inside the document's scrollbars */ 8 9 #ifndef nsCanvasFrame_h___ 10 #define nsCanvasFrame_h___ 11 12 #include "mozilla/Attributes.h" 13 #include "mozilla/EventForwards.h" 14 #include "nsContainerFrame.h" 15 #include "nsIScrollPositionListener.h" 16 #include "nsDisplayList.h" 17 #include "nsIAnonymousContentCreator.h" 18 #include "gfxPrefs.h" 19 20 class nsPresContext; 21 class gfxContext; 22 23 /** 24 * Root frame class. 25 * 26 * The root frame is the parent frame for the document element's frame. 27 * It only supports having a single child frame which must be an area 28 * frame. 29 * @note nsCanvasFrame keeps overflow container continuations of its child 30 * frame in the main child list. 31 */ 32 class nsCanvasFrame final : public nsContainerFrame, 33 public nsIScrollPositionListener, 34 public nsIAnonymousContentCreator { 35 public: nsCanvasFrame(nsStyleContext * aContext)36 explicit nsCanvasFrame(nsStyleContext* aContext) 37 : nsContainerFrame(aContext, kClassID), 38 mDoPaintFocus(false), 39 mAddedScrollPositionListener(false) {} 40 41 NS_DECL_QUERYFRAME 42 NS_DECL_FRAMEARENA_HELPERS(nsCanvasFrame) 43 44 virtual void DestroyFrom(nsIFrame* aDestructRoot, 45 PostDestroyData& aPostDestroyData) override; 46 47 virtual void SetInitialChildList(ChildListID aListID, 48 nsFrameList& aChildList) override; 49 virtual void AppendFrames(ChildListID aListID, 50 nsFrameList& aFrameList) override; 51 virtual void InsertFrames(ChildListID aListID, nsIFrame* aPrevFrame, 52 nsFrameList& aFrameList) override; 53 #ifdef DEBUG 54 virtual void RemoveFrame(ChildListID aListID, nsIFrame* aOldFrame) override; 55 #endif 56 57 virtual nscoord GetMinISize(gfxContext* aRenderingContext) override; 58 virtual nscoord GetPrefISize(gfxContext* aRenderingContext) override; 59 virtual void Reflow(nsPresContext* aPresContext, ReflowOutput& aDesiredSize, 60 const ReflowInput& aReflowInput, 61 nsReflowStatus& aStatus) override; IsFrameOfType(uint32_t aFlags)62 virtual bool IsFrameOfType(uint32_t aFlags) const override { 63 return nsContainerFrame::IsFrameOfType( 64 aFlags & ~(nsIFrame::eCanContainOverflowContainers)); 65 } 66 67 // nsIAnonymousContentCreator 68 virtual nsresult CreateAnonymousContent( 69 nsTArray<ContentInfo>& aElements) override; 70 virtual void AppendAnonymousContentTo(nsTArray<nsIContent*>& aElements, 71 uint32_t aFilter) override; 72 GetCustomContentContainer()73 mozilla::dom::Element* GetCustomContentContainer() const { 74 return mCustomContentContainer; 75 } 76 77 /** 78 * Unhide the CustomContentContainer. This call only has an effect if 79 * mCustomContentContainer is non-null. 80 */ 81 void ShowCustomContentContainer(); 82 83 /** 84 * Hide the CustomContentContainer. This call only has an effect if 85 * mCustomContentContainer is non-null. 86 */ 87 void HideCustomContentContainer(); 88 89 /** SetHasFocus tells the CanvasFrame to draw with focus ring 90 * @param aHasFocus true to show focus ring, false to hide it 91 */ 92 NS_IMETHOD SetHasFocus(bool aHasFocus); 93 94 virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, 95 const nsDisplayListSet& aLists) override; 96 97 void PaintFocus(mozilla::gfx::DrawTarget* aRenderingContext, nsPoint aPt); 98 99 // nsIScrollPositionListener 100 virtual void ScrollPositionWillChange(nscoord aX, nscoord aY) override; ScrollPositionDidChange(nscoord aX,nscoord aY)101 virtual void ScrollPositionDidChange(nscoord aX, nscoord aY) override {} 102 103 #ifdef DEBUG_FRAME_DUMP 104 virtual nsresult GetFrameName(nsAString& aResult) const override; 105 #endif 106 virtual nsresult GetContentForEvent(mozilla::WidgetEvent* aEvent, 107 nsIContent** aContent) override; 108 109 nsRect CanvasArea() const; 110 111 protected: 112 // Utility function to propagate the WritingMode from our first child to 113 // 'this' and all its ancestors. 114 void MaybePropagateRootElementWritingMode(); 115 116 // Data members 117 bool mDoPaintFocus; 118 bool mAddedScrollPositionListener; 119 120 nsCOMPtr<mozilla::dom::Element> mCustomContentContainer; 121 }; 122 123 /** 124 * Override nsDisplayBackground methods so that we pass aBGClipRect to 125 * PaintBackground, covering the whole overflow area. 126 * We can also paint an "extra background color" behind the normal 127 * background. 128 */ 129 class nsDisplayCanvasBackgroundColor : public nsDisplaySolidColorBase { 130 public: nsDisplayCanvasBackgroundColor(nsDisplayListBuilder * aBuilder,nsIFrame * aFrame)131 nsDisplayCanvasBackgroundColor(nsDisplayListBuilder* aBuilder, 132 nsIFrame* aFrame) 133 : nsDisplaySolidColorBase(aBuilder, aFrame, NS_RGBA(0, 0, 0, 0)) {} 134 ComputeVisibility(nsDisplayListBuilder * aBuilder,nsRegion * aVisibleRegion)135 virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder, 136 nsRegion* aVisibleRegion) override { 137 return NS_GET_A(mColor) > 0; 138 } GetBounds(nsDisplayListBuilder * aBuilder,bool * aSnap)139 virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, 140 bool* aSnap) const override { 141 nsCanvasFrame* frame = static_cast<nsCanvasFrame*>(mFrame); 142 *aSnap = true; 143 return frame->CanvasArea() + ToReferenceFrame(); 144 } HitTest(nsDisplayListBuilder * aBuilder,const nsRect & aRect,HitTestState * aState,nsTArray<nsIFrame * > * aOutFrames)145 virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect, 146 HitTestState* aState, 147 nsTArray<nsIFrame*>* aOutFrames) override { 148 // We need to override so we don't consider border-radius. 149 aOutFrames->AppendElement(mFrame); 150 } 151 virtual already_AddRefed<Layer> BuildLayer( 152 nsDisplayListBuilder* aBuilder, LayerManager* aManager, 153 const ContainerLayerParameters& aContainerParameters) override; 154 virtual bool CreateWebRenderCommands( 155 mozilla::wr::DisplayListBuilder& aBuilder, 156 mozilla::wr::IpcResourceUpdateQueue& aResources, 157 const StackingContextHelper& aSc, 158 mozilla::layers::WebRenderLayerManager* aManager, 159 nsDisplayListBuilder* aDisplayListBuilder) override; GetLayerState(nsDisplayListBuilder * aBuilder,LayerManager * aManager,const ContainerLayerParameters & aParameters)160 virtual LayerState GetLayerState( 161 nsDisplayListBuilder* aBuilder, LayerManager* aManager, 162 const ContainerLayerParameters& aParameters) override { 163 if (ShouldUseAdvancedLayer( 164 aManager, gfxPrefs::LayersAllowCanvasBackgroundColorLayers) || 165 ForceActiveLayers()) { 166 return mozilla::LAYER_ACTIVE; 167 } 168 return mozilla::LAYER_NONE; 169 } 170 virtual void Paint(nsDisplayListBuilder* aBuilder, gfxContext* aCtx) override; 171 SetExtraBackgroundColor(nscolor aColor)172 void SetExtraBackgroundColor(nscolor aColor) { mColor = aColor; } 173 174 NS_DISPLAY_DECL_NAME("CanvasBackgroundColor", TYPE_CANVAS_BACKGROUND_COLOR) 175 #ifdef MOZ_DUMP_PAINTING 176 virtual void WriteDebugInfo(std::stringstream& aStream) override; 177 #endif 178 }; 179 180 class nsDisplayCanvasBackgroundImage : public nsDisplayBackgroundImage { 181 public: nsDisplayCanvasBackgroundImage(nsDisplayListBuilder * aBuilder,const InitData & aInitData)182 explicit nsDisplayCanvasBackgroundImage(nsDisplayListBuilder* aBuilder, 183 const InitData& aInitData) 184 : nsDisplayBackgroundImage(aBuilder, aInitData) {} 185 186 virtual void Paint(nsDisplayListBuilder* aBuilder, gfxContext* aCtx) override; 187 188 // We still need to paint a background color as well as an image for this 189 // item, so we can't support this yet. SupportsOptimizingToImage()190 virtual bool SupportsOptimizingToImage() const override { return false; } 191 192 bool IsSingleFixedPositionImage(nsDisplayListBuilder* aBuilder, 193 const nsRect& aClipRect, gfxRect* aDestRect); 194 195 NS_DISPLAY_DECL_NAME("CanvasBackgroundImage", TYPE_CANVAS_BACKGROUND_IMAGE) 196 }; 197 198 class nsDisplayCanvasThemedBackground : public nsDisplayThemedBackground { 199 public: nsDisplayCanvasThemedBackground(nsDisplayListBuilder * aBuilder,nsIFrame * aFrame)200 nsDisplayCanvasThemedBackground(nsDisplayListBuilder* aBuilder, 201 nsIFrame* aFrame) 202 : nsDisplayThemedBackground(aBuilder, aFrame, 203 aFrame->GetRectRelativeToSelf() + 204 aBuilder->ToReferenceFrame(aFrame)) {} 205 206 virtual void Paint(nsDisplayListBuilder* aBuilder, gfxContext* aCtx) override; 207 208 NS_DISPLAY_DECL_NAME("CanvasThemedBackground", TYPE_CANVAS_THEMED_BACKGROUND) 209 }; 210 211 #endif /* nsCanvasFrame_h___ */ 212