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 #ifndef nsImageBoxFrame_h___ 7 #define nsImageBoxFrame_h___ 8 9 #include "mozilla/Attributes.h" 10 #include "nsLeafBoxFrame.h" 11 12 #include "imgIRequest.h" 13 #include "imgIContainer.h" 14 #include "imgINotificationObserver.h" 15 16 class imgRequestProxy; 17 class nsImageBoxFrame; 18 19 class nsDisplayXULImage; 20 21 namespace mozilla { 22 class PresShell; 23 } // namespace mozilla 24 25 class nsImageBoxListener final : public imgINotificationObserver { 26 public: 27 explicit nsImageBoxListener(nsImageBoxFrame* frame); 28 29 NS_DECL_ISUPPORTS 30 NS_DECL_IMGINOTIFICATIONOBSERVER 31 ClearFrame()32 void ClearFrame() { mFrame = nullptr; } 33 34 private: 35 virtual ~nsImageBoxListener(); 36 37 nsImageBoxFrame* mFrame; 38 }; 39 40 class nsImageBoxFrame final : public nsLeafBoxFrame { 41 public: 42 typedef mozilla::image::ImgDrawResult ImgDrawResult; 43 typedef mozilla::layers::ImageContainer ImageContainer; 44 typedef mozilla::layers::LayerManager LayerManager; 45 46 friend class nsDisplayXULImage; 47 NS_DECL_FRAMEARENA_HELPERS(nsImageBoxFrame) 48 NS_DECL_QUERYFRAME 49 50 virtual nsSize GetXULPrefSize(nsBoxLayoutState& aBoxLayoutState) override; 51 virtual nsSize GetXULMinSize(nsBoxLayoutState& aBoxLayoutState) override; 52 virtual nscoord GetXULBoxAscent(nsBoxLayoutState& aBoxLayoutState) override; 53 virtual void MarkIntrinsicISizesDirty() override; 54 55 void Notify(imgIRequest* aRequest, int32_t aType, const nsIntRect* aData); 56 57 friend nsIFrame* NS_NewImageBoxFrame(mozilla::PresShell* aPresShell, 58 ComputedStyle* aStyle); 59 60 virtual void Init(nsIContent* aContent, nsContainerFrame* aParent, 61 nsIFrame* asPrevInFlow) override; 62 63 virtual nsresult AttributeChanged(int32_t aNameSpaceID, nsAtom* aAttribute, 64 int32_t aModType) override; 65 66 virtual void DidSetComputedStyle(ComputedStyle* aOldStyle) override; 67 68 virtual void DestroyFrom(nsIFrame* aDestructRoot, 69 PostDestroyData& aPostDestroyData) override; 70 71 #ifdef DEBUG_FRAME_DUMP 72 virtual nsresult GetFrameName(nsAString& aResult) const override; 73 #endif 74 75 /** 76 * Gets the image to be loaded from the current style. May be null if themed, 77 * or if not an url image. 78 * 79 * TODO(emilio): Maybe support list-style-image: linear-gradient() etc? 80 */ 81 const mozilla::StyleImage* GetImageFromStyle(const ComputedStyle&) const; GetImageFromStyle()82 const mozilla::StyleImage* GetImageFromStyle() const { 83 return GetImageFromStyle(*Style()); 84 } 85 86 mozilla::ImageResolution GetImageResolution() const; 87 88 /** 89 * Update mUseSrcAttr from appropriate content attributes or from 90 * style, throw away the current image, and load the appropriate 91 * image. 92 * */ 93 void UpdateImage(); 94 95 /** 96 * Update mLoadFlags from content attributes. Does not attempt to reload the 97 * image using the new load flags. 98 */ 99 void UpdateLoadFlags(); 100 101 void RestartAnimation(); 102 void StopAnimation(); 103 104 virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, 105 const nsDisplayListSet& aLists) override; 106 107 virtual ~nsImageBoxFrame(); 108 109 already_AddRefed<imgIContainer> GetImageContainerForPainting( 110 const nsPoint& aPt, ImgDrawResult& aDrawResult, 111 Maybe<nsPoint>& aAnchorPoint, nsRect& aDest); 112 113 ImgDrawResult PaintImage(gfxContext& aRenderingContext, 114 const nsRect& aDirtyRect, nsPoint aPt, 115 uint32_t aFlags); 116 117 ImgDrawResult CreateWebRenderCommands( 118 mozilla::wr::DisplayListBuilder& aBuilder, 119 mozilla::wr::IpcResourceUpdateQueue& aResources, 120 const mozilla::layers::StackingContextHelper& aSc, 121 mozilla::layers::RenderRootStateManager* aManager, nsDisplayItem* aItem, 122 nsPoint aPt, uint32_t aFlags); 123 124 bool CanOptimizeToImageLayer(); 125 126 nsRect GetDestRect(const nsPoint& aOffset, Maybe<nsPoint>& aAnchorPoint); 127 128 protected: 129 explicit nsImageBoxFrame(ComputedStyle* aStyle, nsPresContext* aPresContext); 130 131 virtual void GetImageSize(); 132 133 private: 134 void OnSizeAvailable(imgIRequest* aRequest, imgIContainer* aImage); 135 void OnDecodeComplete(imgIRequest* aRequest); 136 void OnLoadComplete(imgIRequest* aRequest, nsresult aStatus); 137 void OnImageIsAnimated(imgIRequest* aRequest); 138 void OnFrameUpdate(imgIRequest* aRequest); 139 140 nsRect mSubRect; ///< If set, indicates that only the portion of the image 141 ///< specified by the rect should be used. 142 nsSize mIntrinsicSize; 143 nsSize mImageSize; 144 145 RefPtr<imgRequestProxy> mImageRequest; 146 nsCOMPtr<imgINotificationObserver> mListener; 147 148 int32_t mLoadFlags; 149 150 // Boolean variable to determine if the current image request has been 151 // registered with the refresh driver. 152 bool mRequestRegistered; 153 154 bool mUseSrcAttr; ///< Whether or not the image src comes from an attribute. 155 bool mSuppressStyleCheck; 156 }; // class nsImageBoxFrame 157 158 class nsDisplayXULImage final : public nsDisplayImageContainer { 159 public: nsDisplayXULImage(nsDisplayListBuilder * aBuilder,nsImageBoxFrame * aFrame)160 nsDisplayXULImage(nsDisplayListBuilder* aBuilder, nsImageBoxFrame* aFrame) 161 : nsDisplayImageContainer(aBuilder, aFrame) { 162 MOZ_COUNT_CTOR(nsDisplayXULImage); 163 } 164 MOZ_COUNTED_DTOR_OVERRIDE(nsDisplayXULImage) 165 166 virtual bool CanOptimizeToImageLayer(LayerManager* aManager, 167 nsDisplayListBuilder* aBuilder) override; 168 virtual already_AddRefed<imgIContainer> GetImage() override; 169 virtual nsRect GetDestRect() const override; UpdateDrawResult(mozilla::image::ImgDrawResult aResult)170 virtual void UpdateDrawResult( 171 mozilla::image::ImgDrawResult aResult) override { 172 nsDisplayItemGenericImageGeometry::UpdateDrawResult(this, aResult); 173 } GetBounds(nsDisplayListBuilder * aBuilder,bool * aSnap)174 virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, 175 bool* aSnap) const override { 176 *aSnap = true; 177 return nsRect(ToReferenceFrame(), Frame()->GetSize()); 178 } 179 virtual nsDisplayItemGeometry* AllocateGeometry( 180 nsDisplayListBuilder* aBuilder) override; 181 virtual void ComputeInvalidationRegion( 182 nsDisplayListBuilder* aBuilder, const nsDisplayItemGeometry* aGeometry, 183 nsRegion* aInvalidRegion) const override; 184 // Doesn't handle HitTest because nsLeafBoxFrame already creates an 185 // event receiver for us 186 virtual void Paint(nsDisplayListBuilder* aBuilder, gfxContext* aCtx) override; 187 188 virtual bool CreateWebRenderCommands( 189 mozilla::wr::DisplayListBuilder& aBuilder, 190 mozilla::wr::IpcResourceUpdateQueue& aResources, 191 const StackingContextHelper& aSc, 192 mozilla::layers::RenderRootStateManager* aManager, 193 nsDisplayListBuilder* aDisplayListBuilder) override; 194 195 NS_DISPLAY_DECL_NAME("XULImage", TYPE_XUL_IMAGE) 196 }; 197 198 #endif /* nsImageBoxFrame_h___ */ 199