LCOV - code coverage report
Current view: top level - layout/generic - nsImageFrame.h (source / functions) Hit Total Coverage
Test: output.info Lines: 0 42 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 19 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* This Source Code Form is subject to the terms of the Mozilla Public
       3             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       4             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       5             : 
       6             : /* rendering object for replaced elements with image data */
       7             : 
       8             : #ifndef nsImageFrame_h___
       9             : #define nsImageFrame_h___
      10             : 
      11             : #include "nsAtomicContainerFrame.h"
      12             : #include "nsIIOService.h"
      13             : #include "nsIObserver.h"
      14             : 
      15             : #include "imgINotificationObserver.h"
      16             : 
      17             : #include "nsDisplayList.h"
      18             : #include "imgIContainer.h"
      19             : #include "mozilla/Attributes.h"
      20             : #include "mozilla/DebugOnly.h"
      21             : #include "nsIReflowCallback.h"
      22             : #include "nsTObserverArray.h"
      23             : 
      24             : class nsFontMetrics;
      25             : class nsImageMap;
      26             : class nsIURI;
      27             : class nsILoadGroup;
      28             : class nsDisplayImage;
      29             : class nsPresContext;
      30             : class nsImageFrame;
      31             : class nsTransform2D;
      32             : class nsImageLoadingContent;
      33             : 
      34             : namespace mozilla {
      35             : class PresShell;
      36             : namespace layers {
      37             :   class ImageContainer;
      38             :   class ImageLayer;
      39             :   class LayerManager;
      40             : } // namespace layers
      41             : } // namespace mozilla
      42             : 
      43             : class nsImageListener : public imgINotificationObserver
      44             : {
      45             : protected:
      46             :   virtual ~nsImageListener();
      47             : 
      48             : public:
      49             :   explicit nsImageListener(nsImageFrame *aFrame);
      50             : 
      51             :   NS_DECL_ISUPPORTS
      52             :   NS_DECL_IMGINOTIFICATIONOBSERVER
      53             : 
      54           0 :   void SetFrame(nsImageFrame *frame) { mFrame = frame; }
      55             : 
      56             : private:
      57             :   nsImageFrame *mFrame;
      58             : };
      59             : 
      60             : class nsImageFrame : public nsAtomicContainerFrame
      61             :                    , public nsIReflowCallback {
      62             : public:
      63             :   template <typename T> using Maybe = mozilla::Maybe<T>;
      64             :   using Nothing = mozilla::Nothing;
      65             :   using Visibility = mozilla::Visibility;
      66             : 
      67             :   typedef mozilla::image::DrawResult DrawResult;
      68             :   typedef mozilla::layers::ImageContainer ImageContainer;
      69             :   typedef mozilla::layers::ImageLayer ImageLayer;
      70             :   typedef mozilla::layers::LayerManager LayerManager;
      71             : 
      72           0 :   NS_DECL_FRAMEARENA_HELPERS(nsImageFrame)
      73             :   NS_DECL_QUERYFRAME
      74             : 
      75             :   virtual void DestroyFrom(nsIFrame* aDestructRoot) override;
      76             :   virtual void DidSetStyleContext(nsStyleContext* aOldStyleContext) override;
      77             : 
      78             :   virtual void Init(nsIContent*       aContent,
      79             :                     nsContainerFrame* aParent,
      80             :                     nsIFrame*         aPrevInFlow) override;
      81             :   virtual void BuildDisplayList(nsDisplayListBuilder*   aBuilder,
      82             :                                 const nsRect&           aDirtyRect,
      83             :                                 const nsDisplayListSet& aLists) override;
      84             :   virtual nscoord GetMinISize(gfxContext *aRenderingContext) override;
      85             :   virtual nscoord GetPrefISize(gfxContext *aRenderingContext) override;
      86             :   virtual mozilla::IntrinsicSize GetIntrinsicSize() override;
      87             :   virtual nsSize GetIntrinsicRatio() override;
      88             :   virtual void Reflow(nsPresContext*           aPresContext,
      89             :                       ReflowOutput&     aDesiredSize,
      90             :                       const ReflowInput& aReflowInput,
      91             :                       nsReflowStatus&          aStatus) override;
      92             : 
      93             :   virtual nsresult  GetContentForEvent(mozilla::WidgetEvent* aEvent,
      94             :                                        nsIContent** aContent) override;
      95             :   virtual nsresult HandleEvent(nsPresContext* aPresContext,
      96             :                                mozilla::WidgetGUIEvent* aEvent,
      97             :                                nsEventStatus* aEventStatus) override;
      98             :   virtual nsresult GetCursor(const nsPoint& aPoint,
      99             :                              nsIFrame::Cursor& aCursor) override;
     100             :   virtual nsresult AttributeChanged(int32_t aNameSpaceID,
     101             :                                     nsIAtom* aAttribute,
     102             :                                     int32_t aModType) override;
     103             : 
     104             :   void OnVisibilityChange(Visibility aNewVisibility,
     105             :                           const Maybe<OnNonvisible>& aNonvisibleAction = Nothing()) override;
     106             : 
     107             : #ifdef ACCESSIBILITY
     108             :   virtual mozilla::a11y::AccType AccessibleType() override;
     109             : #endif
     110             : 
     111           0 :   virtual bool IsFrameOfType(uint32_t aFlags) const override
     112             :   {
     113           0 :     return nsAtomicContainerFrame::IsFrameOfType(aFlags &
     114           0 :       ~(nsIFrame::eReplaced | nsIFrame::eReplacedSizing));
     115             :   }
     116             : 
     117             : #ifdef DEBUG_FRAME_DUMP
     118             :   virtual nsresult GetFrameName(nsAString& aResult) const override;
     119             :   void List(FILE* out = stderr, const char* aPrefix = "",
     120             :             uint32_t aFlags = 0) const override;
     121             : #endif
     122             : 
     123           0 :   nsSplittableType GetSplittableType() const override
     124             :   {
     125           0 :     return NS_FRAME_SPLITTABLE;
     126             :   }
     127             : 
     128             :   virtual LogicalSides GetLogicalSkipSides(const ReflowInput* aReflowInput = nullptr) const override;
     129             : 
     130             :   nsresult GetIntrinsicImageSize(nsSize& aSize);
     131             : 
     132           0 :   static void ReleaseGlobals() {
     133           0 :     if (gIconLoad) {
     134           0 :       gIconLoad->Shutdown();
     135           0 :       NS_RELEASE(gIconLoad);
     136             :     }
     137           0 :     NS_IF_RELEASE(sIOService);
     138           0 :   }
     139             : 
     140             :   nsresult Notify(imgIRequest *aRequest, int32_t aType, const nsIntRect* aData);
     141             : 
     142             :   /**
     143             :    * Function to test whether aContent, which has aStyleContext as its style,
     144             :    * should get an image frame.  Note that this method is only used by the
     145             :    * frame constructor; it's only here because it uses gIconLoad for now.
     146             :    */
     147             :   static bool ShouldCreateImageFrameFor(mozilla::dom::Element* aElement,
     148             :                                           nsStyleContext* aStyleContext);
     149             : 
     150             :   DrawResult DisplayAltFeedback(gfxContext& aRenderingContext,
     151             :                                 const nsRect& aDirtyRect,
     152             :                                 nsPoint aPt,
     153             :                                 uint32_t aFlags);
     154             : 
     155             :   nsRect GetInnerArea() const;
     156             : 
     157             :   /**
     158             :    * Return a map element associated with this image.
     159             :    */
     160             :   mozilla::dom::Element* GetMapElement() const;
     161             : 
     162             :   /**
     163             :    * Return true if the image has associated image map.
     164             :    */
     165           0 :   bool HasImageMap() const { return mImageMap || GetMapElement(); }
     166             : 
     167             :   nsImageMap* GetImageMap();
     168           0 :   nsImageMap* GetExistingImageMap() const { return mImageMap; }
     169             : 
     170             :   virtual void AddInlineMinISize(gfxContext *aRenderingContext,
     171             :                                  InlineMinISizeData *aData) override;
     172             : 
     173             :   void DisconnectMap();
     174             : 
     175             :   // nsIReflowCallback
     176             :   virtual bool ReflowFinished() override;
     177             :   virtual void ReflowCallbackCanceled() override;
     178             : 
     179             : private:
     180             :   friend nsIFrame* NS_NewImageFrame(nsIPresShell*, nsStyleContext*);
     181           0 :   explicit nsImageFrame(nsStyleContext* aContext)
     182           0 :     : nsImageFrame(aContext, kClassID) {}
     183             : 
     184             : protected:
     185             :   nsImageFrame(nsStyleContext* aContext, ClassID aID);
     186             :   virtual ~nsImageFrame();
     187             : 
     188             :   void EnsureIntrinsicSizeAndRatio();
     189             : 
     190             :   virtual mozilla::LogicalSize
     191             :   ComputeSize(gfxContext *aRenderingContext,
     192             :               mozilla::WritingMode aWritingMode,
     193             :               const mozilla::LogicalSize& aCBSize,
     194             :               nscoord aAvailableISize,
     195             :               const mozilla::LogicalSize& aMargin,
     196             :               const mozilla::LogicalSize& aBorder,
     197             :               const mozilla::LogicalSize& aPadding,
     198             :               ComputeSizeFlags aFlags) override;
     199             : 
     200             :   bool IsServerImageMap();
     201             : 
     202             :   void TranslateEventCoords(const nsPoint& aPoint,
     203             :                             nsIntPoint& aResult);
     204             : 
     205             :   bool GetAnchorHREFTargetAndNode(nsIURI** aHref, nsString& aTarget,
     206             :                                     nsIContent** aNode);
     207             :   /**
     208             :    * Computes the width of the string that fits into the available space
     209             :    *
     210             :    * @param in aLength total length of the string in PRUnichars
     211             :    * @param in aMaxWidth width not to be exceeded
     212             :    * @param out aMaxFit length of the string that fits within aMaxWidth
     213             :    *            in PRUnichars
     214             :    * @return width of the string that fits within aMaxWidth
     215             :    */
     216             :   nscoord MeasureString(const char16_t*     aString,
     217             :                         int32_t              aLength,
     218             :                         nscoord              aMaxWidth,
     219             :                         uint32_t&            aMaxFit,
     220             :                         gfxContext&          aContext,
     221             :                         nsFontMetrics&      aFontMetrics);
     222             : 
     223             :   void DisplayAltText(nsPresContext*      aPresContext,
     224             :                       gfxContext&          aRenderingContext,
     225             :                       const nsString&      aAltText,
     226             :                       const nsRect&        aRect);
     227             : 
     228             :   DrawResult PaintImage(gfxContext& aRenderingContext, nsPoint aPt,
     229             :                         const nsRect& aDirtyRect, imgIContainer* aImage,
     230             :                         uint32_t aFlags);
     231             : 
     232             :   /**
     233             :    * If we're ready to decode - that is, if our current request's image is
     234             :    * available and our decoding heuristics are satisfied - then trigger a decode
     235             :    * for our image at the size we predict it will be drawn next time it's
     236             :    * painted.
     237             :    */
     238             :   void MaybeDecodeForPredictedSize();
     239             : 
     240             : protected:
     241             :   friend class nsImageListener;
     242             :   friend class nsImageLoadingContent;
     243             :   friend class mozilla::PresShell;
     244             : 
     245             :   nsresult OnSizeAvailable(imgIRequest* aRequest, imgIContainer* aImage);
     246             :   nsresult OnFrameUpdate(imgIRequest* aRequest, const nsIntRect* aRect);
     247             :   nsresult OnLoadComplete(imgIRequest* aRequest, nsresult aStatus);
     248             : 
     249             :   /**
     250             :    * Notification that aRequest will now be the current request.
     251             :    */
     252             :   void NotifyNewCurrentRequest(imgIRequest *aRequest, nsresult aStatus);
     253             : 
     254             :   /// Always sync decode our image when painting if @aForce is true.
     255           0 :   void SetForceSyncDecoding(bool aForce) { mForceSyncDecoding = aForce; }
     256             : 
     257             :   /**
     258             :    * Computes the predicted dest rect that we'll draw into, in app units, based
     259             :    * upon the provided frame content box. (The content box is what
     260             :    * nsDisplayImage::GetBounds() returns.)
     261             :    * The result is not necessarily contained in the frame content box.
     262             :    */
     263             :   nsRect PredictedDestRect(const nsRect& aFrameContentBox);
     264             : 
     265             : private:
     266             :   // random helpers
     267             :   inline void SpecToURI(const nsAString& aSpec, nsIIOService *aIOService,
     268             :                         nsIURI **aURI);
     269             : 
     270             :   inline void GetLoadGroup(nsPresContext *aPresContext,
     271             :                            nsILoadGroup **aLoadGroup);
     272             :   nscoord GetContinuationOffset() const;
     273             :   void GetDocumentCharacterSet(nsACString& aCharset) const;
     274             :   bool ShouldDisplaySelection();
     275             : 
     276             :   /**
     277             :    * Recalculate mIntrinsicSize from the image.
     278             :    *
     279             :    * @return whether aImage's size did _not_
     280             :    *         match our previous intrinsic size.
     281             :    */
     282             :   bool UpdateIntrinsicSize(imgIContainer* aImage);
     283             : 
     284             :   /**
     285             :    * Recalculate mIntrinsicRatio from the image.
     286             :    *
     287             :    * @return whether aImage's ratio did _not_
     288             :    *         match our previous intrinsic ratio.
     289             :    */
     290             :   bool UpdateIntrinsicRatio(imgIContainer* aImage);
     291             : 
     292             :   /**
     293             :    * This function calculates the transform for converting between
     294             :    * source space & destination space. May fail if our image has a
     295             :    * percent-valued or zero-valued height or width.
     296             :    *
     297             :    * @param aTransform The transform object to populate.
     298             :    *
     299             :    * @return whether we succeeded in creating the transform.
     300             :    */
     301             :   bool GetSourceToDestTransform(nsTransform2D& aTransform);
     302             : 
     303             :   /**
     304             :    * Helper function to check whether the request corresponds to a load we don't
     305             :    * care about.  Most of the decoder observer methods will bail early if this
     306             :    * returns true.
     307             :    */
     308             :   bool IsPendingLoad(imgIRequest* aRequest) const;
     309             : 
     310             :   /**
     311             :    * Function to convert a dirty rect in the source image to a dirty
     312             :    * rect for the image frame.
     313             :    */
     314             :   nsRect SourceRectToDest(const nsIntRect & aRect);
     315             : 
     316             :   /**
     317             :    * Triggers invalidation for both our image display item and, if appropriate,
     318             :    * our alt-feedback display item.
     319             :    *
     320             :    * @param aLayerInvalidRect The area to invalidate in layer space. If null, the
     321             :    *                          entire layer will be invalidated.
     322             :    * @param aFrameInvalidRect The area to invalidate in frame space. If null, the
     323             :    *                          entire frame will be invalidated.
     324             :    */
     325             :   void InvalidateSelf(const nsIntRect* aLayerInvalidRect,
     326             :                       const nsRect* aFrameInvalidRect);
     327             : 
     328             :   RefPtr<nsImageMap> mImageMap;
     329             : 
     330             :   nsCOMPtr<imgINotificationObserver> mListener;
     331             : 
     332             :   nsCOMPtr<imgIContainer> mImage;
     333             :   nsCOMPtr<imgIContainer> mPrevImage;
     334             :   nsSize mComputedSize;
     335             :   mozilla::IntrinsicSize mIntrinsicSize;
     336             :   nsSize mIntrinsicRatio;
     337             : 
     338             :   bool mDisplayingIcon;
     339             :   bool mFirstFrameComplete;
     340             :   bool mReflowCallbackPosted;
     341             :   bool mForceSyncDecoding;
     342             : 
     343             :   static nsIIOService* sIOService;
     344             : 
     345             :   /* loading / broken image icon support */
     346             : 
     347             :   // XXXbz this should be handled by the prescontext, I think; that
     348             :   // way we would have a single iconload per mozilla session instead
     349             :   // of one per document...
     350             : 
     351             :   // LoadIcons: initiate the loading of the static icons used to show
     352             :   // loading / broken images
     353             :   nsresult LoadIcons(nsPresContext *aPresContext);
     354             :   nsresult LoadIcon(const nsAString& aSpec, nsPresContext *aPresContext,
     355             :                     imgRequestProxy **aRequest);
     356             : 
     357             :   class IconLoad final : public nsIObserver,
     358             :                          public imgINotificationObserver
     359             :   {
     360             :     // private class that wraps the data and logic needed for
     361             :     // broken image and loading image icons
     362             :   public:
     363             :     IconLoad();
     364             : 
     365             :     void Shutdown();
     366             : 
     367             :     NS_DECL_ISUPPORTS
     368             :     NS_DECL_NSIOBSERVER
     369             :     NS_DECL_IMGINOTIFICATIONOBSERVER
     370             : 
     371           0 :     void AddIconObserver(nsImageFrame *frame) {
     372           0 :         MOZ_ASSERT(!mIconObservers.Contains(frame),
     373             :                    "Observer shouldn't aleady be in array");
     374           0 :         mIconObservers.AppendElement(frame);
     375           0 :     }
     376             : 
     377           0 :     void RemoveIconObserver(nsImageFrame *frame) {
     378           0 :       mozilla::DebugOnly<bool> didRemove = mIconObservers.RemoveElement(frame);
     379           0 :       MOZ_ASSERT(didRemove, "Observer not in array");
     380           0 :     }
     381             : 
     382             :   private:
     383           0 :     ~IconLoad() {}
     384             : 
     385             :     void GetPrefs();
     386             :     nsTObserverArray<nsImageFrame*> mIconObservers;
     387             : 
     388             : 
     389             :   public:
     390             :     RefPtr<imgRequestProxy> mLoadingImage;
     391             :     RefPtr<imgRequestProxy> mBrokenImage;
     392             :     bool             mPrefForceInlineAltText;
     393             :     bool             mPrefShowPlaceholders;
     394             :     bool             mPrefShowLoadingPlaceholder;
     395             :   };
     396             : 
     397             : public:
     398             :   static IconLoad* gIconLoad; // singleton pattern: one LoadIcons instance is used
     399             : 
     400             :   friend class nsDisplayImage;
     401             : };
     402             : 
     403             : /**
     404             :  * Note that nsDisplayImage does not receive events. However, an image element
     405             :  * is replaced content so its background will be z-adjacent to the
     406             :  * image itself, and hence receive events just as if the image itself
     407             :  * received events.
     408             :  */
     409             : class nsDisplayImage : public nsDisplayImageContainer {
     410             : public:
     411             :   typedef mozilla::layers::LayerManager LayerManager;
     412             : 
     413           0 :   nsDisplayImage(nsDisplayListBuilder* aBuilder, nsImageFrame* aFrame,
     414             :                  imgIContainer* aImage, imgIContainer* aPrevImage)
     415           0 :     : nsDisplayImageContainer(aBuilder, aFrame)
     416             :     , mImage(aImage)
     417           0 :     , mPrevImage(aPrevImage)
     418             :   {
     419           0 :     MOZ_COUNT_CTOR(nsDisplayImage);
     420           0 :   }
     421           0 :   virtual ~nsDisplayImage() {
     422           0 :     MOZ_COUNT_DTOR(nsDisplayImage);
     423           0 :   }
     424             : 
     425             :   virtual nsDisplayItemGeometry* AllocateGeometry(nsDisplayListBuilder* aBuilder) override;
     426             :   virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
     427             :                                          const nsDisplayItemGeometry* aGeometry,
     428             :                                          nsRegion* aInvalidRegion) override;
     429             :   virtual void Paint(nsDisplayListBuilder* aBuilder,
     430             :                      gfxContext* aCtx) override;
     431             : 
     432             :   virtual already_AddRefed<imgIContainer> GetImage() override;
     433             : 
     434             :   /**
     435             :    * @return The dest rect we'll use when drawing this image, in app units.
     436             :    *         Not necessarily contained in this item's bounds.
     437             :    */
     438             :   virtual nsRect GetDestRect() override;
     439             : 
     440             :   virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
     441             :                                    LayerManager* aManager,
     442             :                                    const ContainerLayerParameters& aParameters) override;
     443           0 :   nsRect GetBounds(bool* aSnap)
     444             :   {
     445           0 :     *aSnap = true;
     446             : 
     447           0 :     nsImageFrame* imageFrame = static_cast<nsImageFrame*>(mFrame);
     448           0 :     return imageFrame->GetInnerArea() + ToReferenceFrame();
     449             :   }
     450             : 
     451           0 :   virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder,
     452             :                            bool* aSnap) override
     453             :   {
     454           0 :     return GetBounds(aSnap);
     455             :   }
     456             : 
     457             :   virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
     458             :                                    bool* aSnap) override;
     459             : 
     460             :   virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
     461             :                                              LayerManager* aManager,
     462             :                                              const ContainerLayerParameters& aContainerParameters) override;
     463             :   virtual bool CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
     464             :                                        const StackingContextHelper& aSc,
     465             :                                        nsTArray<WebRenderParentCommand>& aParentCommands,
     466             :                                        mozilla::layers::WebRenderLayerManager* aManager,
     467             :                                        nsDisplayListBuilder* aDisplayListBuilder) override;
     468             : 
     469           0 :   NS_DISPLAY_DECL_NAME("Image", TYPE_IMAGE)
     470             : private:
     471             :   nsCOMPtr<imgIContainer> mImage;
     472             :   nsCOMPtr<imgIContainer> mPrevImage;
     473             : };
     474             : 
     475             : #endif /* nsImageFrame_h___ */

Generated by: LCOV version 1.13