Wed, 31 Dec 2014 06:09:35 +0100
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___ */