Bumping manifests a=b2g-bump
[gecko.git] / layout / generic / nsImageFrame.h
blob35bb9dac4b73955f7294be98654d9a7a72e80d22
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 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"
22 #include "nsTObserverArray.h"
24 class nsFontMetrics;
25 class nsImageMap;
26 class nsIURI;
27 class nsILoadGroup;
28 struct nsHTMLReflowState;
29 class nsHTMLReflowMetrics;
30 class nsDisplayImage;
31 class nsPresContext;
32 class nsImageFrame;
33 class nsTransform2D;
34 class nsImageLoadingContent;
36 namespace mozilla {
37 namespace layers {
38 class ImageContainer;
39 class ImageLayer;
40 class LayerManager;
44 class nsImageListener : public imgINotificationObserver
46 protected:
47 virtual ~nsImageListener();
49 public:
50 explicit nsImageListener(nsImageFrame *aFrame);
52 NS_DECL_ISUPPORTS
53 NS_DECL_IMGINOTIFICATIONOBSERVER
55 void SetFrame(nsImageFrame *frame) { mFrame = frame; }
57 private:
58 nsImageFrame *mFrame;
61 typedef nsSplittableFrame ImageFrameSuper;
63 class nsImageFrame : public ImageFrameSuper,
64 public nsIReflowCallback {
65 public:
66 typedef mozilla::image::DrawResult DrawResult;
67 typedef mozilla::layers::ImageContainer ImageContainer;
68 typedef mozilla::layers::ImageLayer ImageLayer;
69 typedef mozilla::layers::LayerManager LayerManager;
71 NS_DECL_FRAMEARENA_HELPERS
73 explicit nsImageFrame(nsStyleContext* aContext);
75 NS_DECL_QUERYFRAME_TARGET(nsImageFrame)
76 NS_DECL_QUERYFRAME
78 virtual void DestroyFrom(nsIFrame* aDestructRoot) MOZ_OVERRIDE;
79 virtual void DidSetStyleContext(nsStyleContext* aOldStyleContext) MOZ_OVERRIDE;
81 virtual void Init(nsIContent* aContent,
82 nsContainerFrame* aParent,
83 nsIFrame* aPrevInFlow) MOZ_OVERRIDE;
84 virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder,
85 const nsRect& aDirtyRect,
86 const nsDisplayListSet& aLists) MOZ_OVERRIDE;
87 virtual nscoord GetMinISize(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE;
88 virtual nscoord GetPrefISize(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE;
89 virtual mozilla::IntrinsicSize GetIntrinsicSize() MOZ_OVERRIDE;
90 virtual nsSize GetIntrinsicRatio() MOZ_OVERRIDE;
91 virtual void Reflow(nsPresContext* aPresContext,
92 nsHTMLReflowMetrics& aDesiredSize,
93 const nsHTMLReflowState& aReflowState,
94 nsReflowStatus& aStatus) MOZ_OVERRIDE;
96 virtual nsresult GetContentForEvent(mozilla::WidgetEvent* aEvent,
97 nsIContent** aContent) MOZ_OVERRIDE;
98 virtual nsresult HandleEvent(nsPresContext* aPresContext,
99 mozilla::WidgetGUIEvent* aEvent,
100 nsEventStatus* aEventStatus) MOZ_OVERRIDE;
101 virtual nsresult GetCursor(const nsPoint& aPoint,
102 nsIFrame::Cursor& aCursor) MOZ_OVERRIDE;
103 virtual nsresult AttributeChanged(int32_t aNameSpaceID,
104 nsIAtom* aAttribute,
105 int32_t aModType) MOZ_OVERRIDE;
107 #ifdef ACCESSIBILITY
108 virtual mozilla::a11y::AccType AccessibleType() MOZ_OVERRIDE;
109 #endif
111 virtual nsIAtom* GetType() const MOZ_OVERRIDE;
113 virtual bool IsFrameOfType(uint32_t aFlags) const MOZ_OVERRIDE
115 return ImageFrameSuper::IsFrameOfType(aFlags & ~(nsIFrame::eReplaced));
118 #ifdef DEBUG_FRAME_DUMP
119 virtual nsresult GetFrameName(nsAString& aResult) const MOZ_OVERRIDE;
120 void List(FILE* out = stderr, const char* aPrefix = "",
121 uint32_t aFlags = 0) const MOZ_OVERRIDE;
122 #endif
124 virtual LogicalSides GetLogicalSkipSides(const nsHTMLReflowState* aReflowState = nullptr) const MOZ_OVERRIDE;
126 nsresult GetIntrinsicImageSize(nsSize& aSize);
128 static void ReleaseGlobals() {
129 if (gIconLoad) {
130 gIconLoad->Shutdown();
131 NS_RELEASE(gIconLoad);
133 NS_IF_RELEASE(sIOService);
136 nsresult Notify(imgIRequest *aRequest, int32_t aType, const nsIntRect* aData);
139 * Function to test whether aContent, which has aStyleContext as its style,
140 * should get an image frame. Note that this method is only used by the
141 * frame constructor; it's only here because it uses gIconLoad for now.
143 static bool ShouldCreateImageFrameFor(mozilla::dom::Element* aElement,
144 nsStyleContext* aStyleContext);
146 void DisplayAltFeedback(nsRenderingContext& aRenderingContext,
147 const nsRect& aDirtyRect,
148 imgIRequest* aRequest,
149 nsPoint aPt);
151 nsRect GetInnerArea() const;
154 * Return a map element associated with this image.
156 mozilla::dom::Element* GetMapElement() const;
159 * Return true if the image has associated image map.
161 bool HasImageMap() const { return mImageMap || GetMapElement(); }
163 nsImageMap* GetImageMap();
164 nsImageMap* GetExistingImageMap() const { return mImageMap; }
166 virtual void AddInlineMinISize(nsRenderingContext *aRenderingContext,
167 InlineMinISizeData *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();
180 virtual mozilla::LogicalSize
181 ComputeSize(nsRenderingContext *aRenderingContext,
182 mozilla::WritingMode aWritingMode,
183 const mozilla::LogicalSize& aCBSize,
184 nscoord aAvailableISize,
185 const mozilla::LogicalSize& aMargin,
186 const mozilla::LogicalSize& aBorder,
187 const mozilla::LogicalSize& aPadding,
188 ComputeSizeFlags aFlags) MOZ_OVERRIDE;
190 bool IsServerImageMap();
192 void TranslateEventCoords(const nsPoint& aPoint,
193 nsIntPoint& aResult);
195 bool GetAnchorHREFTargetAndNode(nsIURI** aHref, nsString& aTarget,
196 nsIContent** aNode);
198 * Computes the width of the string that fits into the available space
200 * @param in aLength total length of the string in PRUnichars
201 * @param in aMaxWidth width not to be exceeded
202 * @param out aMaxFit length of the string that fits within aMaxWidth
203 * in PRUnichars
204 * @return width of the string that fits within aMaxWidth
206 nscoord MeasureString(const char16_t* aString,
207 int32_t aLength,
208 nscoord aMaxWidth,
209 uint32_t& aMaxFit,
210 nsRenderingContext& aContext,
211 nsFontMetrics& aFontMetrics);
213 void DisplayAltText(nsPresContext* aPresContext,
214 nsRenderingContext& aRenderingContext,
215 const nsString& aAltText,
216 const nsRect& aRect);
218 DrawResult PaintImage(nsRenderingContext& aRenderingContext, nsPoint aPt,
219 const nsRect& aDirtyRect, imgIContainer* aImage,
220 uint32_t aFlags);
222 protected:
223 friend class nsImageListener;
224 friend class nsImageLoadingContent;
226 nsresult OnSizeAvailable(imgIRequest* aRequest, imgIContainer* aImage);
227 nsresult OnFrameUpdate(imgIRequest* aRequest, const nsIntRect* aRect);
228 nsresult OnLoadComplete(imgIRequest* aRequest, nsresult aStatus);
231 * Notification that aRequest will now be the current request.
233 void NotifyNewCurrentRequest(imgIRequest *aRequest, nsresult aStatus);
235 private:
236 // random helpers
237 inline void SpecToURI(const nsAString& aSpec, nsIIOService *aIOService,
238 nsIURI **aURI);
240 inline void GetLoadGroup(nsPresContext *aPresContext,
241 nsILoadGroup **aLoadGroup);
242 nscoord GetContinuationOffset() const;
243 void GetDocumentCharacterSet(nsACString& aCharset) const;
244 bool ShouldDisplaySelection();
247 * Recalculate mIntrinsicSize from the image.
249 * @return whether aImage's size did _not_
250 * match our previous intrinsic size.
252 bool UpdateIntrinsicSize(imgIContainer* aImage);
255 * Recalculate mIntrinsicRatio from the image.
257 * @return whether aImage's ratio did _not_
258 * match our previous intrinsic ratio.
260 bool UpdateIntrinsicRatio(imgIContainer* aImage);
263 * This function calculates the transform for converting between
264 * source space & destination space. May fail if our image has a
265 * percent-valued or zero-valued height or width.
267 * @param aTransform The transform object to populate.
269 * @return whether we succeeded in creating the transform.
271 bool GetSourceToDestTransform(nsTransform2D& aTransform);
274 * Helper function to check whether the request corresponds to a load we don't
275 * care about. Most of the decoder observer methods will bail early if this
276 * returns true.
278 bool IsPendingLoad(imgIRequest* aRequest) const;
281 * Function to convert a dirty rect in the source image to a dirty
282 * rect for the image frame.
284 nsRect SourceRectToDest(const nsIntRect & aRect);
287 * Triggers invalidation for both our image display item and, if appropriate,
288 * our alt-feedback display item.
290 * @param aLayerInvalidRect The area to invalidate in layer space. If null, the
291 * entire layer will be invalidated.
292 * @param aFrameInvalidRect The area to invalidate in frame space. If null, the
293 * entire frame will be invalidated.
295 void InvalidateSelf(const nsIntRect* aLayerInvalidRect,
296 const nsRect* aFrameInvalidRect);
298 nsImageMap* mImageMap;
300 nsCOMPtr<imgINotificationObserver> mListener;
302 nsCOMPtr<imgIContainer> mImage;
303 nsSize mComputedSize;
304 mozilla::IntrinsicSize mIntrinsicSize;
305 nsSize mIntrinsicRatio;
307 bool mDisplayingIcon;
308 bool mFirstFrameComplete;
309 bool mReflowCallbackPosted;
311 static nsIIOService* sIOService;
313 /* loading / broken image icon support */
315 // XXXbz this should be handled by the prescontext, I think; that
316 // way we would have a single iconload per mozilla session instead
317 // of one per document...
319 // LoadIcons: initiate the loading of the static icons used to show
320 // loading / broken images
321 nsresult LoadIcons(nsPresContext *aPresContext);
322 nsresult LoadIcon(const nsAString& aSpec, nsPresContext *aPresContext,
323 imgRequestProxy **aRequest);
325 class IconLoad MOZ_FINAL : public nsIObserver,
326 public imgINotificationObserver {
327 // private class that wraps the data and logic needed for
328 // broken image and loading image icons
329 public:
330 IconLoad();
332 void Shutdown();
334 NS_DECL_ISUPPORTS
335 NS_DECL_NSIOBSERVER
336 NS_DECL_IMGINOTIFICATIONOBSERVER
338 void AddIconObserver(nsImageFrame *frame) {
339 NS_ABORT_IF_FALSE(!mIconObservers.Contains(frame),
340 "Observer shouldn't aleady be in array");
341 mIconObservers.AppendElement(frame);
344 void RemoveIconObserver(nsImageFrame *frame) {
345 mozilla::DebugOnly<bool> didRemove = mIconObservers.RemoveElement(frame);
346 NS_ABORT_IF_FALSE(didRemove, "Observer not in array");
349 private:
350 ~IconLoad() {}
352 void GetPrefs();
353 nsTObserverArray<nsImageFrame*> mIconObservers;
356 public:
357 nsRefPtr<imgRequestProxy> mLoadingImage;
358 nsRefPtr<imgRequestProxy> mBrokenImage;
359 bool mPrefForceInlineAltText;
360 bool mPrefShowPlaceholders;
363 public:
364 static IconLoad* gIconLoad; // singleton pattern: one LoadIcons instance is used
366 friend class nsDisplayImage;
370 * Note that nsDisplayImage does not receive events. However, an image element
371 * is replaced content so its background will be z-adjacent to the
372 * image itself, and hence receive events just as if the image itself
373 * received events.
375 class nsDisplayImage : public nsDisplayImageContainer {
376 public:
377 typedef mozilla::layers::LayerManager LayerManager;
379 nsDisplayImage(nsDisplayListBuilder* aBuilder, nsImageFrame* aFrame,
380 imgIContainer* aImage)
381 : nsDisplayImageContainer(aBuilder, aFrame), mImage(aImage) {
382 MOZ_COUNT_CTOR(nsDisplayImage);
384 virtual ~nsDisplayImage() {
385 MOZ_COUNT_DTOR(nsDisplayImage);
388 virtual nsDisplayItemGeometry* AllocateGeometry(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE;
389 virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
390 const nsDisplayItemGeometry* aGeometry,
391 nsRegion* aInvalidRegion) MOZ_OVERRIDE;
392 virtual void Paint(nsDisplayListBuilder* aBuilder,
393 nsRenderingContext* aCtx) MOZ_OVERRIDE;
396 * Returns an ImageContainer for this image if the image type
397 * supports it (TYPE_RASTER only).
399 virtual already_AddRefed<ImageContainer> GetContainer(LayerManager* aManager,
400 nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE;
402 gfxRect GetDestRect();
404 virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
405 LayerManager* aManager,
406 const ContainerLayerParameters& aParameters) MOZ_OVERRIDE;
407 nsRect GetBounds(bool* aSnap)
409 *aSnap = true;
411 nsImageFrame* imageFrame = static_cast<nsImageFrame*>(mFrame);
412 return imageFrame->GetInnerArea() + ToReferenceFrame();
415 virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder,
416 bool* aSnap) MOZ_OVERRIDE
418 return GetBounds(aSnap);
421 virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
422 bool* aSnap) MOZ_OVERRIDE;
424 virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
425 LayerManager* aManager,
426 const ContainerLayerParameters& aContainerParameters) MOZ_OVERRIDE;
429 * Configure an ImageLayer for this display item.
430 * Set the required filter and scaling transform.
432 virtual void ConfigureLayer(ImageLayer* aLayer, const nsIntPoint& aOffset) MOZ_OVERRIDE;
434 NS_DISPLAY_DECL_NAME("Image", TYPE_IMAGE)
435 private:
436 nsCOMPtr<imgIContainer> mImage;
439 #endif /* nsImageFrame_h___ */