1 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* ***** BEGIN LICENSE BLOCK *****
3 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 : *
5 : * The contents of this file are subject to the Mozilla Public License Version
6 : * 1.1 (the "License"); you may not use this file except in compliance with
7 : * the License. You may obtain a copy of the License at
8 : * http://www.mozilla.org/MPL/
9 : *
10 : * Software distributed under the License is distributed on an "AS IS" basis,
11 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 : * for the specific language governing rights and limitations under the
13 : * License.
14 : *
15 : * The Original Code is Mozilla.org code.
16 : *
17 : * The Initial Developer of the Original Code is
18 : * Boris Zbarsky <bzbarsky@mit.edu>.
19 : * Portions created by the Initial Developer are Copyright (C) 2002
20 : * the Initial Developer. All Rights Reserved.
21 : *
22 : * Contributor(s):
23 : * Boris Zbarsky <bzbarsky@mit.edu> (original author)
24 : * L. David Baron <dbaron@dbaron.org>, Mozilla Corporation
25 : * Mats Palmgren <matspal@gmail.com>
26 : *
27 : * Alternatively, the contents of this file may be used under the terms of
28 : * either of the GNU General Public License Version 2 or later (the "GPL"),
29 : * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
30 : * in which case the provisions of the GPL or the LGPL are applicable instead
31 : * of those above. If you wish to allow use of your version of this file only
32 : * under the terms of either the GPL or the LGPL, and not to allow others to
33 : * use your version of this file under the terms of the MPL, indicate your
34 : * decision by deleting the provisions above and replace them with the notice
35 : * and other provisions required by the GPL or the LGPL. If you do not delete
36 : * the provisions above, a recipient may use your version of this file under
37 : * the terms of any one of the MPL, the GPL or the LGPL.
38 : *
39 : * ***** END LICENSE BLOCK ***** */
40 :
41 : #ifndef nsLayoutUtils_h__
42 : #define nsLayoutUtils_h__
43 :
44 : class nsIFormControlFrame;
45 : class nsPresContext;
46 : class nsIContent;
47 : class nsIAtom;
48 : class nsIScrollableFrame;
49 : class nsIDOMEvent;
50 : class nsRegion;
51 : class nsDisplayListBuilder;
52 : class nsDisplayItem;
53 : class nsFontMetrics;
54 : class nsClientRectList;
55 : class nsFontFaceList;
56 :
57 : #include "prtypes.h"
58 : #include "nsStyleContext.h"
59 : #include "nsAutoPtr.h"
60 : #include "nsStyleSet.h"
61 : #include "nsIView.h"
62 : #include "nsIFrame.h"
63 : #include "nsThreadUtils.h"
64 : #include "nsIPresShell.h"
65 : #include "nsIPrincipal.h"
66 : #include "gfxPattern.h"
67 : #include "imgIContainer.h"
68 : #include "nsCSSPseudoElements.h"
69 : #include "nsHTMLReflowState.h"
70 : #include "nsIFrameLoader.h"
71 : #include "Layers.h"
72 :
73 : class nsBlockFrame;
74 : class gfxDrawable;
75 :
76 : namespace mozilla {
77 : namespace dom {
78 : class Element;
79 : } // namespace dom
80 : } // namespace mozilla
81 :
82 : /**
83 : * nsLayoutUtils is a namespace class used for various helper
84 : * functions that are useful in multiple places in layout. The goal
85 : * is not to define multiple copies of the same static helper.
86 : */
87 : class nsLayoutUtils
88 : {
89 : typedef gfxPattern::GraphicsFilter GraphicsFilter;
90 :
91 : public:
92 : typedef mozilla::layers::FrameMetrics::ViewID ViewID;
93 :
94 : /**
95 : * Finds previously assigned or generates a unique ViewID for the given
96 : * content element.
97 : */
98 : static ViewID FindIDFor(nsIContent* aContent);
99 :
100 : /**
101 : * Find content for given ID.
102 : */
103 : static nsIContent* FindContentFor(ViewID aId);
104 :
105 : /**
106 : * Get display port for the given element.
107 : */
108 : static bool GetDisplayPort(nsIContent* aContent, nsRect *aResult);
109 :
110 : /**
111 : * Use heuristics to figure out the child list that
112 : * aChildFrame is currently in.
113 : */
114 : static nsIFrame::ChildListID GetChildListNameFor(nsIFrame* aChildFrame);
115 :
116 : /**
117 : * GetBeforeFrame returns the outermost :before frame of the given frame, if
118 : * one exists. This is typically O(1). The frame passed in must be
119 : * the first-in-flow.
120 : *
121 : * @param aFrame the frame whose :before is wanted
122 : * @return the :before frame or nsnull if there isn't one
123 : */
124 : static nsIFrame* GetBeforeFrame(nsIFrame* aFrame);
125 :
126 : /**
127 : * GetAfterFrame returns the outermost :after frame of the given frame, if one
128 : * exists. This will walk the in-flow chain to the last-in-flow if
129 : * needed. This function is typically O(N) in the number of child
130 : * frames, following in-flows, etc.
131 : *
132 : * @param aFrame the frame whose :after is wanted
133 : * @return the :after frame or nsnull if there isn't one
134 : */
135 : static nsIFrame* GetAfterFrame(nsIFrame* aFrame);
136 :
137 : /**
138 : * Given a frame, search up the frame tree until we find an
139 : * ancestor that (or the frame itself) is of type aFrameType, if any.
140 : *
141 : * @param aFrame the frame to start at
142 : * @param aFrameType the frame type to look for
143 : * @return a frame of the given type or nsnull if no
144 : * such ancestor exists
145 : */
146 : static nsIFrame* GetClosestFrameOfType(nsIFrame* aFrame, nsIAtom* aFrameType);
147 :
148 : /**
149 : * Given a frame, search up the frame tree until we find an
150 : * ancestor that (or the frame itself) is a "Page" frame, if any.
151 : *
152 : * @param aFrame the frame to start at
153 : * @return a frame of type nsGkAtoms::pageFrame or nsnull if no
154 : * such ancestor exists
155 : */
156 : static nsIFrame* GetPageFrame(nsIFrame* aFrame)
157 : {
158 : return GetClosestFrameOfType(aFrame, nsGkAtoms::pageFrame);
159 : }
160 :
161 : /**
162 : * Given a frame which is the primary frame for an element,
163 : * return the frame that has the non-psuedoelement style context for
164 : * the content.
165 : * This is aPrimaryFrame itself except for tableOuter frames.
166 : */
167 : static nsIFrame* GetStyleFrame(nsIFrame* aPrimaryFrame);
168 :
169 : /**
170 : * IsGeneratedContentFor returns true if aFrame is the outermost
171 : * frame for generated content of type aPseudoElement for aContent.
172 : * aFrame *might not* have the aPseudoElement pseudo-style! For example
173 : * it might be a table outer frame and the inner table frame might
174 : * have the pseudo-style.
175 : *
176 : * @param aContent the content node we're looking at. If this is
177 : * null, then we just assume that aFrame has the right content
178 : * pointer.
179 : * @param aFrame the frame we're looking at
180 : * @param aPseudoElement the pseudo type we're interested in
181 : * @return whether aFrame is the generated aPseudoElement frame for aContent
182 : */
183 : static bool IsGeneratedContentFor(nsIContent* aContent, nsIFrame* aFrame,
184 : nsIAtom* aPseudoElement);
185 :
186 : #ifdef DEBUG
187 : // TODO: remove, see bug 598468.
188 : static bool gPreventAssertInCompareTreePosition;
189 : #endif // DEBUG
190 :
191 : /**
192 : * CompareTreePosition determines whether aContent1 comes before or
193 : * after aContent2 in a preorder traversal of the content tree.
194 : *
195 : * @param aCommonAncestor either null, or a common ancestor of
196 : * aContent1 and aContent2. Actually this is
197 : * only a hint; if it's not an ancestor of
198 : * aContent1 or aContent2, this function will
199 : * still work, but it will be slower than
200 : * normal.
201 : * @return < 0 if aContent1 is before aContent2
202 : * > 0 if aContent1 is after aContent2,
203 : * 0 otherwise (meaning they're the same, or they're in
204 : * different documents)
205 : */
206 0 : static PRInt32 CompareTreePosition(nsIContent* aContent1,
207 : nsIContent* aContent2,
208 : const nsIContent* aCommonAncestor = nsnull)
209 : {
210 0 : return DoCompareTreePosition(aContent1, aContent2, -1, 1, aCommonAncestor);
211 : }
212 :
213 : /*
214 : * More generic version of |CompareTreePosition|. |aIf1Ancestor|
215 : * gives the value to return when 1 is an ancestor of 2, and likewise
216 : * for |aIf2Ancestor|. Passing (-1, 1) gives preorder traversal
217 : * order, and (1, -1) gives postorder traversal order.
218 : */
219 : static PRInt32 DoCompareTreePosition(nsIContent* aContent1,
220 : nsIContent* aContent2,
221 : PRInt32 aIf1Ancestor,
222 : PRInt32 aIf2Ancestor,
223 : const nsIContent* aCommonAncestor = nsnull);
224 :
225 : /**
226 : * CompareTreePosition determines whether aFrame1 comes before or
227 : * after aFrame2 in a preorder traversal of the frame tree, where out
228 : * of flow frames are treated as children of their placeholders. This is
229 : * basically the same ordering as DoCompareTreePosition(nsIContent*) except
230 : * that it handles anonymous content properly and there are subtleties with
231 : * continuations.
232 : *
233 : * @param aCommonAncestor either null, or a common ancestor of
234 : * aContent1 and aContent2. Actually this is
235 : * only a hint; if it's not an ancestor of
236 : * aContent1 or aContent2, this function will
237 : * still work, but it will be slower than
238 : * normal.
239 : * @return < 0 if aContent1 is before aContent2
240 : * > 0 if aContent1 is after aContent2,
241 : * 0 otherwise (meaning they're the same, or they're in
242 : * different frame trees)
243 : */
244 : static PRInt32 CompareTreePosition(nsIFrame* aFrame1,
245 : nsIFrame* aFrame2,
246 : nsIFrame* aCommonAncestor = nsnull)
247 : {
248 : return DoCompareTreePosition(aFrame1, aFrame2, -1, 1, aCommonAncestor);
249 : }
250 :
251 : /*
252 : * More generic version of |CompareTreePosition|. |aIf1Ancestor|
253 : * gives the value to return when 1 is an ancestor of 2, and likewise
254 : * for |aIf2Ancestor|. Passing (-1, 1) gives preorder traversal
255 : * order, and (1, -1) gives postorder traversal order.
256 : */
257 : static PRInt32 DoCompareTreePosition(nsIFrame* aFrame1,
258 : nsIFrame* aFrame2,
259 : PRInt32 aIf1Ancestor,
260 : PRInt32 aIf2Ancestor,
261 : nsIFrame* aCommonAncestor = nsnull);
262 :
263 : /**
264 : * GetLastContinuationWithChild gets the last continuation in aFrame's chain
265 : * that has a child, or the first continuation if the frame has no children.
266 : */
267 : static nsIFrame* GetLastContinuationWithChild(nsIFrame* aFrame);
268 :
269 : /**
270 : * GetLastSibling simply finds the last sibling of aFrame, or returns nsnull if
271 : * aFrame is null.
272 : */
273 : static nsIFrame* GetLastSibling(nsIFrame* aFrame);
274 :
275 : /**
276 : * FindSiblingViewFor locates the child of aParentView that aFrame's
277 : * view should be inserted 'above' (i.e., before in sibling view
278 : * order). This is the first child view of aParentView whose
279 : * corresponding content is before aFrame's content (view siblings
280 : * are in reverse content order).
281 : */
282 : static nsIView* FindSiblingViewFor(nsIView* aParentView, nsIFrame* aFrame);
283 :
284 : /**
285 : * Get the parent of aFrame. If aFrame is the root frame for a document,
286 : * and the document has a parent document in the same view hierarchy, then
287 : * we try to return the subdocumentframe in the parent document.
288 : * @param aExtraOffset [in/out] if non-null, then as we cross documents
289 : * an extra offset may be required and it will be added to aCrossDocOffset.
290 : * Be careful dealing with this extra offset as it is in app units of the
291 : * parent document, which may have a different app units per dev pixel ratio
292 : * than the child document.
293 : */
294 : static nsIFrame* GetCrossDocParentFrame(const nsIFrame* aFrame,
295 : nsPoint* aCrossDocOffset = nsnull);
296 :
297 : /**
298 : * IsProperAncestorFrame checks whether aAncestorFrame is an ancestor
299 : * of aFrame and not equal to aFrame.
300 : * @param aCommonAncestor nsnull, or a common ancestor of aFrame and
301 : * aAncestorFrame. If non-null, this can bound the search and speed up
302 : * the function
303 : */
304 : static bool IsProperAncestorFrame(nsIFrame* aAncestorFrame, nsIFrame* aFrame,
305 : nsIFrame* aCommonAncestor = nsnull);
306 :
307 : /**
308 : * Like IsProperAncestorFrame, but looks across document boundaries.
309 : *
310 : * Just like IsAncestorFrameCrossDoc, except that it returns false when
311 : * aFrame == aAncestorFrame.
312 : */
313 : static bool IsProperAncestorFrameCrossDoc(nsIFrame* aAncestorFrame, nsIFrame* aFrame,
314 : nsIFrame* aCommonAncestor = nsnull);
315 :
316 : /**
317 : * IsAncestorFrameCrossDoc checks whether aAncestorFrame is an ancestor
318 : * of aFrame or equal to aFrame, looking across document boundaries.
319 : * @param aCommonAncestor nsnull, or a common ancestor of aFrame and
320 : * aAncestorFrame. If non-null, this can bound the search and speed up
321 : * the function.
322 : *
323 : * Just like IsProperAncestorFrameCrossDoc, except that it returns true when
324 : * aFrame == aAncestorFrame.
325 : */
326 : static bool IsAncestorFrameCrossDoc(nsIFrame* aAncestorFrame, nsIFrame* aFrame,
327 : nsIFrame* aCommonAncestor = nsnull);
328 :
329 : /**
330 : * Finds the nearest ancestor frame that is the root of an "actively
331 : * scrolled" frame subtree, or aStopAtAncestor if there is no
332 : * such ancestor before we reach aStopAtAncestor in the ancestor chain.
333 : * We expect frames with the same "active scrolled root" to be
334 : * scrolled together, so we'll place them in the same ThebesLayer.
335 : */
336 : static nsIFrame* GetActiveScrolledRootFor(nsIFrame* aFrame,
337 : nsIFrame* aStopAtAncestor);
338 :
339 : static nsIFrame* GetActiveScrolledRootFor(nsDisplayItem* aItem,
340 : nsDisplayListBuilder* aBuilder,
341 : bool* aShouldFixToViewport = nsnull);
342 :
343 : static bool ScrolledByViewportScrolling(nsIFrame* aActiveScrolledRoot,
344 : nsDisplayListBuilder* aBuilder);
345 :
346 : /**
347 : * GetScrollableFrameFor returns the scrollable frame for a scrolled frame
348 : */
349 : static nsIScrollableFrame* GetScrollableFrameFor(nsIFrame *aScrolledFrame);
350 :
351 : /**
352 : * GetNearestScrollableFrameForDirection locates the first ancestor of
353 : * aFrame (or aFrame itself) that is scrollable with overflow:scroll or
354 : * overflow:auto in the given direction and where either the scrollbar for
355 : * that direction is visible or the frame can be scrolled by some
356 : * positive amount in that direction.
357 : * The search extends across document boundaries.
358 : *
359 : * @param aFrame the frame to start with
360 : * @param aDirection Whether it's for horizontal or vertical scrolling.
361 : * @return the nearest scrollable frame or nsnull if not found
362 : */
363 : enum Direction { eHorizontal, eVertical };
364 : static nsIScrollableFrame* GetNearestScrollableFrameForDirection(nsIFrame* aFrame,
365 : Direction aDirection);
366 :
367 : /**
368 : * GetNearestScrollableFrame locates the first ancestor of aFrame
369 : * (or aFrame itself) that is scrollable with overflow:scroll or
370 : * overflow:auto in some direction.
371 : * The search extends across document boundaries.
372 : *
373 : * @param aFrame the frame to start with
374 : * @return the nearest scrollable frame or nsnull if not found
375 : */
376 : static nsIScrollableFrame* GetNearestScrollableFrame(nsIFrame* aFrame);
377 :
378 : /**
379 : * HasPseudoStyle returns true if aContent (whose primary style
380 : * context is aStyleContext) has the aPseudoElement pseudo-style
381 : * attached to it; returns false otherwise.
382 : *
383 : * @param aContent the content node we're looking at
384 : * @param aStyleContext aContent's style context
385 : * @param aPseudoElement the id of the pseudo style we care about
386 : * @param aPresContext the presentation context
387 : * @return whether aContent has aPseudoElement style attached to it
388 : */
389 : static bool HasPseudoStyle(nsIContent* aContent,
390 : nsStyleContext* aStyleContext,
391 : nsCSSPseudoElements::Type aPseudoElement,
392 : nsPresContext* aPresContext);
393 :
394 : /**
395 : * If this frame is a placeholder for a float, then return the float,
396 : * otherwise return nsnull. aPlaceholder must be a placeholder frame.
397 : */
398 : static nsIFrame* GetFloatFromPlaceholder(nsIFrame* aPlaceholder);
399 :
400 : // Combine aNewBreakType with aOrigBreakType, but limit the break types
401 : // to NS_STYLE_CLEAR_LEFT, RIGHT, LEFT_AND_RIGHT.
402 : static PRUint8 CombineBreakType(PRUint8 aOrigBreakType, PRUint8 aNewBreakType);
403 :
404 : /**
405 : * Get the coordinates of a given DOM mouse event, relative to a given
406 : * frame. Works only for DOM events generated by nsGUIEvents.
407 : * @param aDOMEvent the event
408 : * @param aFrame the frame to make coordinates relative to
409 : * @return the point, or (NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE) if
410 : * for some reason the coordinates for the mouse are not known (e.g.,
411 : * the event is not a GUI event).
412 : */
413 : static nsPoint GetDOMEventCoordinatesRelativeTo(nsIDOMEvent* aDOMEvent,
414 : nsIFrame* aFrame);
415 :
416 : /**
417 : * Get the coordinates of a given native mouse event, relative to a given
418 : * frame.
419 : * @param aEvent the event
420 : * @param aFrame the frame to make coordinates relative to
421 : * @return the point, or (NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE) if
422 : * for some reason the coordinates for the mouse are not known (e.g.,
423 : * the event is not a GUI event).
424 : */
425 : static nsPoint GetEventCoordinatesRelativeTo(const nsEvent* aEvent,
426 : nsIFrame* aFrame);
427 :
428 : /**
429 : * Get the coordinates of a given point relative to an event and a
430 : * given frame.
431 : * @param aEvent the event
432 : * @param aPoint the point to get the coordinates relative to
433 : * @param aFrame the frame to make coordinates relative to
434 : * @return the point, or (NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE) if
435 : * for some reason the coordinates for the mouse are not known (e.g.,
436 : * the event is not a GUI event).
437 : */
438 : static nsPoint GetEventCoordinatesRelativeTo(const nsEvent* aEvent,
439 : const nsIntPoint aPoint,
440 : nsIFrame* aFrame);
441 :
442 : /**
443 : * Get the popup frame of a given native mouse event.
444 : * @param aPresContext only check popups within aPresContext or a descendant
445 : * @param aEvent the event.
446 : * @return Null, if there is no popup frame at the point, otherwise,
447 : * returns top-most popup frame at the point.
448 : */
449 : static nsIFrame* GetPopupFrameForEventCoordinates(nsPresContext* aPresContext,
450 : const nsEvent* aEvent);
451 :
452 : /**
453 : * Translate from widget coordinates to the view's coordinates
454 : * @param aPresContext the PresContext for the view
455 : * @param aWidget the widget
456 : * @param aPt the point relative to the widget
457 : * @param aView view to which returned coordinates are relative
458 : * @return the point in the view's coordinates
459 : */
460 : static nsPoint TranslateWidgetToView(nsPresContext* aPresContext,
461 : nsIWidget* aWidget, nsIntPoint aPt,
462 : nsIView* aView);
463 :
464 : /**
465 : * Given a matrix and a point, let T be the transformation matrix translating points
466 : * in the coordinate space with origin aOrigin to the coordinate space used by the
467 : * matrix. If M is the stored matrix, this function returns (T-1)MT, the matrix
468 : * that's equivalent to aMatrix but in the coordinate space that treats aOrigin
469 : * as the origin.
470 : *
471 : * @param aOrigin The origin to translate to.
472 : * @param aMatrix The matrix to change the basis of.
473 : * @return A matrix equivalent to aMatrix, but operating in the coordinate system with
474 : * origin aOrigin.
475 : */
476 : static gfx3DMatrix ChangeMatrixBasis(const gfxPoint3D &aOrigin, const gfx3DMatrix &aMatrix);
477 :
478 : /**
479 : * Find IDs corresponding to a scrollable content element in the child process.
480 : * In correspondence with the shadow layer tree, you can use this to perform a
481 : * hit test that corresponds to a specific shadow layer that you can then perform
482 : * transformations on to do parent-side scrolling.
483 : *
484 : * @param aFrame The root frame of a stack context
485 : * @param aTarget The rect to hit test relative to the frame origin
486 : * @param aOutIDs All found IDs are added here
487 : * @param aIgnoreRootScrollFrame a boolean to control if the display list
488 : * builder should ignore the root scroll frame
489 : */
490 : static nsresult GetRemoteContentIds(nsIFrame* aFrame,
491 : const nsRect& aTarget,
492 : nsTArray<ViewID> &aOutIDs,
493 : bool aIgnoreRootScrollFrame);
494 :
495 : /**
496 : * Given aFrame, the root frame of a stacking context, find its descendant
497 : * frame under the point aPt that receives a mouse event at that location,
498 : * or nsnull if there is no such frame.
499 : * @param aPt the point, relative to the frame origin
500 : * @param aShouldIgnoreSuppression a boolean to control if the display
501 : * list builder should ignore paint suppression or not
502 : * @param aIgnoreRootScrollFrame whether or not the display list builder
503 : * should ignore the root scroll frame.
504 : */
505 : static nsIFrame* GetFrameForPoint(nsIFrame* aFrame, nsPoint aPt,
506 : bool aShouldIgnoreSuppression = false,
507 : bool aIgnoreRootScrollFrame = false);
508 :
509 : /**
510 : * Given aFrame, the root frame of a stacking context, find all descendant
511 : * frames under the area of a rectangle that receives a mouse event,
512 : * or nsnull if there is no such frame.
513 : * @param aRect the rect, relative to the frame origin
514 : * @param aOutFrames an array to add all the frames found
515 : * @param aShouldIgnoreSuppression a boolean to control if the display
516 : * list builder should ignore paint suppression or not
517 : * @param aIgnoreRootScrollFrame whether or not the display list builder
518 : * should ignore the root scroll frame.
519 : */
520 : static nsresult GetFramesForArea(nsIFrame* aFrame, const nsRect& aRect,
521 : nsTArray<nsIFrame*> &aOutFrames,
522 : bool aShouldIgnoreSuppression = false,
523 : bool aIgnoreRootScrollFrame = false);
524 :
525 : /**
526 : * Transform aRect relative to aAncestor down to the coordinate system of
527 : * aFrame. Computes the bounding-box of the true quadrilateral.
528 : */
529 : static nsRect TransformAncestorRectToFrame(nsIFrame* aFrame,
530 : const nsRect& aRect,
531 : nsIFrame* aAncestor);
532 :
533 : /**
534 : * Transform aRect relative to aFrame up to the coordinate system of
535 : * aAncestor. Computes the bounding-box of the true quadrilateral.
536 : */
537 : static nsRect TransformFrameRectToAncestor(nsIFrame* aFrame,
538 : const nsRect& aRect,
539 : nsIFrame* aAncestor);
540 :
541 :
542 : /**
543 : * Gets the transform for aFrame relative to aAncestor. Pass null for aAncestor
544 : * to go up to the root frame.
545 : */
546 : static gfx3DMatrix GetTransformToAncestor(nsIFrame *aFrame, nsIFrame *aAncestor);
547 :
548 : /**
549 : * Given a point in the global coordinate space, returns that point expressed
550 : * in the coordinate system of aFrame. This effectively inverts all transforms
551 : * between this point and the root frame.
552 : *
553 : * @param aFrame The frame that acts as the coordinate space container.
554 : * @param aPoint The point, in the global space, to get in the frame-local space.
555 : * @return aPoint, expressed in aFrame's canonical coordinate space.
556 : */
557 : static nsPoint TransformRootPointToFrame(nsIFrame* aFrame,
558 : const nsPoint &aPt);
559 :
560 : /**
561 : * Helper function that, given a rectangle and a matrix, returns the smallest
562 : * rectangle containing the image of the source rectangle.
563 : *
564 : * @param aBounds The rectangle to transform.
565 : * @param aMatrix The matrix to transform it with.
566 : * @param aFactor The number of app units per graphics unit.
567 : * @return The smallest rect that contains the image of aBounds.
568 : */
569 : static nsRect MatrixTransformRect(const nsRect &aBounds,
570 : const gfx3DMatrix &aMatrix, float aFactor);
571 :
572 : /**
573 : * Helper function that, given a rectangle and a matrix, returns the smallest
574 : * rectangle containing the image of the source rectangle rounded out to the nearest
575 : * pixel value.
576 : *
577 : * @param aBounds The rectangle to transform.
578 : * @param aMatrix The matrix to transform it with.
579 : * @param aFactor The number of app units per graphics unit.
580 : * @return The smallest rect that contains the image of aBounds.
581 : */
582 : static nsRect MatrixTransformRectOut(const nsRect &aBounds,
583 : const gfx3DMatrix &aMatrix, float aFactor);
584 : /**
585 : * Helper function that, given a point and a matrix, returns the image
586 : * of that point under the matrix transform.
587 : *
588 : * @param aPoint The point to transform.
589 : * @param aMatrix The matrix to transform it with.
590 : * @param aFactor The number of app units per graphics unit.
591 : * @return The image of the point under the transform.
592 : */
593 : static nsPoint MatrixTransformPoint(const nsPoint &aPoint,
594 : const gfx3DMatrix &aMatrix, float aFactor);
595 :
596 : /**
597 : * Given a graphics rectangle in graphics space, return a rectangle in
598 : * app space that contains the graphics rectangle, rounding out as necessary.
599 : *
600 : * @param aRect The graphics rect to round outward.
601 : * @param aFactor The number of app units per graphics unit.
602 : * @return The smallest rectangle in app space that contains aRect.
603 : */
604 : static nsRect RoundGfxRectToAppRect(const gfxRect &aRect, float aFactor);
605 :
606 : /**
607 : * Returns a subrectangle of aContainedRect that is entirely inside the rounded
608 : * rect. Complex cases are handled conservatively by returning a smaller
609 : * rect than necessary.
610 : */
611 : static nsRegion RoundedRectIntersectRect(const nsRect& aRoundedRect,
612 : const nscoord aRadii[8],
613 : const nsRect& aContainedRect);
614 :
615 : enum {
616 : PAINT_IN_TRANSFORM = 0x01,
617 : PAINT_SYNC_DECODE_IMAGES = 0x02,
618 : PAINT_WIDGET_LAYERS = 0x04,
619 : PAINT_IGNORE_SUPPRESSION = 0x08,
620 : PAINT_DOCUMENT_RELATIVE = 0x10,
621 : PAINT_HIDE_CARET = 0x20,
622 : PAINT_ALL_CONTINUATIONS = 0x40,
623 : PAINT_TO_WINDOW = 0x80,
624 : PAINT_EXISTING_TRANSACTION = 0x100
625 : };
626 :
627 : /**
628 : * Given aFrame, the root frame of a stacking context, paint it and its
629 : * descendants to aRenderingContext.
630 : * @param aRenderingContext a rendering context translated so that (0,0)
631 : * is the origin of aFrame; for best results, (0,0) should transform
632 : * to pixel-aligned coordinates. This can be null, in which case
633 : * aFrame must be a "display root" (root frame for a root document,
634 : * or the root of a popup) with an associated widget and we draw using
635 : * the layer manager for the frame's widget.
636 : * @param aDirtyRegion the region that must be painted, in the coordinates
637 : * of aFrame
638 : * @param aBackstop paint the dirty area with this color before drawing
639 : * the actual content; pass NS_RGBA(0,0,0,0) to draw no background
640 : * @param aFlags if PAINT_IN_TRANSFORM is set, then we assume
641 : * this is inside a transform or SVG foreignObject. If
642 : * PAINT_SYNC_DECODE_IMAGES is set, we force synchronous decode on all
643 : * images. If PAINT_WIDGET_LAYERS is set, aFrame must be a display root,
644 : * and we will use the frame's widget's layer manager to paint
645 : * even if aRenderingContext is non-null. This is useful if you want
646 : * to force rendering to use the widget's layer manager for testing
647 : * or speed. PAINT_WIDGET_LAYERS must be set if aRenderingContext is null.
648 : * If PAINT_DOCUMENT_RELATIVE is used, the visible region is interpreted
649 : * as being relative to the document. (Normally it's relative to the CSS
650 : * viewport.) PAINT_TO_WINDOW sets painting to window to true on the display
651 : * list builder even if we can't tell that we are painting to the window.
652 : * If PAINT_EXISTING_TRANSACTION is set, then BeginTransaction() has already
653 : * been called on aFrame's widget's layer manager and should not be
654 : * called again.
655 : *
656 : * So there are three possible behaviours:
657 : * 1) PAINT_WIDGET_LAYERS is set and aRenderingContext is null; we paint
658 : * by calling BeginTransaction on the widget's layer manager
659 : * 2) PAINT_WIDGET_LAYERS is set and aRenderingContext is non-null; we
660 : * paint by calling BeginTransactionWithTarget on the widget's layer
661 : * maanger
662 : * 3) PAINT_WIDGET_LAYERS is not set and aRenderingContext is non-null;
663 : * we paint by construct a BasicLayerManager and calling
664 : * BeginTransactionWithTarget on it. This is desirable if we're doing
665 : * something like drawWindow in a mode where what gets rendered doesn't
666 : * necessarily correspond to what's visible in the window; we don't
667 : * want to mess up the widget's layer tree.
668 : */
669 : static nsresult PaintFrame(nsRenderingContext* aRenderingContext, nsIFrame* aFrame,
670 : const nsRegion& aDirtyRegion, nscolor aBackstop,
671 : PRUint32 aFlags = 0);
672 :
673 : /**
674 : * Compute the used z-index of aFrame; returns zero for elements to which
675 : * z-index does not apply, and for z-index:auto
676 : */
677 : static PRInt32 GetZIndex(nsIFrame* aFrame);
678 :
679 : /**
680 : * Uses a binary search for find where the cursor falls in the line of text
681 : * It also keeps track of the part of the string that has already been measured
682 : * so it doesn't have to keep measuring the same text over and over
683 : *
684 : * @param "aBaseWidth" contains the width in twips of the portion
685 : * of the text that has already been measured, and aBaseInx contains
686 : * the index of the text that has already been measured.
687 : *
688 : * @param aTextWidth returns the (in twips) the length of the text that falls
689 : * before the cursor aIndex contains the index of the text where the cursor falls
690 : */
691 : static bool
692 : BinarySearchForPosition(nsRenderingContext* acx,
693 : const PRUnichar* aText,
694 : PRInt32 aBaseWidth,
695 : PRInt32 aBaseInx,
696 : PRInt32 aStartInx,
697 : PRInt32 aEndInx,
698 : PRInt32 aCursorPos,
699 : PRInt32& aIndex,
700 : PRInt32& aTextWidth);
701 :
702 : class BoxCallback {
703 : public:
704 : virtual void AddBox(nsIFrame* aFrame) = 0;
705 : };
706 : /**
707 : * Collect all CSS boxes associated with aFrame and its
708 : * continuations, "drilling down" through outer table frames and
709 : * some anonymous blocks since they're not real CSS boxes.
710 : * If aFrame is null, no boxes are returned.
711 : * SVG frames return a single box, themselves.
712 : */
713 : static void GetAllInFlowBoxes(nsIFrame* aFrame, BoxCallback* aCallback);
714 :
715 : class RectCallback {
716 : public:
717 : virtual void AddRect(const nsRect& aRect) = 0;
718 : };
719 :
720 0 : struct RectAccumulator : public RectCallback {
721 : nsRect mResultRect;
722 : nsRect mFirstRect;
723 : bool mSeenFirstRect;
724 :
725 : RectAccumulator();
726 :
727 : virtual void AddRect(const nsRect& aRect);
728 : };
729 :
730 : struct RectListBuilder : public RectCallback {
731 : nsClientRectList* mRectList;
732 : nsresult mRV;
733 :
734 : RectListBuilder(nsClientRectList* aList);
735 : virtual void AddRect(const nsRect& aRect);
736 : };
737 :
738 : static nsIFrame* GetContainingBlockForClientRect(nsIFrame* aFrame);
739 :
740 : enum {
741 : RECTS_ACCOUNT_FOR_TRANSFORMS = 0x01
742 : };
743 : /**
744 : * Collect all CSS border-boxes associated with aFrame and its
745 : * continuations, "drilling down" through outer table frames and
746 : * some anonymous blocks since they're not real CSS boxes.
747 : * The boxes are positioned relative to aRelativeTo (taking scrolling
748 : * into account) and passed to the callback in frame-tree order.
749 : * If aFrame is null, no boxes are returned.
750 : * For SVG frames, returns one rectangle, the bounding box.
751 : * If aFlags includes RECTS_ACCOUNT_FOR_TRANSFORMS, then when converting
752 : * the boxes into aRelativeTo coordinates, transforms (including CSS
753 : * and SVG transforms) are taken into account.
754 : */
755 : static void GetAllInFlowRects(nsIFrame* aFrame, nsIFrame* aRelativeTo,
756 : RectCallback* aCallback, PRUint32 aFlags = 0);
757 :
758 : /**
759 : * Computes the union of all rects returned by GetAllInFlowRects. If
760 : * the union is empty, returns the first rect.
761 : * If aFlags includes RECTS_ACCOUNT_FOR_TRANSFORMS, then when converting
762 : * the boxes into aRelativeTo coordinates, transforms (including CSS
763 : * and SVG transforms) are taken into account.
764 : */
765 : static nsRect GetAllInFlowRectsUnion(nsIFrame* aFrame, nsIFrame* aRelativeTo,
766 : PRUint32 aFlags = 0);
767 :
768 : enum {
769 : EXCLUDE_BLUR_SHADOWS = 0x01
770 : };
771 : /**
772 : * Takes a text-shadow array from the style properties of a given nsIFrame and
773 : * computes the union of those shadows along with the given initial rect.
774 : * If there are no shadows, the initial rect is returned.
775 : */
776 : static nsRect GetTextShadowRectsUnion(const nsRect& aTextAndDecorationsRect,
777 : nsIFrame* aFrame,
778 : PRUint32 aFlags = 0);
779 :
780 : /**
781 : * Get the font metrics corresponding to the frame's style data.
782 : * @param aFrame the frame
783 : * @param aFontMetrics the font metrics result
784 : * @param aSizeInflation number to multiply font size by
785 : * @return success or failure code
786 : */
787 : static nsresult GetFontMetricsForFrame(const nsIFrame* aFrame,
788 : nsFontMetrics** aFontMetrics,
789 : float aSizeInflation = 1.0f);
790 :
791 : /**
792 : * Get the font metrics corresponding to the given style data.
793 : * @param aStyleContext the style data
794 : * @param aFontMetrics the font metrics result
795 : * @param aSizeInflation number to multiply font size by
796 : * @return success or failure code
797 : */
798 : static nsresult GetFontMetricsForStyleContext(nsStyleContext* aStyleContext,
799 : nsFontMetrics** aFontMetrics,
800 : float aSizeInflation = 1.0f);
801 :
802 : /**
803 : * Find the immediate child of aParent whose frame subtree contains
804 : * aDescendantFrame. Returns null if aDescendantFrame is not a descendant
805 : * of aParent.
806 : */
807 : static nsIFrame* FindChildContainingDescendant(nsIFrame* aParent, nsIFrame* aDescendantFrame);
808 :
809 : /**
810 : * Find the nearest ancestor that's a block
811 : */
812 : static nsBlockFrame* FindNearestBlockAncestor(nsIFrame* aFrame);
813 :
814 : /**
815 : * Find the nearest ancestor that's not for generated content. Will return
816 : * aFrame if aFrame is not for generated content.
817 : */
818 : static nsIFrame* GetNonGeneratedAncestor(nsIFrame* aFrame);
819 :
820 : /**
821 : * Cast aFrame to an nsBlockFrame* or return null if it's not
822 : * an nsBlockFrame.
823 : */
824 : static nsBlockFrame* GetAsBlock(nsIFrame* aFrame);
825 :
826 : /*
827 : * Whether the frame is an nsBlockFrame which is not a wrapper block.
828 : */
829 : static bool IsNonWrapperBlock(nsIFrame* aFrame) {
830 : return GetAsBlock(aFrame) && !aFrame->IsBlockWrapper();
831 : }
832 :
833 : /**
834 : * If aFrame is an out of flow frame, return its placeholder, otherwise
835 : * return its parent.
836 : */
837 : static nsIFrame* GetParentOrPlaceholderFor(nsFrameManager* aFrameManager,
838 : nsIFrame* aFrame);
839 :
840 : /**
841 : * Get a frame's next-in-flow, or, if it doesn't have one, its special sibling.
842 : */
843 : static nsIFrame*
844 : GetNextContinuationOrSpecialSibling(nsIFrame *aFrame);
845 :
846 : /**
847 : * Get the first frame in the continuation-plus-special-sibling chain
848 : * containing aFrame.
849 : */
850 : static nsIFrame*
851 : GetFirstContinuationOrSpecialSibling(nsIFrame *aFrame);
852 :
853 : /**
854 : * Check whether aFrame is a part of the scrollbar or scrollcorner of
855 : * the root content.
856 : * @param aFrame the checking frame
857 : * @return if TRUE, the frame is a part of the scrollbar or scrollcorner of
858 : * the root content.
859 : */
860 : static bool IsViewportScrollbarFrame(nsIFrame* aFrame);
861 :
862 : /**
863 : * Get the contribution of aFrame to its containing block's intrinsic
864 : * width. This considers the child's intrinsic width, its 'width',
865 : * 'min-width', and 'max-width' properties, and its padding, border,
866 : * and margin.
867 : */
868 : enum IntrinsicWidthType { MIN_WIDTH, PREF_WIDTH };
869 : static nscoord IntrinsicForContainer(nsRenderingContext* aRenderingContext,
870 : nsIFrame* aFrame,
871 : IntrinsicWidthType aType);
872 :
873 : /*
874 : * Convert nsStyleCoord to nscoord when percentages depend on the
875 : * containing block width.
876 : */
877 : static nscoord ComputeWidthDependentValue(
878 : nscoord aContainingBlockWidth,
879 : const nsStyleCoord& aCoord);
880 :
881 : /*
882 : * Convert nsStyleCoord to nscoord when percentages depend on the
883 : * containing block width, and enumerated values are for width,
884 : * min-width, or max-width. Returns the content-box width value based
885 : * on aContentEdgeToBoxSizing and aBoxSizingToMarginEdge (which are
886 : * also used for the enumerated values for width. This function does
887 : * not handle 'auto'. It ensures that the result is nonnegative.
888 : *
889 : * @param aRenderingContext Rendering context for font measurement/metrics.
890 : * @param aFrame Frame whose (min-/max-/)width is being computed
891 : * @param aContainingBlockWidth Width of aFrame's containing block.
892 : * @param aContentEdgeToBoxSizing The sum of any left/right padding and
893 : * border that goes inside the rect chosen by -moz-box-sizing.
894 : * @param aBoxSizingToMarginEdge The sum of any left/right padding, border,
895 : * and margin that goes outside the rect chosen by -moz-box-sizing.
896 : * @param aCoord The width value to compute.
897 : */
898 : static nscoord ComputeWidthValue(
899 : nsRenderingContext* aRenderingContext,
900 : nsIFrame* aFrame,
901 : nscoord aContainingBlockWidth,
902 : nscoord aContentEdgeToBoxSizing,
903 : nscoord aBoxSizingToMarginEdge,
904 : const nsStyleCoord& aCoord);
905 :
906 : /*
907 : * Convert nsStyleCoord to nscoord when percentages depend on the
908 : * containing block height.
909 : */
910 : static nscoord ComputeHeightDependentValue(
911 : nscoord aContainingBlockHeight,
912 : const nsStyleCoord& aCoord);
913 :
914 : /*
915 : * Likewise, but for 'height', 'min-height', or 'max-height'.
916 : */
917 : static nscoord ComputeHeightValue(nscoord aContainingBlockHeight,
918 : const nsStyleCoord& aCoord)
919 : {
920 : nscoord result =
921 : ComputeHeightDependentValue(aContainingBlockHeight, aCoord);
922 : if (result < 0)
923 : result = 0; // clamp calc()
924 : return result;
925 : }
926 :
927 : static bool IsAutoHeight(const nsStyleCoord &aCoord, nscoord aCBHeight)
928 : {
929 : nsStyleUnit unit = aCoord.GetUnit();
930 : return unit == eStyleUnit_Auto || // only for 'height'
931 : unit == eStyleUnit_None || // only for 'max-height'
932 : (aCBHeight == NS_AUTOHEIGHT && aCoord.HasPercent());
933 : }
934 :
935 : static bool IsPaddingZero(const nsStyleCoord &aCoord)
936 : {
937 : return (aCoord.GetUnit() == eStyleUnit_Coord &&
938 : aCoord.GetCoordValue() == 0) ||
939 : (aCoord.GetUnit() == eStyleUnit_Percent &&
940 : aCoord.GetPercentValue() == 0.0f) ||
941 : (aCoord.IsCalcUnit() &&
942 : // clamp negative calc() to 0
943 : nsRuleNode::ComputeCoordPercentCalc(aCoord, nscoord_MAX) <= 0 &&
944 : nsRuleNode::ComputeCoordPercentCalc(aCoord, 0) <= 0);
945 : }
946 :
947 : static bool IsMarginZero(const nsStyleCoord &aCoord)
948 : {
949 : return (aCoord.GetUnit() == eStyleUnit_Coord &&
950 : aCoord.GetCoordValue() == 0) ||
951 : (aCoord.GetUnit() == eStyleUnit_Percent &&
952 : aCoord.GetPercentValue() == 0.0f) ||
953 : (aCoord.IsCalcUnit() &&
954 : nsRuleNode::ComputeCoordPercentCalc(aCoord, nscoord_MAX) == 0 &&
955 : nsRuleNode::ComputeCoordPercentCalc(aCoord, 0) == 0);
956 : }
957 :
958 : /*
959 : * Calculate the used values for 'width' and 'height' for a replaced element.
960 : *
961 : * http://www.w3.org/TR/CSS21/visudet.html#min-max-widths
962 : */
963 : static nsSize ComputeSizeWithIntrinsicDimensions(
964 : nsRenderingContext* aRenderingContext, nsIFrame* aFrame,
965 : const nsIFrame::IntrinsicSize& aIntrinsicSize,
966 : nsSize aIntrinsicRatio, nsSize aCBSize,
967 : nsSize aMargin, nsSize aBorder, nsSize aPadding);
968 :
969 : /*
970 : * Calculate the used values for 'width' and 'height' when width
971 : * and height are 'auto'. The tentWidth and tentHeight arguments should be
972 : * the result of applying the rules for computing intrinsic sizes and ratios.
973 : * as specified by CSS 2.1 sections 10.3.2 and 10.6.2
974 : */
975 : static nsSize ComputeAutoSizeWithIntrinsicDimensions(nscoord minWidth, nscoord minHeight,
976 : nscoord maxWidth, nscoord maxHeight,
977 : nscoord tentWidth, nscoord tentHeight);
978 :
979 : // Implement nsIFrame::GetPrefWidth in terms of nsIFrame::AddInlinePrefWidth
980 : static nscoord PrefWidthFromInline(nsIFrame* aFrame,
981 : nsRenderingContext* aRenderingContext);
982 :
983 : // Implement nsIFrame::GetMinWidth in terms of nsIFrame::AddInlineMinWidth
984 : static nscoord MinWidthFromInline(nsIFrame* aFrame,
985 : nsRenderingContext* aRenderingContext);
986 :
987 : // Get a suitable foreground color for painting aProperty for aFrame.
988 : static nscolor GetColor(nsIFrame* aFrame, nsCSSProperty aProperty);
989 :
990 : // Get a baseline y position in app units that is snapped to device pixels.
991 : static gfxFloat GetSnappedBaselineY(nsIFrame* aFrame, gfxContext* aContext,
992 : nscoord aY, nscoord aAscent);
993 :
994 : static void DrawString(const nsIFrame* aFrame,
995 : nsRenderingContext* aContext,
996 : const PRUnichar* aString,
997 : PRInt32 aLength,
998 : nsPoint aPoint,
999 : PRUint8 aDirection = NS_STYLE_DIRECTION_INHERIT);
1000 :
1001 : static nscoord GetStringWidth(const nsIFrame* aFrame,
1002 : nsRenderingContext* aContext,
1003 : const PRUnichar* aString,
1004 : PRInt32 aLength);
1005 :
1006 : /**
1007 : * Helper function for drawing text-shadow. The callback's job
1008 : * is to draw whatever needs to be blurred onto the given context.
1009 : */
1010 : typedef void (* TextShadowCallback)(nsRenderingContext* aCtx,
1011 : nsPoint aShadowOffset,
1012 : const nscolor& aShadowColor,
1013 : void* aData);
1014 :
1015 : static void PaintTextShadow(const nsIFrame* aFrame,
1016 : nsRenderingContext* aContext,
1017 : const nsRect& aTextRect,
1018 : const nsRect& aDirtyRect,
1019 : const nscolor& aForegroundColor,
1020 : TextShadowCallback aCallback,
1021 : void* aCallbackData);
1022 :
1023 : /**
1024 : * Gets the baseline to vertically center text from a font within a
1025 : * line of specified height.
1026 : *
1027 : * Returns the baseline position relative to the top of the line.
1028 : */
1029 : static nscoord GetCenteredFontBaseline(nsFontMetrics* aFontMetrics,
1030 : nscoord aLineHeight);
1031 :
1032 : /**
1033 : * Derive a baseline of |aFrame| (measured from its top border edge)
1034 : * from its first in-flow line box (not descending into anything with
1035 : * 'overflow' not 'visible', potentially including aFrame itself).
1036 : *
1037 : * Returns true if a baseline was found (and fills in aResult).
1038 : * Otherwise returns false.
1039 : */
1040 : static bool GetFirstLineBaseline(const nsIFrame* aFrame, nscoord* aResult);
1041 :
1042 : /**
1043 : * Just like GetFirstLineBaseline, except also returns the top and
1044 : * bottom of the line with the baseline.
1045 : *
1046 : * Returns true if a line was found (and fills in aResult).
1047 : * Otherwise returns false.
1048 : */
1049 : struct LinePosition {
1050 : nscoord mTop, mBaseline, mBottom;
1051 :
1052 : LinePosition operator+(nscoord aOffset) const {
1053 : LinePosition result;
1054 : result.mTop = mTop + aOffset;
1055 : result.mBaseline = mBaseline + aOffset;
1056 : result.mBottom = mBottom + aOffset;
1057 : return result;
1058 : }
1059 : };
1060 : static bool GetFirstLinePosition(const nsIFrame* aFrame,
1061 : LinePosition* aResult);
1062 :
1063 :
1064 : /**
1065 : * Derive a baseline of |aFrame| (measured from its top border edge)
1066 : * from its last in-flow line box (not descending into anything with
1067 : * 'overflow' not 'visible', potentially including aFrame itself).
1068 : *
1069 : * Returns true if a baseline was found (and fills in aResult).
1070 : * Otherwise returns false.
1071 : */
1072 : static bool GetLastLineBaseline(const nsIFrame* aFrame, nscoord* aResult);
1073 :
1074 : /**
1075 : * Returns a y coordinate relative to this frame's origin that represents
1076 : * the logical bottom of the frame or its visible content, whichever is lower.
1077 : * Relative positioning is ignored and margins and glyph bounds are not
1078 : * considered.
1079 : * This value will be >= mRect.height() and <= overflowRect.YMost() unless
1080 : * relative positioning is applied.
1081 : */
1082 : static nscoord CalculateContentBottom(nsIFrame* aFrame);
1083 :
1084 : /**
1085 : * Gets the closest frame (the frame passed in or one of its parents) that
1086 : * qualifies as a "layer"; used in DOM0 methods that depends upon that
1087 : * definition. This is the nearest frame that is either positioned or scrolled
1088 : * (the child of a scroll frame).
1089 : */
1090 : static nsIFrame* GetClosestLayer(nsIFrame* aFrame);
1091 :
1092 : /**
1093 : * Gets the graphics filter for the frame
1094 : */
1095 : static GraphicsFilter GetGraphicsFilterForFrame(nsIFrame* aFrame);
1096 :
1097 : /* N.B. The only difference between variants of the Draw*Image
1098 : * functions below is the type of the aImage argument.
1099 : */
1100 :
1101 : /**
1102 : * Draw a background image. The image's dimensions are as specified in aDest;
1103 : * the image itself is not consulted to determine a size.
1104 : * See https://wiki.mozilla.org/Gecko:Image_Snapping_and_Rendering
1105 : * @param aRenderingContext Where to draw the image, set up with an
1106 : * appropriate scale and transform for drawing in
1107 : * app units.
1108 : * @param aImage The image.
1109 : * @param aImageSize The unscaled size of the image being drawn.
1110 : * (This might be the image's size if no scaling
1111 : * occurs, or it might be the image's size if
1112 : * the image is a vector image being rendered at
1113 : * that size.)
1114 : * @param aDest The position and scaled area where one copy of
1115 : * the image should be drawn.
1116 : * @param aFill The area to be filled with copies of the
1117 : * image.
1118 : * @param aAnchor A point in aFill which we will ensure is
1119 : * pixel-aligned in the output.
1120 : * @param aDirty Pixels outside this area may be skipped.
1121 : * @param aImageFlags Image flags of the imgIContainer::FLAG_* variety
1122 : */
1123 : static nsresult DrawBackgroundImage(nsRenderingContext* aRenderingContext,
1124 : imgIContainer* aImage,
1125 : const nsIntSize& aImageSize,
1126 : GraphicsFilter aGraphicsFilter,
1127 : const nsRect& aDest,
1128 : const nsRect& aFill,
1129 : const nsPoint& aAnchor,
1130 : const nsRect& aDirty,
1131 : PRUint32 aImageFlags);
1132 :
1133 : /**
1134 : * Draw an image.
1135 : * See https://wiki.mozilla.org/Gecko:Image_Snapping_and_Rendering
1136 : * @param aRenderingContext Where to draw the image, set up with an
1137 : * appropriate scale and transform for drawing in
1138 : * app units.
1139 : * @param aImage The image.
1140 : * @param aDest Where one copy of the image should mapped to.
1141 : * @param aFill The area to be filled with copies of the
1142 : * image.
1143 : * @param aAnchor A point in aFill which we will ensure is
1144 : * pixel-aligned in the output.
1145 : * @param aDirty Pixels outside this area may be skipped.
1146 : * @param aImageFlags Image flags of the imgIContainer::FLAG_* variety
1147 : */
1148 : static nsresult DrawImage(nsRenderingContext* aRenderingContext,
1149 : imgIContainer* aImage,
1150 : GraphicsFilter aGraphicsFilter,
1151 : const nsRect& aDest,
1152 : const nsRect& aFill,
1153 : const nsPoint& aAnchor,
1154 : const nsRect& aDirty,
1155 : PRUint32 aImageFlags);
1156 :
1157 : /**
1158 : * Convert an nsRect to a gfxRect.
1159 : */
1160 : static gfxRect RectToGfxRect(const nsRect& aRect,
1161 : PRInt32 aAppUnitsPerDevPixel);
1162 :
1163 : /**
1164 : * Draw a drawable using the pixel snapping algorithm.
1165 : * See https://wiki.mozilla.org/Gecko:Image_Snapping_and_Rendering
1166 : * @param aRenderingContext Where to draw the image, set up with an
1167 : * appropriate scale and transform for drawing in
1168 : * app units.
1169 : * @param aDrawable The drawable we want to draw.
1170 : * @param aFilter The graphics filter we should draw with.
1171 : * @param aDest Where one copy of the image should mapped to.
1172 : * @param aFill The area to be filled with copies of the
1173 : * image.
1174 : * @param aAnchor A point in aFill which we will ensure is
1175 : * pixel-aligned in the output.
1176 : * @param aDirty Pixels outside this area may be skipped.
1177 : */
1178 : static void DrawPixelSnapped(nsRenderingContext* aRenderingContext,
1179 : gfxDrawable* aDrawable,
1180 : GraphicsFilter aFilter,
1181 : const nsRect& aDest,
1182 : const nsRect& aFill,
1183 : const nsPoint& aAnchor,
1184 : const nsRect& aDirty);
1185 :
1186 : /**
1187 : * Draw a whole image without scaling or tiling.
1188 : *
1189 : * @param aRenderingContext Where to draw the image, set up with an
1190 : * appropriate scale and transform for drawing in
1191 : * app units.
1192 : * @param aImage The image.
1193 : * @param aDest The top-left where the image should be drawn
1194 : * @param aDirty If non-null, then pixels outside this area may
1195 : * be skipped.
1196 : * @param aImageFlags Image flags of the imgIContainer::FLAG_* variety
1197 : * @param aSourceArea If non-null, this area is extracted from
1198 : * the image and drawn at aDest. It's
1199 : * in appunits. For best results it should
1200 : * be aligned with image pixels.
1201 : */
1202 : static nsresult DrawSingleUnscaledImage(nsRenderingContext* aRenderingContext,
1203 : imgIContainer* aImage,
1204 : GraphicsFilter aGraphicsFilter,
1205 : const nsPoint& aDest,
1206 : const nsRect* aDirty,
1207 : PRUint32 aImageFlags,
1208 : const nsRect* aSourceArea = nsnull);
1209 :
1210 : /**
1211 : * Draw a whole image without tiling.
1212 : *
1213 : * @param aRenderingContext Where to draw the image, set up with an
1214 : * appropriate scale and transform for drawing in
1215 : * app units.
1216 : * @param aImage The image.
1217 : * @param aDest The area that the image should fill
1218 : * @param aDirty Pixels outside this area may be skipped.
1219 : * @param aSourceArea If non-null, this area is extracted from
1220 : * the image and drawn in aDest. It's
1221 : * in appunits. For best results it should
1222 : * be aligned with image pixels.
1223 : * @param aImageFlags Image flags of the imgIContainer::FLAG_* variety
1224 : */
1225 : static nsresult DrawSingleImage(nsRenderingContext* aRenderingContext,
1226 : imgIContainer* aImage,
1227 : GraphicsFilter aGraphicsFilter,
1228 : const nsRect& aDest,
1229 : const nsRect& aDirty,
1230 : PRUint32 aImageFlags,
1231 : const nsRect* aSourceArea = nsnull);
1232 :
1233 : /**
1234 : * Given an imgIContainer, this method attempts to obtain an intrinsic
1235 : * px-valued height & width for it. If the imgIContainer has a non-pixel
1236 : * value for either height or width, this method tries to generate a pixel
1237 : * value for that dimension using the intrinsic ratio (if available). The
1238 : * intrinsic ratio will be assigned to aIntrinsicRatio; if there's no
1239 : * intrinsic ratio then (0, 0) will be assigned.
1240 : *
1241 : * This method will always set aGotWidth and aGotHeight to indicate whether
1242 : * we were able to successfully obtain (or compute) a value for each
1243 : * dimension.
1244 : *
1245 : * NOTE: This method is similar to ComputeSizeWithIntrinsicDimensions. The
1246 : * difference is that this one is simpler and is suited to places where we
1247 : * have less information about the frame tree.
1248 : */
1249 : static void ComputeSizeForDrawing(imgIContainer* aImage,
1250 : nsIntSize& aImageSize,
1251 : nsSize& aIntrinsicRatio,
1252 : bool& aGotWidth,
1253 : bool& aGotHeight);
1254 :
1255 : /**
1256 : * Given a source area of an image (in appunits) and a destination area
1257 : * that we want to map that source area too, computes the area that
1258 : * would be covered by the whole image. This is useful for passing to
1259 : * the aDest parameter of DrawImage, when we want to draw a subimage
1260 : * of an overall image.
1261 : */
1262 : static nsRect GetWholeImageDestination(const nsIntSize& aWholeImageSize,
1263 : const nsRect& aImageSourceArea,
1264 : const nsRect& aDestArea);
1265 :
1266 : /**
1267 : * Determine if any corner radius is of nonzero size
1268 : * @param aCorners the |nsStyleCorners| object to check
1269 : * @return true unless all the coordinates are 0%, 0 or null.
1270 : *
1271 : * A corner radius with one dimension zero and one nonzero is
1272 : * treated as a nonzero-radius corner, even though it will end up
1273 : * being rendered like a zero-radius corner. This is because such
1274 : * corners are not expected to appear outside of test cases, and it's
1275 : * simpler to implement the test this way.
1276 : */
1277 : static bool HasNonZeroCorner(const nsStyleCorners& aCorners);
1278 :
1279 : /**
1280 : * Determine if there is any corner radius on corners adjacent to the
1281 : * given side.
1282 : */
1283 : static bool HasNonZeroCornerOnSide(const nsStyleCorners& aCorners,
1284 : mozilla::css::Side aSide);
1285 :
1286 : /**
1287 : * Determine if a widget is likely to require transparency or translucency.
1288 : * @param aBackgroundFrame The frame that the background is set on. For
1289 : * <window>s, this will be the canvas frame.
1290 : * @param aCSSRootFrame The frame that holds CSS properties affecting
1291 : * the widget's transparency. For menupopups,
1292 : * aBackgroundFrame and aCSSRootFrame will be the
1293 : * same.
1294 : * @return a value suitable for passing to SetWindowTranslucency
1295 : */
1296 : static nsTransparencyMode GetFrameTransparency(nsIFrame* aBackgroundFrame,
1297 : nsIFrame* aCSSRootFrame);
1298 :
1299 : /**
1300 : * A frame is a popup if it has its own floating window. Menus, panels
1301 : * and combobox dropdowns are popups.
1302 : */
1303 : static bool IsPopup(nsIFrame* aFrame);
1304 :
1305 : /**
1306 : * Find the nearest "display root". This is the nearest enclosing
1307 : * popup frame or the root prescontext's root frame.
1308 : */
1309 : static nsIFrame* GetDisplayRootFrame(nsIFrame* aFrame);
1310 :
1311 : /**
1312 : * Get textrun construction flags determined by a given style; in particular
1313 : * some combination of:
1314 : * -- TEXT_DISABLE_OPTIONAL_LIGATURES if letter-spacing is in use
1315 : * -- TEXT_OPTIMIZE_SPEED if the text-rendering CSS property and font size
1316 : * and prefs indicate we should be optimizing for speed over quality
1317 : */
1318 : static PRUint32 GetTextRunFlagsForStyle(nsStyleContext* aStyleContext,
1319 : const nsStyleText* aStyleText,
1320 : const nsStyleFont* aStyleFont);
1321 :
1322 : /**
1323 : * Takes two rectangles whose origins must be the same, and computes
1324 : * the difference between their union and their intersection as two
1325 : * rectangles. (This difference is a superset of the difference
1326 : * between the two rectangles.)
1327 : */
1328 : static void GetRectDifferenceStrips(const nsRect& aR1, const nsRect& aR2,
1329 : nsRect* aHStrip, nsRect* aVStrip);
1330 :
1331 : /**
1332 : * Get a device context that can be used to get up-to-date device
1333 : * dimensions for the given docshell. For some reason, this is more
1334 : * complicated than it ought to be in multi-monitor situations.
1335 : */
1336 : static nsDeviceContext*
1337 : GetDeviceContextForScreenInfo(nsIDocShell* aDocShell);
1338 :
1339 : /**
1340 : * Some frames with 'position: fixed' (nsStylePosition::mDisplay ==
1341 : * NS_STYLE_POSITION_FIXED) are not really fixed positioned, since
1342 : * they're inside an element with -moz-transform. This function says
1343 : * whether such an element is a real fixed-pos element.
1344 : */
1345 : static bool IsReallyFixedPos(nsIFrame* aFrame);
1346 :
1347 : /**
1348 : * Return true if aFrame is in an {ib} split and is NOT one of the
1349 : * continuations of the first inline in it.
1350 : */
1351 : static bool FrameIsNonFirstInIBSplit(const nsIFrame* aFrame) {
1352 : return (aFrame->GetStateBits() & NS_FRAME_IS_SPECIAL) &&
1353 : aFrame->GetFirstContinuation()->
1354 : Properties().Get(nsIFrame::IBSplitSpecialPrevSibling());
1355 : }
1356 :
1357 : /**
1358 : * Return true if aFrame is in an {ib} split and is NOT one of the
1359 : * continuations of the last inline in it.
1360 : */
1361 : static bool FrameIsNonLastInIBSplit(const nsIFrame* aFrame) {
1362 : return (aFrame->GetStateBits() & NS_FRAME_IS_SPECIAL) &&
1363 : aFrame->GetFirstContinuation()->
1364 : Properties().Get(nsIFrame::IBSplitSpecialSibling());
1365 : }
1366 :
1367 : /**
1368 : * Obtain a gfxASurface from the given DOM element, if possible.
1369 : * This obtains the most natural surface from the element; that
1370 : * is, the one that can be obtained with the fewest conversions.
1371 : *
1372 : * The flags below can modify the behaviour of this function. The
1373 : * result is returned as a SurfaceFromElementResult struct, also
1374 : * defined below.
1375 : *
1376 : * Currently, this will do:
1377 : * - HTML Canvas elements: will return the underlying canvas surface
1378 : * - HTML Video elements: will return the current video frame
1379 : * - Image elements: will return the image
1380 : *
1381 : * The above results are modified by the below flags (copying,
1382 : * forcing image surface, etc.).
1383 : */
1384 :
1385 : enum {
1386 : /* Always create a new surface for the result */
1387 : SFE_WANT_NEW_SURFACE = 1 << 0,
1388 : /* When creating a new surface, create an image surface */
1389 : SFE_WANT_IMAGE_SURFACE = 1 << 1,
1390 : /* Whether to extract the first frame (as opposed to the
1391 : current frame) in the case that the element is an image. */
1392 : SFE_WANT_FIRST_FRAME = 1 << 2,
1393 : /* Whether we should skip colorspace/gamma conversion */
1394 : SFE_NO_COLORSPACE_CONVERSION = 1 << 3,
1395 : /* Whether we should skip premultiplication -- the resulting
1396 : image will always be an image surface, and must not be given to
1397 : Thebes for compositing! */
1398 : SFE_NO_PREMULTIPLY_ALPHA = 1 << 4
1399 : };
1400 :
1401 0 : struct SurfaceFromElementResult {
1402 : SurfaceFromElementResult() :
1403 : // Use safe default values here
1404 : mIsWriteOnly(true), mIsStillLoading(false), mCORSUsed(false) {}
1405 :
1406 : /* mSurface will contain the resulting surface, or will be NULL on error */
1407 : nsRefPtr<gfxASurface> mSurface;
1408 : /* The size of the surface */
1409 : gfxIntSize mSize;
1410 : /* The principal associated with the element whose surface was returned.
1411 : If there is a surface, this will never be null. */
1412 : nsCOMPtr<nsIPrincipal> mPrincipal;
1413 : /* The image request, if the element is an nsIImageLoadingContent */
1414 : nsCOMPtr<imgIRequest> mImageRequest;
1415 : /* Whether the element was "write only", that is, the bits should not be exposed to content */
1416 : bool mIsWriteOnly;
1417 : /* Whether the element was still loading. Some consumers need to handle
1418 : this case specially. */
1419 : bool mIsStillLoading;
1420 : /* Whether the element used CORS when loading. */
1421 : bool mCORSUsed;
1422 : };
1423 :
1424 : static SurfaceFromElementResult SurfaceFromElement(mozilla::dom::Element *aElement,
1425 : PRUint32 aSurfaceFlags = 0);
1426 :
1427 : /**
1428 : * When the document is editable by contenteditable attribute of its root
1429 : * content or body content.
1430 : *
1431 : * Be aware, this returns NULL if it's in designMode.
1432 : *
1433 : * For example:
1434 : *
1435 : * <html contenteditable="true"><body></body></html>
1436 : * returns the <html>.
1437 : *
1438 : * <html><body contenteditable="true"></body></html>
1439 : * <body contenteditable="true"></body>
1440 : * With these cases, this returns the <body>.
1441 : * NOTE: The latter case isn't created normally, however, it can be
1442 : * created by script with XHTML.
1443 : *
1444 : * <body><p contenteditable="true"></p></body>
1445 : * returns NULL because <body> isn't editable.
1446 : */
1447 : static nsIContent*
1448 : GetEditableRootContentByContentEditable(nsIDocument* aDocument);
1449 :
1450 : /**
1451 : * Returns true if the passed in prescontext needs the dark grey background
1452 : * that goes behind the page of a print preview presentation.
1453 : */
1454 : static bool NeedsPrintPreviewBackground(nsPresContext* aPresContext) {
1455 : return aPresContext->IsRootPaginatedDocument() &&
1456 : (aPresContext->Type() == nsPresContext::eContext_PrintPreview ||
1457 : aPresContext->Type() == nsPresContext::eContext_PageLayout);
1458 : }
1459 :
1460 : /**
1461 : * Adds all font faces used in the frame tree starting from aFrame
1462 : * to the list aFontFaceList.
1463 : */
1464 : static nsresult GetFontFacesForFrames(nsIFrame* aFrame,
1465 : nsFontFaceList* aFontFaceList);
1466 :
1467 : /**
1468 : * Adds all font faces used within the specified range of text in aFrame,
1469 : * and optionally its continuations, to the list in aFontFaceList.
1470 : * Pass 0 and PR_INT32_MAX for aStartOffset and aEndOffset to specify the
1471 : * entire text is to be considered.
1472 : */
1473 : static nsresult GetFontFacesForText(nsIFrame* aFrame,
1474 : PRInt32 aStartOffset,
1475 : PRInt32 aEndOffset,
1476 : bool aFollowContinuations,
1477 : nsFontFaceList* aFontFaceList);
1478 :
1479 : /**
1480 : * Walks the frame tree starting at aFrame looking for textRuns.
1481 : * If |clear| is true, just clears the TEXT_RUN_MEMORY_ACCOUNTED flag
1482 : * on each textRun found (and |aMallocSizeOf| is not used).
1483 : * If |clear| is false, adds the storage used for each textRun to the
1484 : * total, and sets the TEXT_RUN_MEMORY_ACCOUNTED flag to avoid double-
1485 : * accounting. (Runs with this flag already set will be skipped.)
1486 : * Expected usage pattern is therefore to call twice:
1487 : * (void)SizeOfTextRunsForFrames(rootFrame, nsnull, true);
1488 : * total = SizeOfTextRunsForFrames(rootFrame, mallocSizeOf, false);
1489 : */
1490 : static size_t SizeOfTextRunsForFrames(nsIFrame* aFrame,
1491 : nsMallocSizeOfFun aMallocSizeOf,
1492 : bool clear);
1493 :
1494 : /**
1495 : * Checks if CSS 3D transforms are currently enabled.
1496 : */
1497 : static bool Are3DTransformsEnabled();
1498 :
1499 : /**
1500 : * Unions the overflow areas of all non-popup children of aFrame with
1501 : * aOverflowAreas.
1502 : */
1503 : static void UnionChildOverflow(nsIFrame* aFrame,
1504 : nsOverflowAreas& aOverflowAreas);
1505 :
1506 : /**
1507 : * Return whether this is a frame whose width is used when computing
1508 : * the font size inflation of its descendants.
1509 : */
1510 : static bool IsContainerForFontSizeInflation(const nsIFrame *aFrame)
1511 : {
1512 : return aFrame->GetStateBits() & NS_FRAME_FONT_INFLATION_CONTAINER;
1513 : }
1514 :
1515 : /**
1516 : * Return the font size inflation *ratio* for a given frame. This is
1517 : * the factor by which font sizes should be inflated; it is never
1518 : * smaller than 1.
1519 : *
1520 : * The WidthDetermination parameter says how we determine the width of
1521 : * the nearest inflation container: when not in reflow we look at the
1522 : * frame tree; when in reflow we look at state stored on the pres
1523 : * context.
1524 : */
1525 : enum WidthDetermination { eNotInReflow, eInReflow };
1526 : static float FontSizeInflationFor(const nsIFrame *aFrame,
1527 : WidthDetermination aWidthDetermination);
1528 :
1529 : /**
1530 : * Perform the first half of the computation of FontSizeInflationFor
1531 : * (see above).
1532 : * This includes determining whether inflation should be performed
1533 : * within this container and returning 0 if it should not be.
1534 : *
1535 : * The result is guaranteed not to vary between line participants
1536 : * (inlines, text frames) within a line.
1537 : *
1538 : * The result should not be used directly since font sizes slightly
1539 : * above the minimum should always be adjusted as done by
1540 : * FontSizeInflationInner.
1541 : */
1542 : static nscoord InflationMinFontSizeFor(const nsIFrame *aFrame,
1543 : WidthDetermination
1544 : aWidthDetermination);
1545 :
1546 : /**
1547 : * Perform the second half of the computation done by
1548 : * FontSizeInflationFor (see above).
1549 : *
1550 : * aMinFontSize must be the result of one of the
1551 : * InflationMinFontSizeFor methods above.
1552 : */
1553 : static float FontSizeInflationInner(const nsIFrame *aFrame,
1554 : nscoord aMinFontSize);
1555 :
1556 : static bool FontSizeInflationEnabled(nsPresContext *aPresContext);
1557 :
1558 : static void Initialize();
1559 : static void Shutdown();
1560 :
1561 : /**
1562 : * Register an imgIRequest object with a refresh driver.
1563 : *
1564 : * @param aPresContext The nsPresContext whose refresh driver we want to
1565 : * register with.
1566 : * @param aRequest A pointer to the imgIRequest object which the client wants
1567 : * to register with the refresh driver.
1568 : * @param aRequestRegistered A pointer to a boolean value which indicates
1569 : * whether the given image request is registered. If
1570 : * *aRequestRegistered is true, then this request will not be
1571 : * registered again. If the request is registered by this function,
1572 : * then *aRequestRegistered will be set to true upon the completion of
1573 : * this function.
1574 : *
1575 : */
1576 : static void RegisterImageRequest(nsPresContext* aPresContext,
1577 : imgIRequest* aRequest,
1578 : bool* aRequestRegistered);
1579 :
1580 : /**
1581 : * Register an imgIRequest object with a refresh driver, but only if the
1582 : * request is for an image that is animated.
1583 : *
1584 : * @param aPresContext The nsPresContext whose refresh driver we want to
1585 : * register with.
1586 : * @param aRequest A pointer to the imgIRequest object which the client wants
1587 : * to register with the refresh driver.
1588 : * @param aRequestRegistered A pointer to a boolean value which indicates
1589 : * whether the given image request is registered. If
1590 : * *aRequestRegistered is true, then this request will not be
1591 : * registered again. If the request is registered by this function,
1592 : * then *aRequestRegistered will be set to true upon the completion of
1593 : * this function.
1594 : *
1595 : */
1596 : static void RegisterImageRequestIfAnimated(nsPresContext* aPresContext,
1597 : imgIRequest* aRequest,
1598 : bool* aRequestRegistered);
1599 :
1600 : /**
1601 : * Deregister an imgIRequest object from a refresh driver.
1602 : *
1603 : * @param aPresContext The nsPresContext whose refresh driver we want to
1604 : * deregister from.
1605 : * @param aRequest A pointer to the imgIRequest object with which the client
1606 : * previously registered and now wants to deregister from the refresh
1607 : * driver.
1608 : * @param aRequestRegistered A pointer to a boolean value which indicates
1609 : * whether the given image request is registered. If
1610 : * *aRequestRegistered is false, then this request will not be
1611 : * deregistered. If the request is deregistered by this function,
1612 : * then *aRequestRegistered will be set to false upon the completion of
1613 : * this function.
1614 : */
1615 : static void DeregisterImageRequest(nsPresContext* aPresContext,
1616 : imgIRequest* aRequest,
1617 : bool* aRequestRegistered);
1618 :
1619 : #ifdef DEBUG
1620 : /**
1621 : * Assert that there are no duplicate continuations of the same frame
1622 : * within aFrameList. Optimize the tests by assuming that all frames
1623 : * in aFrameList have parent aContainer.
1624 : */
1625 : static void
1626 : AssertNoDuplicateContinuations(nsIFrame* aContainer,
1627 : const nsFrameList& aFrameList);
1628 :
1629 : /**
1630 : * Assert that the frame tree rooted at |aSubtreeRoot| is empty, i.e.,
1631 : * that it contains no first-in-flows.
1632 : */
1633 : static void
1634 : AssertTreeOnlyEmptyNextInFlows(nsIFrame *aSubtreeRoot);
1635 : #endif
1636 : };
1637 :
1638 : namespace mozilla {
1639 : namespace layout {
1640 :
1641 : /**
1642 : * An RAII class which will, for the duration of its lifetime,
1643 : * **if** the frame given is a container for font size inflation,
1644 : * set the current inflation container on the pres context to null
1645 : * (and then, in its destructor, restore the old value).
1646 : */
1647 : class AutoMaybeNullInflationContainer {
1648 : public:
1649 : AutoMaybeNullInflationContainer(nsIFrame *aFrame)
1650 : {
1651 : if (nsLayoutUtils::IsContainerForFontSizeInflation(aFrame)) {
1652 : mPresContext = aFrame->PresContext();
1653 : mOldValue = mPresContext->mCurrentInflationContainer;
1654 : mPresContext->mCurrentInflationContainer = nsnull;
1655 : } else {
1656 : // indicate we have nothing to restore
1657 : mPresContext = nsnull;
1658 : }
1659 : }
1660 :
1661 : ~AutoMaybeNullInflationContainer()
1662 : {
1663 : if (mPresContext) {
1664 : mPresContext->mCurrentInflationContainer = mOldValue;
1665 : }
1666 : }
1667 : private:
1668 : nsPresContext *mPresContext;
1669 : nsIFrame *mOldValue;
1670 : };
1671 :
1672 : }
1673 : }
1674 :
1675 : class nsSetAttrRunnable : public nsRunnable
1676 : {
1677 : public:
1678 : nsSetAttrRunnable(nsIContent* aContent, nsIAtom* aAttrName,
1679 : const nsAString& aValue);
1680 : nsSetAttrRunnable(nsIContent* aContent, nsIAtom* aAttrName,
1681 : PRInt32 aValue);
1682 :
1683 : NS_DECL_NSIRUNNABLE
1684 :
1685 : nsCOMPtr<nsIContent> mContent;
1686 : nsCOMPtr<nsIAtom> mAttrName;
1687 : nsAutoString mValue;
1688 : };
1689 :
1690 : class nsUnsetAttrRunnable : public nsRunnable
1691 : {
1692 : public:
1693 : nsUnsetAttrRunnable(nsIContent* aContent, nsIAtom* aAttrName);
1694 :
1695 : NS_DECL_NSIRUNNABLE
1696 :
1697 : nsCOMPtr<nsIContent> mContent;
1698 : nsCOMPtr<nsIAtom> mAttrName;
1699 : };
1700 :
1701 : class nsReflowFrameRunnable : public nsRunnable
1702 : {
1703 : public:
1704 : nsReflowFrameRunnable(nsIFrame* aFrame,
1705 : nsIPresShell::IntrinsicDirty aIntrinsicDirty,
1706 : nsFrameState aBitToAdd);
1707 :
1708 : NS_DECL_NSIRUNNABLE
1709 :
1710 : nsWeakFrame mWeakFrame;
1711 : nsIPresShell::IntrinsicDirty mIntrinsicDirty;
1712 : nsFrameState mBitToAdd;
1713 : };
1714 :
1715 : #endif // nsLayoutUtils_h__
|