layout/generic/nsImageFrame.h

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     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/. */
     6 /* rendering object for replaced elements with bitmap image data */
     8 #ifndef nsImageFrame_h___
     9 #define nsImageFrame_h___
    11 #include "nsSplittableFrame.h"
    12 #include "nsIIOService.h"
    13 #include "nsIObserver.h"
    15 #include "imgINotificationObserver.h"
    17 #include "nsDisplayList.h"
    18 #include "imgIContainer.h"
    19 #include "mozilla/Attributes.h"
    20 #include "mozilla/DebugOnly.h"
    21 #include "nsIReflowCallback.h"
    23 class nsImageMap;
    24 class nsIURI;
    25 class nsILoadGroup;
    26 struct nsHTMLReflowState;
    27 struct nsHTMLReflowMetrics;
    28 class nsDisplayImage;
    29 class nsPresContext;
    30 class nsImageFrame;
    31 class nsTransform2D;
    32 class nsImageLoadingContent;
    34 namespace mozilla {
    35 namespace layers {
    36   class ImageContainer;
    37   class ImageLayer;
    38   class LayerManager;
    39 }
    40 }
    42 class nsImageListener : public imgINotificationObserver
    43 {
    44 public:
    45   nsImageListener(nsImageFrame *aFrame);
    46   virtual ~nsImageListener();
    48   NS_DECL_ISUPPORTS
    49   NS_DECL_IMGINOTIFICATIONOBSERVER
    51   void SetFrame(nsImageFrame *frame) { mFrame = frame; }
    53 private:
    54   nsImageFrame *mFrame;
    55 };
    57 typedef nsSplittableFrame ImageFrameSuper;
    59 class nsImageFrame : public ImageFrameSuper,
    60                      public nsIReflowCallback {
    61 public:
    62   typedef mozilla::layers::ImageContainer ImageContainer;
    63   typedef mozilla::layers::ImageLayer ImageLayer;
    64   typedef mozilla::layers::LayerManager LayerManager;
    66   NS_DECL_FRAMEARENA_HELPERS
    68   nsImageFrame(nsStyleContext* aContext);
    70   NS_DECL_QUERYFRAME_TARGET(nsImageFrame)
    71   NS_DECL_QUERYFRAME
    73   virtual void DestroyFrom(nsIFrame* aDestructRoot) MOZ_OVERRIDE;
    74   virtual void Init(nsIContent*      aContent,
    75                     nsIFrame*        aParent,
    76                     nsIFrame*        aPrevInFlow) MOZ_OVERRIDE;
    77   virtual void BuildDisplayList(nsDisplayListBuilder*   aBuilder,
    78                                 const nsRect&           aDirtyRect,
    79                                 const nsDisplayListSet& aLists) MOZ_OVERRIDE;
    80   virtual nscoord GetMinWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE;
    81   virtual nscoord GetPrefWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE;
    82   virtual mozilla::IntrinsicSize GetIntrinsicSize() MOZ_OVERRIDE;
    83   virtual nsSize GetIntrinsicRatio() MOZ_OVERRIDE;
    84   virtual nsresult Reflow(nsPresContext*          aPresContext,
    85                           nsHTMLReflowMetrics&     aDesiredSize,
    86                           const nsHTMLReflowState& aReflowState,
    87                           nsReflowStatus&          aStatus) MOZ_OVERRIDE;
    89   virtual nsresult  GetContentForEvent(mozilla::WidgetEvent* aEvent,
    90                                        nsIContent** aContent) MOZ_OVERRIDE;
    91   virtual nsresult HandleEvent(nsPresContext* aPresContext,
    92                                mozilla::WidgetGUIEvent* aEvent,
    93                                nsEventStatus* aEventStatus) MOZ_OVERRIDE;
    94   virtual nsresult GetCursor(const nsPoint& aPoint,
    95                              nsIFrame::Cursor& aCursor) MOZ_OVERRIDE;
    96   virtual nsresult AttributeChanged(int32_t aNameSpaceID,
    97                                     nsIAtom* aAttribute,
    98                                     int32_t aModType) MOZ_OVERRIDE;
   100 #ifdef ACCESSIBILITY
   101   virtual mozilla::a11y::AccType AccessibleType() MOZ_OVERRIDE;
   102 #endif
   104   virtual nsIAtom* GetType() const MOZ_OVERRIDE;
   106   virtual bool IsFrameOfType(uint32_t aFlags) const MOZ_OVERRIDE
   107   {
   108     return ImageFrameSuper::IsFrameOfType(aFlags & ~(nsIFrame::eReplaced));
   109   }
   111 #ifdef DEBUG_FRAME_DUMP
   112   virtual nsresult GetFrameName(nsAString& aResult) const MOZ_OVERRIDE;
   113   void List(FILE* out = stderr, const char* aPrefix = "", 
   114             uint32_t aFlags = 0) const MOZ_OVERRIDE;
   115 #endif
   117   virtual int GetLogicalSkipSides(const nsHTMLReflowState* aReflowState = nullptr) const MOZ_OVERRIDE;
   119   nsresult GetIntrinsicImageSize(nsSize& aSize);
   121   static void ReleaseGlobals() {
   122     if (gIconLoad) {
   123       gIconLoad->Shutdown();
   124       NS_RELEASE(gIconLoad);
   125     }
   126     NS_IF_RELEASE(sIOService);
   127   }
   129   nsresult Notify(imgIRequest *aRequest, int32_t aType, const nsIntRect* aData);
   131   /**
   132    * Function to test whether aContent, which has aStyleContext as its style,
   133    * should get an image frame.  Note that this method is only used by the
   134    * frame constructor; it's only here because it uses gIconLoad for now.
   135    */
   136   static bool ShouldCreateImageFrameFor(mozilla::dom::Element* aElement,
   137                                           nsStyleContext* aStyleContext);
   139   void DisplayAltFeedback(nsRenderingContext& aRenderingContext,
   140                           const nsRect&        aDirtyRect,
   141                           imgIRequest*         aRequest,
   142                           nsPoint              aPt);
   144   nsRect GetInnerArea() const;
   146   /**
   147    * Return a map element associated with this image.
   148    */
   149   mozilla::dom::Element* GetMapElement() const
   150   {
   151     nsAutoString usemap;
   152     if (mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::usemap, usemap)) {
   153       return mContent->OwnerDoc()->FindImageMap(usemap);
   154     }
   155     return nullptr;
   156   }
   158   /**
   159    * Return true if the image has associated image map.
   160    */
   161   bool HasImageMap() const { return mImageMap || GetMapElement(); }
   163   nsImageMap* GetImageMap();
   164   nsImageMap* GetExistingImageMap() const { return mImageMap; }
   166   virtual void AddInlineMinWidth(nsRenderingContext *aRenderingContext,
   167                                  InlineMinWidthData *aData) MOZ_OVERRIDE;
   169   void DisconnectMap();
   171   // nsIReflowCallback
   172   virtual bool ReflowFinished() MOZ_OVERRIDE;
   173   virtual void ReflowCallbackCanceled() MOZ_OVERRIDE;
   175 protected:
   176   virtual ~nsImageFrame();
   178   void EnsureIntrinsicSizeAndRatio(nsPresContext* aPresContext);
   180   virtual nsSize ComputeSize(nsRenderingContext *aRenderingContext,
   181                              nsSize aCBSize, nscoord aAvailableWidth,
   182                              nsSize aMargin, nsSize aBorder, nsSize aPadding,
   183                              uint32_t aFlags) MOZ_OVERRIDE;
   185   bool IsServerImageMap();
   187   void TranslateEventCoords(const nsPoint& aPoint,
   188                             nsIntPoint& aResult);
   190   bool GetAnchorHREFTargetAndNode(nsIURI** aHref, nsString& aTarget,
   191                                     nsIContent** aNode);
   192   /**
   193    * Computes the width of the string that fits into the available space
   194    *
   195    * @param in aLength total length of the string in PRUnichars
   196    * @param in aMaxWidth width not to be exceeded
   197    * @param out aMaxFit length of the string that fits within aMaxWidth
   198    *            in PRUnichars
   199    * @return width of the string that fits within aMaxWidth
   200    */
   201   nscoord MeasureString(const char16_t*     aString,
   202                         int32_t              aLength,
   203                         nscoord              aMaxWidth,
   204                         uint32_t&            aMaxFit,
   205                         nsRenderingContext& aContext);
   207   void DisplayAltText(nsPresContext*      aPresContext,
   208                       nsRenderingContext& aRenderingContext,
   209                       const nsString&      aAltText,
   210                       const nsRect&        aRect);
   212   void PaintImage(nsRenderingContext& aRenderingContext, nsPoint aPt,
   213                   const nsRect& aDirtyRect, imgIContainer* aImage,
   214                   uint32_t aFlags);
   216 protected:
   217   friend class nsImageListener;
   218   friend class nsImageLoadingContent;
   219   nsresult OnStartContainer(imgIRequest *aRequest, imgIContainer *aImage);
   220   nsresult OnDataAvailable(imgIRequest *aRequest, const nsIntRect *rect);
   221   nsresult OnStopRequest(imgIRequest *aRequest,
   222                          nsresult aStatus);
   223   nsresult FrameChanged(imgIRequest *aRequest,
   224                         imgIContainer *aContainer);
   225   /**
   226    * Notification that aRequest will now be the current request.
   227    */
   228   void NotifyNewCurrentRequest(imgIRequest *aRequest, nsresult aStatus);
   230 private:
   231   // random helpers
   232   inline void SpecToURI(const nsAString& aSpec, nsIIOService *aIOService,
   233                         nsIURI **aURI);
   235   inline void GetLoadGroup(nsPresContext *aPresContext,
   236                            nsILoadGroup **aLoadGroup);
   237   nscoord GetContinuationOffset() const;
   238   void GetDocumentCharacterSet(nsACString& aCharset) const;
   239   bool ShouldDisplaySelection();
   241   /**
   242    * Recalculate mIntrinsicSize from the image.
   243    *
   244    * @return whether aImage's size did _not_
   245    *         match our previous intrinsic size.
   246    */
   247   bool UpdateIntrinsicSize(imgIContainer* aImage);
   249   /**
   250    * Recalculate mIntrinsicRatio from the image.
   251    *
   252    * @return whether aImage's ratio did _not_
   253    *         match our previous intrinsic ratio.
   254    */
   255   bool UpdateIntrinsicRatio(imgIContainer* aImage);
   257   /**
   258    * This function calculates the transform for converting between
   259    * source space & destination space. May fail if our image has a
   260    * percent-valued or zero-valued height or width.
   261    *
   262    * @param aTransform The transform object to populate.
   263    *
   264    * @return whether we succeeded in creating the transform.
   265    */
   266   bool GetSourceToDestTransform(nsTransform2D& aTransform);
   268   /**
   269    * Helper functions to check whether the request or image container
   270    * corresponds to a load we don't care about.  Most of the decoder
   271    * observer methods will bail early if these return true.
   272    */
   273   bool IsPendingLoad(imgIRequest* aRequest) const;
   274   bool IsPendingLoad(imgIContainer* aContainer) const;
   276   /**
   277    * Function to convert a dirty rect in the source image to a dirty
   278    * rect for the image frame.
   279    */
   280   nsRect SourceRectToDest(const nsIntRect & aRect);
   282   nsImageMap*         mImageMap;
   284   nsCOMPtr<imgINotificationObserver> mListener;
   286   nsCOMPtr<imgIContainer> mImage;
   287   nsSize mComputedSize;
   288   mozilla::IntrinsicSize mIntrinsicSize;
   289   nsSize mIntrinsicRatio;
   291   bool mDisplayingIcon;
   292   bool mFirstFrameComplete;
   293   bool mReflowCallbackPosted;
   295   static nsIIOService* sIOService;
   297   /* loading / broken image icon support */
   299   // XXXbz this should be handled by the prescontext, I think; that
   300   // way we would have a single iconload per mozilla session instead
   301   // of one per document...
   303   // LoadIcons: initiate the loading of the static icons used to show
   304   // loading / broken images
   305   nsresult LoadIcons(nsPresContext *aPresContext);
   306   nsresult LoadIcon(const nsAString& aSpec, nsPresContext *aPresContext,
   307                     imgRequestProxy **aRequest);
   309   class IconLoad MOZ_FINAL : public nsIObserver,
   310                              public imgINotificationObserver {
   311     // private class that wraps the data and logic needed for
   312     // broken image and loading image icons
   313   public:
   314     IconLoad();
   316     void Shutdown();
   318     NS_DECL_ISUPPORTS
   319     NS_DECL_NSIOBSERVER
   320     NS_DECL_IMGINOTIFICATIONOBSERVER
   322     void AddIconObserver(nsImageFrame *frame) {
   323         NS_ABORT_IF_FALSE(!mIconObservers.Contains(frame),
   324                           "Observer shouldn't aleady be in array");
   325         mIconObservers.AppendElement(frame);
   326     }
   328     void RemoveIconObserver(nsImageFrame *frame) {
   329       mozilla::DebugOnly<bool> didRemove = mIconObservers.RemoveElement(frame);
   330       NS_ABORT_IF_FALSE(didRemove, "Observer not in array");
   331     }
   333   private:
   334     void GetPrefs();
   335     nsTObserverArray<nsImageFrame*> mIconObservers;
   338   public:
   339     nsRefPtr<imgRequestProxy> mLoadingImage;
   340     nsRefPtr<imgRequestProxy> mBrokenImage;
   341     bool             mPrefForceInlineAltText;
   342     bool             mPrefShowPlaceholders;
   343   };
   345 public:
   346   static IconLoad* gIconLoad; // singleton pattern: one LoadIcons instance is used
   348   friend class nsDisplayImage;
   349 };
   351 /**
   352  * Note that nsDisplayImage does not receive events. However, an image element
   353  * is replaced content so its background will be z-adjacent to the
   354  * image itself, and hence receive events just as if the image itself
   355  * received events.
   356  */
   357 class nsDisplayImage : public nsDisplayImageContainer {
   358 public:
   359   typedef mozilla::layers::LayerManager LayerManager;
   361   nsDisplayImage(nsDisplayListBuilder* aBuilder, nsImageFrame* aFrame,
   362                  imgIContainer* aImage)
   363     : nsDisplayImageContainer(aBuilder, aFrame), mImage(aImage) {
   364     MOZ_COUNT_CTOR(nsDisplayImage);
   365   }
   366   virtual ~nsDisplayImage() {
   367     MOZ_COUNT_DTOR(nsDisplayImage);
   368   }
   369   virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
   370                                          const nsDisplayItemGeometry* aGeometry,
   371                                          nsRegion* aInvalidRegion) MOZ_OVERRIDE;
   372   virtual void Paint(nsDisplayListBuilder* aBuilder,
   373                      nsRenderingContext* aCtx) MOZ_OVERRIDE;
   375   /**
   376    * Returns an ImageContainer for this image if the image type
   377    * supports it (TYPE_RASTER only).
   378    */
   379   virtual already_AddRefed<ImageContainer> GetContainer(LayerManager* aManager,
   380                                                         nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE;
   382   gfxRect GetDestRect();
   384   virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
   385                                    LayerManager* aManager,
   386                                    const ContainerLayerParameters& aParameters) MOZ_OVERRIDE;
   387   virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) MOZ_OVERRIDE
   388   {
   389     *aSnap = true;
   390     return nsRect(ToReferenceFrame(), Frame()->GetSize());
   391   }
   393   virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
   394                                              LayerManager* aManager,
   395                                              const ContainerLayerParameters& aContainerParameters) MOZ_OVERRIDE;
   397   /**
   398    * Configure an ImageLayer for this display item.
   399    * Set the required filter and scaling transform.
   400    */
   401   virtual void ConfigureLayer(ImageLayer* aLayer, const nsIntPoint& aOffset) MOZ_OVERRIDE;
   403   NS_DISPLAY_DECL_NAME("Image", TYPE_IMAGE)
   404 private:
   405   nsCOMPtr<imgIContainer> mImage;
   406 };
   408 #endif /* nsImageFrame_h___ */

mercurial