Coverage Report

Created: 2018-09-25 14:53

/work/obj-fuzz/dist/include/nsLayoutUtils.h
Line
Count
Source (jump to first uncovered line)
1
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
3
/* This Source Code Form is subject to the terms of the Mozilla Public
4
 * License, v. 2.0. If a copy of the MPL was not distributed with this
5
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7
#ifndef nsLayoutUtils_h__
8
#define nsLayoutUtils_h__
9
10
#include "LayoutConstants.h"
11
#include "mozilla/MemoryReporting.h"
12
#include "mozilla/ArrayUtils.h"
13
#include "mozilla/LookAndFeel.h"
14
#include "mozilla/Maybe.h"
15
#include "mozilla/TypedEnumBits.h"
16
#include "nsBoundingMetrics.h"
17
#include "nsChangeHint.h"
18
#include "nsFrameList.h"
19
#include "mozilla/layout/FrameChildList.h"
20
#include "nsThreadUtils.h"
21
#include "nsIPrincipal.h"
22
#include "FrameMetrics.h"
23
#include "nsIWidget.h"
24
#include "nsCSSPropertyID.h"
25
#include "nsStyleCoord.h"
26
#include "nsStyleConsts.h"
27
#include "nsGkAtoms.h"
28
#include "imgIContainer.h"
29
#include "mozilla/gfx/2D.h"
30
#include "Units.h"
31
#include "mozilla/ToString.h"
32
#include "mozilla/ReflowOutput.h"
33
#include "ImageContainer.h"
34
#include "gfx2DGlue.h"
35
#include "nsStyleConsts.h"
36
#include "SVGImageContext.h"
37
#include <limits>
38
#include <algorithm>
39
#include "gfxPoint.h"
40
#include "nsClassHashtable.h"
41
42
class gfxContext;
43
class nsPresContext;
44
class nsIContent;
45
class nsAtom;
46
class nsIScrollableFrame;
47
class nsRegion;
48
class nsDisplayListBuilder;
49
enum class nsDisplayListBuilderMode : uint8_t;
50
class nsDisplayItem;
51
class nsFontMetrics;
52
class nsFontFaceList;
53
class nsIImageLoadingContent;
54
class nsBlockFrame;
55
class nsContainerFrame;
56
class nsView;
57
class nsIFrame;
58
class nsStyleCoord;
59
class nsStyleCorners;
60
class nsPIDOMWindowOuter;
61
class imgIRequest;
62
class nsIDocument;
63
struct nsStyleFont;
64
struct nsOverflowAreas;
65
66
namespace mozilla {
67
class ComputedStyle;
68
enum class CSSPseudoElementType : uint8_t;
69
class EventListenerManager;
70
enum class LayoutFrameType : uint8_t;
71
struct IntrinsicSize;
72
struct ContainerLayerParameters;
73
class WritingMode;
74
class DisplayItemClip;
75
class EffectSet;
76
struct ActiveScrolledRoot;
77
enum class StyleImageOrientation : uint8_t;
78
namespace dom {
79
class CanvasRenderingContext2D;
80
class DOMRectList;
81
class Element;
82
class Event;
83
class HTMLImageElement;
84
class HTMLCanvasElement;
85
class HTMLVideoElement;
86
class InspectorFontFace;
87
class OffscreenCanvas;
88
class Selection;
89
} // namespace dom
90
namespace gfx {
91
struct RectCornerRadii;
92
enum class ShapedTextFlags : uint16_t;
93
} // namespace gfx
94
namespace layers {
95
class Image;
96
class StackingContextHelper;
97
class Layer;
98
} // namespace layers
99
} // namespace mozilla
100
101
namespace mozilla {
102
103
struct DisplayPortPropertyData {
104
  DisplayPortPropertyData(const nsRect& aRect, uint32_t aPriority)
105
    : mRect(aRect)
106
    , mPriority(aPriority)
107
0
  {}
108
  nsRect mRect;
109
  uint32_t mPriority;
110
};
111
112
struct DisplayPortMarginsPropertyData {
113
  DisplayPortMarginsPropertyData(const ScreenMargin& aMargins,
114
                                 uint32_t aPriority)
115
    : mMargins(aMargins)
116
    , mPriority(aPriority)
117
  {}
118
  ScreenMargin mMargins;
119
  uint32_t mPriority;
120
};
121
122
struct MotionPathData {
123
  gfx::Point mTranslate;
124
  float mRotate;
125
};
126
127
} // namespace mozilla
128
129
// For GetDisplayPort
130
enum class RelativeTo {
131
  ScrollPort,
132
  ScrollFrame
133
};
134
135
// Flags to customize the behavior of nsLayoutUtils::DrawString.
136
enum class DrawStringFlags {
137
  eDefault         = 0x0,
138
  eForceHorizontal = 0x1 // Forces the text to be drawn horizontally.
139
};
140
MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(DrawStringFlags)
141
142
enum class ReparentingDirection {
143
  Backwards,
144
  Forwards,
145
  Variable // Could be either of the above; take most pessimistic action.
146
};
147
148
/**
149
 * nsLayoutUtils is a namespace class used for various helper
150
 * functions that are useful in multiple places in layout.  The goal
151
 * is not to define multiple copies of the same static helper.
152
 */
153
class nsLayoutUtils
154
{
155
  typedef mozilla::ComputedStyle ComputedStyle;
156
  typedef mozilla::dom::DOMRectList DOMRectList;
157
  typedef mozilla::layers::Layer Layer;
158
  typedef mozilla::layers::StackingContextHelper StackingContextHelper;
159
  typedef mozilla::ContainerLayerParameters ContainerLayerParameters;
160
  typedef mozilla::IntrinsicSize IntrinsicSize;
161
  typedef mozilla::gfx::SourceSurface SourceSurface;
162
  typedef mozilla::gfx::Color Color;
163
  typedef mozilla::gfx::DrawTarget DrawTarget;
164
  typedef mozilla::gfx::ExtendMode ExtendMode;
165
  typedef mozilla::gfx::SamplingFilter SamplingFilter;
166
  typedef mozilla::gfx::Float Float;
167
  typedef mozilla::gfx::Point Point;
168
  typedef mozilla::gfx::Rect Rect;
169
  typedef mozilla::gfx::RectDouble RectDouble;
170
  typedef mozilla::gfx::Size Size;
171
  typedef mozilla::gfx::Matrix4x4 Matrix4x4;
172
  typedef mozilla::gfx::Matrix4x4Flagged Matrix4x4Flagged;
173
  typedef mozilla::gfx::RectCornerRadii RectCornerRadii;
174
  typedef mozilla::gfx::StrokeOptions StrokeOptions;
175
  typedef mozilla::image::ImgDrawResult ImgDrawResult;
176
177
public:
178
  typedef mozilla::layers::FrameMetrics FrameMetrics;
179
  typedef mozilla::layers::ScrollMetadata ScrollMetadata;
180
  typedef FrameMetrics::ViewID ViewID;
181
  typedef mozilla::CSSPoint CSSPoint;
182
  typedef mozilla::CSSSize CSSSize;
183
  typedef mozilla::CSSIntSize CSSIntSize;
184
  typedef mozilla::CSSRect CSSRect;
185
  typedef mozilla::ScreenMargin ScreenMargin;
186
  typedef mozilla::LayoutDeviceIntSize LayoutDeviceIntSize;
187
  typedef mozilla::LayoutDeviceRect LayoutDeviceRect;
188
  typedef mozilla::StyleGeometryBox StyleGeometryBox;
189
  typedef mozilla::SVGImageContext SVGImageContext;
190
  typedef mozilla::LogicalSize LogicalSize;
191
192
  /**
193
   * Finds previously assigned ViewID for the given content element, if any.
194
   * Returns whether a ViewID was previously assigned.
195
   */
196
  static bool FindIDFor(const nsIContent* aContent, ViewID* aOutViewId);
197
198
  /**
199
   * Finds previously assigned or generates a unique ViewID for the given
200
   * content element.
201
   */
202
  static ViewID FindOrCreateIDFor(nsIContent* aContent);
203
204
  /**
205
   * Find content for given ID.
206
   */
207
  static nsIContent* FindContentFor(ViewID aId);
208
209
  /**
210
   * Find the scrollable frame for a given ID.
211
   */
212
  static nsIScrollableFrame* FindScrollableFrameFor(ViewID aId);
213
214
  /**
215
   * Find the ID for a given scrollable frame.
216
   */
217
  static ViewID FindIDForScrollableFrame(nsIScrollableFrame* aScrollable);
218
219
  /**
220
   * Get display port for the given element, relative to the specified entity,
221
   * defaulting to the scrollport.
222
   */
223
  static bool GetDisplayPort(nsIContent* aContent, nsRect *aResult,
224
    RelativeTo aRelativeTo = RelativeTo::ScrollPort);
225
226
  /**
227
   * Check whether the given element has a displayport.
228
   */
229
  static bool HasDisplayPort(nsIContent* aContent);
230
231
  /**
232
   * Check whether the given frame has a displayport. It returns false
233
   * for scrolled frames and true for the corresponding scroll frame.
234
   * Optionally pass the child, and it only returns true if the child is the
235
   * scrolled frame for the displayport.
236
   */
237
  static bool FrameHasDisplayPort(nsIFrame* aFrame, const nsIFrame* aScrolledFrame = nullptr);
238
239
  /**
240
   * Check if the given element has a margins based displayport but is missing a
241
   * displayport base rect that it needs to properly compute a displayport rect.
242
   */
243
  static bool IsMissingDisplayPortBaseRect(nsIContent* aContent);
244
245
  /**
246
   * Go through the IPC Channel and update displayport margins for content
247
   * elements based on UpdateFrame messages. The messages are left in the
248
   * queue and will be fully processed when dequeued. The aim is to paint
249
   * the most up-to-date displayport without waiting for these message to
250
   * go through the message queue.
251
   */
252
  static void UpdateDisplayPortMarginsFromPendingMessages();
253
254
  /**
255
   * @return the display port for the given element which should be used for
256
   * visibility testing purposes.
257
   *
258
   * If low-precision buffers are enabled, this is the critical display port;
259
   * otherwise, it's the same display port returned by GetDisplayPort().
260
   */
261
  static bool GetDisplayPortForVisibilityTesting(
262
    nsIContent* aContent,
263
    nsRect* aResult,
264
    RelativeTo aRelativeTo = RelativeTo::ScrollPort);
265
266
  enum class RepaintMode : uint8_t {
267
    Repaint,
268
    DoNotRepaint
269
  };
270
271
  /**
272
   * Invalidate for displayport change.
273
   */
274
  static void InvalidateForDisplayPortChange(nsIContent* aContent,
275
                                             bool aHadDisplayPort,
276
                                             const nsRect& aOldDisplayPort,
277
                                             const nsRect& aNewDisplayPort,
278
                                             RepaintMode aRepaintMode = RepaintMode::Repaint);
279
280
  /**
281
   * Set the display port margins for a content element to be used with a
282
   * display port base (see SetDisplayPortBase()).
283
   * See also nsIDOMWindowUtils.setDisplayPortMargins.
284
   * @param aContent the content element for which to set the margins
285
   * @param aPresShell the pres shell for the document containing the element
286
   * @param aMargins the margins to set
287
   * @param aAlignmentX, alignmentY the amount of pixels to which to align the
288
   *                                displayport built by combining the base
289
   *                                rect with the margins, in either direction
290
   * @param aPriority a priority value to determine which margins take effect
291
   *                  when multiple callers specify margins
292
   * @param aRepaintMode whether to schedule a paint after setting the margins
293
   * @return true if the new margins were applied.
294
   */
295
  static bool SetDisplayPortMargins(nsIContent* aContent,
296
                                    nsIPresShell* aPresShell,
297
                                    const ScreenMargin& aMargins,
298
                                    uint32_t aPriority = 0,
299
                                    RepaintMode aRepaintMode = RepaintMode::Repaint);
300
301
  /**
302
   * Set the display port base rect for given element to be used with display
303
   * port margins.
304
   * SetDisplayPortBaseIfNotSet is like SetDisplayPortBase except it only sets
305
   * the display port base to aBase if no display port base is currently set.
306
   */
307
  static void SetDisplayPortBase(nsIContent* aContent, const nsRect& aBase);
308
  static void SetDisplayPortBaseIfNotSet(nsIContent* aContent, const nsRect& aBase);
309
310
  /**
311
   * Get the critical display port for the given element.
312
   */
313
  static bool GetCriticalDisplayPort(nsIContent* aContent, nsRect* aResult);
314
315
  /**
316
   * Check whether the given element has a critical display port.
317
   */
318
  static bool HasCriticalDisplayPort(nsIContent* aContent);
319
320
  /**
321
   * If low-precision painting is turned on, delegates to GetCriticalDisplayPort.
322
   * Otherwise, delegates to GetDisplayPort.
323
   */
324
  static bool GetHighResolutionDisplayPort(nsIContent* aContent, nsRect* aResult);
325
326
  /**
327
   * Remove the displayport for the given element.
328
   */
329
  static void RemoveDisplayPort(nsIContent* aContent);
330
331
  /**
332
   * Use heuristics to figure out the child list that
333
   * aChildFrame is currently in.
334
   */
335
  static mozilla::layout::FrameChildListID GetChildListNameFor(nsIFrame* aChildFrame);
336
337
  /**
338
   * Returns the ::before pseudo-element for aContent, if any.
339
   */
340
  static mozilla::dom::Element* GetBeforePseudo(const nsIContent* aContent);
341
342
  /**
343
   * Returns the frame corresponding to the ::before pseudo-element for
344
   * aContent, if any.
345
   */
346
  static nsIFrame* GetBeforeFrame(const nsIContent* aContent);
347
348
  /**
349
   * Returns the ::after pseudo-element for aContent, if any.
350
   */
351
  static mozilla::dom::Element* GetAfterPseudo(const nsIContent* aContent);
352
353
  /**
354
   * Returns the frame corresponding to the ::after pseudo-element for aContent,
355
   * if any.
356
   */
357
  static nsIFrame* GetAfterFrame(const nsIContent* aContent);
358
359
  /**
360
   * Given a frame, search up the frame tree until we find an
361
   * ancestor that (or the frame itself) is of type aFrameType, if any.
362
   *
363
   * @param aFrame the frame to start at
364
   * @param aFrameType the frame type to look for
365
   * @param aStopAt a frame to stop at after we checked it
366
   * @return a frame of the given type or nullptr if no
367
   *         such ancestor exists
368
   */
369
  static nsIFrame* GetClosestFrameOfType(nsIFrame* aFrame,
370
                                         mozilla::LayoutFrameType aFrameType,
371
                                         nsIFrame* aStopAt = nullptr);
372
373
  /**
374
   * Given a frame, search up the frame tree until we find an
375
   * ancestor that (or the frame itself) is a "Page" frame, if any.
376
   *
377
   * @param aFrame the frame to start at
378
   * @return a frame of type mozilla::LayoutFrameType::Page or nullptr if no
379
   *         such ancestor exists
380
   */
381
  static nsIFrame* GetPageFrame(nsIFrame* aFrame);
382
383
  /**
384
   * Given a frame which is the primary frame for an element,
385
   * return the frame that has the non-pseudoelement ComputedStyle for
386
   * the content.
387
   * This is aPrimaryFrame itself except for tableWrapper frames.
388
   *
389
   * Given a non-null input, this will return null if and only if its
390
   * argument is a table wrapper frame that is mid-destruction (and its
391
   * table frame has been destroyed).
392
   */
393
  static nsIFrame* GetStyleFrame(nsIFrame* aPrimaryFrame);
394
395
  /**
396
   * Given a content node,
397
   * return the frame that has the non-pseudoelement ComputedStyle for
398
   * the content.  May return null.
399
   * This is aContent->GetPrimaryFrame() except for tableWrapper frames.
400
   */
401
  static nsIFrame* GetStyleFrame(const nsIContent* aContent);
402
403
  /**
404
   * Gets the real primary frame associated with the content object.
405
   *
406
   * In the case of absolutely positioned elements and floated elements,
407
   * the real primary frame is the frame that is out of the flow and not the
408
   * placeholder frame.
409
   */
410
  static nsIFrame* GetRealPrimaryFrameFor(const nsIContent* aContent);
411
412
#ifdef DEBUG
413
  // TODO: remove, see bug 598468.
414
  static bool gPreventAssertInCompareTreePosition;
415
#endif // DEBUG
416
417
  /**
418
   * CompareTreePosition determines whether aContent1 comes before or
419
   * after aContent2 in a preorder traversal of the content tree.
420
   *
421
   * @param aCommonAncestor either null, or a common ancestor of
422
   *                        aContent1 and aContent2.  Actually this is
423
   *                        only a hint; if it's not an ancestor of
424
   *                        aContent1 or aContent2, this function will
425
   *                        still work, but it will be slower than
426
   *                        normal.
427
   * @return < 0 if aContent1 is before aContent2
428
   *         > 0 if aContent1 is after aContent2,
429
   *         0 otherwise (meaning they're the same, or they're in
430
   *           different documents)
431
   */
432
  static int32_t CompareTreePosition(nsIContent* aContent1,
433
                                     nsIContent* aContent2,
434
                                     const nsIContent* aCommonAncestor = nullptr)
435
0
  {
436
0
    return DoCompareTreePosition(aContent1, aContent2, -1, 1, aCommonAncestor);
437
0
  }
438
439
  /*
440
   * More generic version of |CompareTreePosition|.  |aIf1Ancestor|
441
   * gives the value to return when 1 is an ancestor of 2, and likewise
442
   * for |aIf2Ancestor|.  Passing (-1, 1) gives preorder traversal
443
   * order, and (1, -1) gives postorder traversal order.
444
   */
445
  static int32_t DoCompareTreePosition(nsIContent* aContent1,
446
                                       nsIContent* aContent2,
447
                                       int32_t aIf1Ancestor,
448
                                       int32_t aIf2Ancestor,
449
                                       const nsIContent* aCommonAncestor = nullptr);
450
451
  /**
452
   * CompareTreePosition determines whether aFrame1 comes before or
453
   * after aFrame2 in a preorder traversal of the frame tree, where out
454
   * of flow frames are treated as children of their placeholders. This is
455
   * basically the same ordering as DoCompareTreePosition(nsIContent*) except
456
   * that it handles anonymous content properly and there are subtleties with
457
   * continuations.
458
   *
459
   * @param aCommonAncestor either null, or a common ancestor of
460
   *                        aContent1 and aContent2.  Actually this is
461
   *                        only a hint; if it's not an ancestor of
462
   *                        aContent1 or aContent2, this function will
463
   *                        still work, but it will be slower than
464
   *                        normal.
465
   * @return < 0 if aContent1 is before aContent2
466
   *         > 0 if aContent1 is after aContent2,
467
   *         0 otherwise (meaning they're the same, or they're in
468
   *           different frame trees)
469
   */
470
  static int32_t CompareTreePosition(nsIFrame* aFrame1,
471
                                     nsIFrame* aFrame2,
472
                                     nsIFrame* aCommonAncestor = nullptr)
473
  {
474
    return DoCompareTreePosition(aFrame1, aFrame2, -1, 1, aCommonAncestor);
475
  }
476
477
  static int32_t CompareTreePosition(nsIFrame* aFrame1,
478
                                     nsIFrame* aFrame2,
479
                                     nsTArray<nsIFrame*>& aFrame2Ancestors,
480
                                     nsIFrame* aCommonAncestor = nullptr)
481
  {
482
    return DoCompareTreePosition(aFrame1, aFrame2, aFrame2Ancestors,
483
                                 -1, 1, aCommonAncestor);
484
  }
485
486
  /*
487
   * More generic version of |CompareTreePosition|.  |aIf1Ancestor|
488
   * gives the value to return when 1 is an ancestor of 2, and likewise
489
   * for |aIf2Ancestor|.  Passing (-1, 1) gives preorder traversal
490
   * order, and (1, -1) gives postorder traversal order.
491
   */
492
  static int32_t DoCompareTreePosition(nsIFrame* aFrame1,
493
                                       nsIFrame* aFrame2,
494
                                       int32_t aIf1Ancestor,
495
                                       int32_t aIf2Ancestor,
496
                                       nsIFrame* aCommonAncestor = nullptr);
497
498
  static nsIFrame* FillAncestors(nsIFrame* aFrame,
499
                                 nsIFrame* aStopAtAncestor,
500
                                 nsTArray<nsIFrame*>* aAncestors);
501
502
  static int32_t DoCompareTreePosition(nsIFrame* aFrame1,
503
                                       nsIFrame* aFrame2,
504
                                       nsTArray<nsIFrame*>& aFrame2Ancestors,
505
                                       int32_t aIf1Ancestor,
506
                                       int32_t aIf2Ancestor,
507
                                       nsIFrame* aCommonAncestor);
508
509
  /**
510
   * LastContinuationWithChild gets the last continuation in aFrame's chain
511
   * that has a child, or the first continuation if the frame has no children.
512
   */
513
  static nsContainerFrame* LastContinuationWithChild(nsContainerFrame* aFrame);
514
515
  /**
516
   * GetLastSibling simply finds the last sibling of aFrame, or returns nullptr if
517
   * aFrame is null.
518
   */
519
  static nsIFrame* GetLastSibling(nsIFrame* aFrame);
520
521
  /**
522
   * FindSiblingViewFor locates the child of aParentView that aFrame's
523
   * view should be inserted 'above' (i.e., before in sibling view
524
   * order).  This is the first child view of aParentView whose
525
   * corresponding content is before aFrame's content (view siblings
526
   * are in reverse content order).
527
   */
528
  static nsView* FindSiblingViewFor(nsView* aParentView, nsIFrame* aFrame);
529
530
  /**
531
   * Get the parent of aFrame. If aFrame is the root frame for a document,
532
   * and the document has a parent document in the same view hierarchy, then
533
   * we try to return the subdocumentframe in the parent document.
534
   * @param aExtraOffset [in/out] if non-null, then as we cross documents
535
   * an extra offset may be required and it will be added to aCrossDocOffset.
536
   * Be careful dealing with this extra offset as it is in app units of the
537
   * parent document, which may have a different app units per dev pixel ratio
538
   * than the child document.
539
   */
540
  static nsIFrame* GetCrossDocParentFrame(const nsIFrame* aFrame,
541
                                          nsPoint* aCrossDocOffset = nullptr);
542
543
  /**
544
   * IsProperAncestorFrame checks whether aAncestorFrame is an ancestor
545
   * of aFrame and not equal to aFrame.
546
   * @param aCommonAncestor nullptr, or a common ancestor of aFrame and
547
   * aAncestorFrame. If non-null, this can bound the search and speed up
548
   * the function
549
   */
550
  static bool IsProperAncestorFrame(nsIFrame* aAncestorFrame, nsIFrame* aFrame,
551
                                      nsIFrame* aCommonAncestor = nullptr);
552
553
  /**
554
   * Like IsProperAncestorFrame, but looks across document boundaries.
555
   *
556
   * Just like IsAncestorFrameCrossDoc, except that it returns false when
557
   * aFrame == aAncestorFrame.
558
   */
559
  static bool IsProperAncestorFrameCrossDoc(nsIFrame* aAncestorFrame, nsIFrame* aFrame,
560
                                              nsIFrame* aCommonAncestor = nullptr);
561
562
  /**
563
   * IsAncestorFrameCrossDoc checks whether aAncestorFrame is an ancestor
564
   * of aFrame or equal to aFrame, looking across document boundaries.
565
   * @param aCommonAncestor nullptr, or a common ancestor of aFrame and
566
   * aAncestorFrame. If non-null, this can bound the search and speed up
567
   * the function.
568
   *
569
   * Just like IsProperAncestorFrameCrossDoc, except that it returns true when
570
   * aFrame == aAncestorFrame.
571
   */
572
  static bool IsAncestorFrameCrossDoc(const nsIFrame* aAncestorFrame, const nsIFrame* aFrame,
573
                                        const nsIFrame* aCommonAncestor = nullptr);
574
575
  /**
576
   * Sets the fixed-pos metadata properties on aLayer.
577
   * aAnchorRect is the basic anchor rectangle. If aFixedPosFrame is not a viewport
578
   * frame, then we pick a corner of aAnchorRect to as the anchor point for the
579
   * fixed-pos layer (i.e. the point to remain stable during zooming), based
580
   * on which of the fixed-pos frame's CSS absolute positioning offset
581
   * properties (top, left, right, bottom) are auto. aAnchorRect is in the
582
   * coordinate space of aLayer's container layer (i.e. relative to the reference
583
   * frame of the display item which is building aLayer's container layer).
584
   */
585
  static void SetFixedPositionLayerData(Layer* aLayer, const nsIFrame* aViewportFrame,
586
                                        const nsRect& aAnchorRect,
587
                                        const nsIFrame* aFixedPosFrame,
588
                                        nsPresContext* aPresContext,
589
                                        const ContainerLayerParameters& aContainerParameters);
590
591
  /**
592
   * Get the scroll id for the root scrollframe of the presshell of the given
593
   * prescontext. Returns NULL_SCROLL_ID if it couldn't be found.
594
   */
595
  static FrameMetrics::ViewID ScrollIdForRootScrollFrame(nsPresContext* aPresContext);
596
597
  /**
598
   * Return true if aPresContext's viewport has a displayport.
599
   */
600
  static bool ViewportHasDisplayPort(nsPresContext* aPresContext);
601
602
  /**
603
   * Return true if aFrame is a fixed-pos frame and is a child of a viewport
604
   * which has a displayport. These frames get special treatment from the compositor.
605
   * aDisplayPort, if non-null, is set to the display port rectangle (relative to
606
   * the viewport).
607
   */
608
  static bool IsFixedPosFrameInDisplayPort(const nsIFrame* aFrame);
609
610
  /**
611
    * GetScrollableFrameFor returns the scrollable frame for a scrolled frame
612
    */
613
  static nsIScrollableFrame* GetScrollableFrameFor(const nsIFrame *aScrolledFrame);
614
615
  /**
616
   * GetNearestScrollableFrameForDirection locates the first ancestor of
617
   * aFrame (or aFrame itself) that is scrollable with overflow:scroll or
618
   * overflow:auto in the given direction and where either the scrollbar for
619
   * that direction is visible or the frame can be scrolled by some
620
   * positive amount in that direction.
621
   * The search extends across document boundaries.
622
   *
623
   * @param  aFrame the frame to start with
624
   * @param  aDirection Whether it's for horizontal or vertical scrolling.
625
   * @return the nearest scrollable frame or nullptr if not found
626
   */
627
  enum Direction { eHorizontal, eVertical };
628
  static nsIScrollableFrame* GetNearestScrollableFrameForDirection(nsIFrame* aFrame,
629
                                                                   Direction aDirection);
630
631
  enum {
632
    /**
633
     * If the SCROLLABLE_SAME_DOC flag is set, then we only walk the frame tree
634
     * up to the root frame in the current document.
635
     */
636
    SCROLLABLE_SAME_DOC = 0x01,
637
    /**
638
     * If the SCROLLABLE_INCLUDE_HIDDEN flag is set then we allow
639
     * overflow:hidden scrollframes to be returned as scrollable frames.
640
     */
641
    SCROLLABLE_INCLUDE_HIDDEN = 0x02,
642
    /**
643
     * If the SCROLLABLE_ONLY_ASYNC_SCROLLABLE flag is set, then we only
644
     * want to match scrollable frames for which WantAsyncScroll() returns
645
     * true.
646
     */
647
    SCROLLABLE_ONLY_ASYNC_SCROLLABLE = 0x04,
648
    /**
649
     * If the SCROLLABLE_ALWAYS_MATCH_ROOT flag is set, then we will always
650
     * return the root scrollable frame for the root document (in the current
651
     * process) if we encounter it, whether or not it is async scrollable or
652
     * overflow: hidden.
653
     */
654
    SCROLLABLE_ALWAYS_MATCH_ROOT = 0x08,
655
    /**
656
     * If the SCROLLABLE_FIXEDPOS_FINDS_ROOT flag is set, then for fixed-pos
657
     * frames that are in the root document (in the current process) return the
658
     * root scrollable frame for that document.
659
     */
660
    SCROLLABLE_FIXEDPOS_FINDS_ROOT = 0x10
661
  };
662
  /**
663
   * GetNearestScrollableFrame locates the first ancestor of aFrame
664
   * (or aFrame itself) that is scrollable with overflow:scroll or
665
   * overflow:auto in some direction.
666
   *
667
   * @param  aFrame the frame to start with
668
   * @param  aFlags if SCROLLABLE_SAME_DOC is set, do not search across
669
   * document boundaries. If SCROLLABLE_INCLUDE_HIDDEN is set, include
670
   * frames scrollable with overflow:hidden.
671
   * @return the nearest scrollable frame or nullptr if not found
672
   */
673
  static nsIScrollableFrame* GetNearestScrollableFrame(nsIFrame* aFrame,
674
                                                       uint32_t aFlags = 0);
675
676
  /**
677
   * GetScrolledRect returns the range of allowable scroll offsets
678
   * for aScrolledFrame, assuming the scrollable overflow area is
679
   * aScrolledFrameOverflowArea and the scrollport size is aScrollPortSize.
680
   * aDirection is either NS_STYLE_DIRECTION_LTR or NS_STYLE_DIRECTION_RTL.
681
   */
682
  static nsRect GetScrolledRect(nsIFrame* aScrolledFrame,
683
                                const nsRect& aScrolledFrameOverflowArea,
684
                                const nsSize& aScrollPortSize,
685
                                uint8_t aDirection);
686
687
  /**
688
   * HasPseudoStyle returns true if aContent (whose primary style
689
   * context is aComputedStyle) has the aPseudoElement pseudo-style
690
   * attached to it; returns false otherwise.
691
   *
692
   * @param aContent the content node we're looking at
693
   * @param aComputedStyle aContent's ComputedStyle
694
   * @param aPseudoElement the id of the pseudo style we care about
695
   * @param aPresContext the presentation context
696
   * @return whether aContent has aPseudoElement style attached to it
697
   */
698
  static bool HasPseudoStyle(nsIContent* aContent,
699
                             ComputedStyle* aComputedStyle,
700
                             mozilla::CSSPseudoElementType aPseudoElement,
701
                             nsPresContext* aPresContext);
702
703
  /**
704
   * If this frame is a placeholder for a float, then return the float,
705
   * otherwise return nullptr.  aPlaceholder must be a placeholder frame.
706
   */
707
  static nsIFrame* GetFloatFromPlaceholder(nsIFrame* aPlaceholder);
708
709
  // Combine aNewBreakType with aOrigBreakType, but limit the break types
710
  // to StyleClear::Left, Right, Both.
711
  static mozilla::StyleClear CombineBreakType(mozilla::StyleClear aOrigBreakType,
712
                                              mozilla::StyleClear aNewBreakType);
713
714
  /**
715
   * Get the coordinates of a given DOM mouse event, relative to a given
716
   * frame. Works only for DOM events generated by WidgetGUIEvents.
717
   * @param aDOMEvent the event
718
   * @param aFrame the frame to make coordinates relative to
719
   * @return the point, or (NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE) if
720
   * for some reason the coordinates for the mouse are not known (e.g.,
721
   * the event is not a GUI event).
722
   */
723
  static nsPoint GetDOMEventCoordinatesRelativeTo(mozilla::dom::Event* aDOMEvent,
724
                                                  nsIFrame* aFrame);
725
726
  /**
727
   * Get the coordinates of a given native mouse event, relative to a given
728
   * frame.
729
   * @param aEvent the event
730
   * @param aFrame the frame to make coordinates relative to
731
   * @return the point, or (NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE) if
732
   * for some reason the coordinates for the mouse are not known (e.g.,
733
   * the event is not a GUI event).
734
   */
735
  static nsPoint GetEventCoordinatesRelativeTo(
736
                   const mozilla::WidgetEvent* aEvent,
737
                   nsIFrame* aFrame);
738
739
  /**
740
   * Get the coordinates of a given point relative to an event and a
741
   * given frame.
742
   * @param aEvent the event
743
   * @param aPoint the point to get the coordinates relative to
744
   * @param aFrame the frame to make coordinates relative to
745
   * @return the point, or (NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE) if
746
   * for some reason the coordinates for the mouse are not known (e.g.,
747
   * the event is not a GUI event).
748
   */
749
  static nsPoint GetEventCoordinatesRelativeTo(
750
                   const mozilla::WidgetEvent* aEvent,
751
                   const mozilla::LayoutDeviceIntPoint& aPoint,
752
                   nsIFrame* aFrame);
753
754
  /**
755
   * Get the coordinates of a given point relative to a widget and a
756
   * given frame.
757
   * @param aWidget the event src widget
758
   * @param aPoint the point to get the coordinates relative to
759
   * @param aFrame the frame to make coordinates relative to
760
   * @return the point, or (NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE) if
761
   * for some reason the coordinates for the mouse are not known (e.g.,
762
   * the event is not a GUI event).
763
   */
764
  static nsPoint GetEventCoordinatesRelativeTo(nsIWidget* aWidget,
765
                                               const mozilla::LayoutDeviceIntPoint& aPoint,
766
                                               nsIFrame* aFrame);
767
768
  /**
769
   * Get the popup frame of a given native mouse event.
770
   * @param aPresContext only check popups within aPresContext or a descendant
771
   * @param aEvent  the event.
772
   * @return        Null, if there is no popup frame at the point, otherwise,
773
   *                returns top-most popup frame at the point.
774
   */
775
  static nsIFrame* GetPopupFrameForEventCoordinates(
776
                     nsPresContext* aPresContext,
777
                     const mozilla::WidgetEvent* aEvent);
778
779
  /**
780
   * Translate from widget coordinates to the view's coordinates
781
   * @param aPresContext the PresContext for the view
782
   * @param aWidget the widget
783
   * @param aPt the point relative to the widget
784
   * @param aView  view to which returned coordinates are relative
785
   * @return the point in the view's coordinates
786
   */
787
  static nsPoint TranslateWidgetToView(nsPresContext* aPresContext,
788
                                       nsIWidget* aWidget,
789
                                       const mozilla::LayoutDeviceIntPoint& aPt,
790
                                       nsView* aView);
791
792
  /**
793
   * Translate from view coordinates to the widget's coordinates.
794
   * @param aPresContext the PresContext for the view
795
   * @param aView the view
796
   * @param aPt the point relative to the view
797
   * @param aWidget the widget to which returned coordinates are relative
798
   * @return the point in the view's coordinates
799
   */
800
  static mozilla::LayoutDeviceIntPoint
801
    TranslateViewToWidget(nsPresContext* aPresContext,
802
                          nsView* aView, nsPoint aPt,
803
                          nsIWidget* aWidget);
804
805
  static mozilla::LayoutDeviceIntPoint
806
    WidgetToWidgetOffset(nsIWidget* aFromWidget, nsIWidget* aToWidget);
807
808
  enum FrameForPointFlags {
809
    /**
810
     * When set, paint suppression is ignored, so we'll return non-root page
811
     * elements even if paint suppression is stopping them from painting.
812
     */
813
    IGNORE_PAINT_SUPPRESSION = 0x01,
814
    /**
815
     * When set, clipping due to the root scroll frame (and any other viewport-
816
     * related clipping) is ignored.
817
     */
818
    IGNORE_ROOT_SCROLL_FRAME = 0x02,
819
    /**
820
     * When set, return only content in the same document as aFrame.
821
     */
822
    IGNORE_CROSS_DOC = 0x04,
823
    /**
824
     * When set, return only content that is actually visible.
825
     */
826
    ONLY_VISIBLE = 0x08
827
  };
828
829
  /**
830
   * Given aFrame, the root frame of a stacking context, find its descendant
831
   * frame under the point aPt that receives a mouse event at that location,
832
   * or nullptr if there is no such frame.
833
   * @param aPt the point, relative to the frame origin
834
   * @param aFlags some combination of FrameForPointFlags
835
   */
836
  static nsIFrame* GetFrameForPoint(nsIFrame* aFrame, nsPoint aPt,
837
                                    uint32_t aFlags = 0);
838
839
  /**
840
   * Given aFrame, the root frame of a stacking context, find all descendant
841
   * frames under the area of a rectangle that receives a mouse event,
842
   * or nullptr if there is no such frame.
843
   * @param aRect the rect, relative to the frame origin
844
   * @param aOutFrames an array to add all the frames found
845
   * @param aFlags some combination of FrameForPointFlags
846
   */
847
  static nsresult GetFramesForArea(nsIFrame* aFrame, const nsRect& aRect,
848
                                   nsTArray<nsIFrame*> &aOutFrames,
849
                                   uint32_t aFlags = 0);
850
851
  /**
852
   * Transform aRect relative to aFrame up to the coordinate system of
853
   * aAncestor. Computes the bounding-box of the true quadrilateral.
854
   * Pass non-null aPreservesAxisAlignedRectangles and it will be set to true if
855
   * we only need to use a 2d transform that PreservesAxisAlignedRectangles().
856
   *
857
   * |aMatrixCache| allows for optimizations in recomputing the same matrix over
858
   * and over. The argument can be one of the following values:
859
   * nullptr (the default) - No optimization; the transform matrix is computed on
860
   *   every call to this function.
861
   * non-null pointer to an empty Maybe<Matrix4x4> - Upon return, the Maybe is
862
   *   filled with the transform matrix that was computed. This can then be passed
863
   *   in to subsequent calls with the same source and destination frames to avoid
864
   *   recomputing the matrix.
865
   * non-null pointer to a non-empty Matrix4x4 - The provided matrix will be used
866
   *   as the transform matrix and applied to the rect.
867
   */
868
  static nsRect TransformFrameRectToAncestor(const nsIFrame* aFrame,
869
                                             const nsRect& aRect,
870
                                             const nsIFrame* aAncestor,
871
                                             bool* aPreservesAxisAlignedRectangles = nullptr,
872
                                             mozilla::Maybe<Matrix4x4Flagged>* aMatrixCache = nullptr,
873
                                             bool aStopAtStackingContextAndDisplayPortAndOOFFrame = false,
874
                                             nsIFrame** aOutAncestor = nullptr);
875
876
877
  /**
878
   * Gets the transform for aFrame relative to aAncestor. Pass null for
879
   * aAncestor to go up to the root frame. aInCSSUnits set to true will
880
   * return CSS units, set to false (the default) will return App units.
881
   */
882
  static Matrix4x4Flagged GetTransformToAncestor(const nsIFrame *aFrame,
883
                                          const nsIFrame *aAncestor,
884
                                          uint32_t aFlags = 0,
885
                                          nsIFrame** aOutAncestor = nullptr);
886
887
  /**
888
   * Gets the scale factors of the transform for aFrame relative to the root
889
   * frame if this transform is 2D, or the identity scale factors otherwise.
890
   */
891
  static gfxSize GetTransformToAncestorScale(nsIFrame* aFrame);
892
893
  /**
894
   * Gets the scale factors of the transform for aFrame relative to the root
895
   * frame if this transform is 2D, or the identity scale factors otherwise.
896
   * If some frame on the path from aFrame to the display root frame may have an
897
   * animated scale, returns the identity scale factors.
898
   */
899
  static gfxSize GetTransformToAncestorScaleExcludingAnimated(nsIFrame* aFrame);
900
901
  /**
902
   * Find the nearest common ancestor frame for aFrame1 and aFrame2. The
903
   * ancestor frame could be cross-doc.
904
   */
905
  static nsIFrame* FindNearestCommonAncestorFrame(nsIFrame* aFrame1,
906
                                                  nsIFrame* aFrame2);
907
908
  /**
909
   * Transforms a list of CSSPoints from aFromFrame to aToFrame, taking into
910
   * account all relevant transformations on the frames up to (but excluding)
911
   * their nearest common ancestor.
912
   * If we encounter a transform that we need to invert but which is
913
   * non-invertible, we return NONINVERTIBLE_TRANSFORM. If the frames have
914
   * no common ancestor, we return NO_COMMON_ANCESTOR.
915
   * If this returns TRANSFORM_SUCCEEDED, the points in aPoints are transformed
916
   * in-place, otherwise they are untouched.
917
   */
918
  enum TransformResult {
919
    TRANSFORM_SUCCEEDED,
920
    NO_COMMON_ANCESTOR,
921
    NONINVERTIBLE_TRANSFORM
922
  };
923
  static TransformResult TransformPoints(nsIFrame* aFromFrame, nsIFrame* aToFrame,
924
                                         uint32_t aPointCount, CSSPoint* aPoints);
925
926
  /**
927
   * Same as above function, but transform points in app units and
928
   * handle 1 point per call.
929
   */
930
  static TransformResult TransformPoint(nsIFrame* aFromFrame, nsIFrame* aToFrame,
931
                                        nsPoint& aPoint);
932
933
  /**
934
   * Transforms a rect from aFromFrame to aToFrame. In app units.
935
   * Returns the bounds of the actual rect if the transform requires rotation
936
   * or anything complex like that.
937
   */
938
  static TransformResult TransformRect(nsIFrame* aFromFrame, nsIFrame* aToFrame,
939
                                       nsRect& aRect);
940
941
  /**
942
   * Converts app units to pixels (with optional snapping) and appends as a
943
   * translation to aTransform.
944
   */
945
  static void PostTranslate(Matrix4x4& aTransform, const nsPoint& aOrigin, float aAppUnitsPerPixel, bool aRounded);
946
947
  /**
948
   * Get the border-box of aElement's primary frame, transformed it to be
949
   * relative to aFrame.
950
   */
951
  static nsRect GetRectRelativeToFrame(mozilla::dom::Element* aElement,
952
                                       nsIFrame* aFrame);
953
954
  /**
955
   * Returns true if aRect with border inflation of size aInflateSize contains
956
   * aPoint.
957
   */
958
  static bool ContainsPoint(const nsRect& aRect, const nsPoint& aPoint,
959
                            nscoord aInflateSize);
960
961
  /**
962
   * Clamp aRect relative to aFrame to the scroll frames boundary searching from
963
   * aFrame.
964
   */
965
  static nsRect ClampRectToScrollFrames(nsIFrame* aFrame,
966
                                        const nsRect& aRect);
967
968
  /**
969
   * Return true if a "layer transform" could be computed for aFrame,
970
   * and optionally return the computed transform.  The returned
971
   * transform is what would be set on the layer currently if a layers
972
   * transaction were opened at the time this helper is called.
973
   */
974
  static bool GetLayerTransformForFrame(nsIFrame* aFrame,
975
                                        Matrix4x4Flagged* aTransform);
976
977
  /**
978
   * Given a point in the global coordinate space, returns that point expressed
979
   * in the coordinate system of aFrame.  This effectively inverts all
980
   * transforms between this point and the root frame.
981
   *
982
   * @param aFrame The frame that acts as the coordinate space container.
983
   * @param aPoint The point, in the global space, to get in the frame-local space.
984
   * @return aPoint, expressed in aFrame's canonical coordinate space.
985
   */
986
  static nsPoint TransformRootPointToFrame(nsIFrame* aFrame,
987
                                           const nsPoint &aPoint)
988
  {
989
    return TransformAncestorPointToFrame(aFrame, aPoint, nullptr);
990
  }
991
992
  /**
993
   * Transform aPoint relative to aAncestor down to the coordinate system of
994
   * aFrame.
995
   */
996
  static nsPoint TransformAncestorPointToFrame(nsIFrame* aFrame,
997
                                               const nsPoint& aPoint,
998
                                               nsIFrame* aAncestor);
999
1000
  /**
1001
   * Helper function that, given a rectangle and a matrix, returns the smallest
1002
   * rectangle containing the image of the source rectangle.
1003
   *
1004
   * @param aBounds The rectangle to transform.
1005
   * @param aMatrix The matrix to transform it with.
1006
   * @param aFactor The number of app units per graphics unit.
1007
   * @return The smallest rect that contains the image of aBounds.
1008
   */
1009
  static nsRect MatrixTransformRect(const nsRect &aBounds,
1010
                                    const Matrix4x4 &aMatrix, float aFactor);
1011
  static nsRect MatrixTransformRect(const nsRect &aBounds,
1012
                                    const Matrix4x4Flagged &aMatrix, float aFactor);
1013
1014
  /**
1015
   * Helper function that, given a point and a matrix, returns the image
1016
   * of that point under the matrix transform.
1017
   *
1018
   * @param aPoint The point to transform.
1019
   * @param aMatrix The matrix to transform it with.
1020
   * @param aFactor The number of app units per graphics unit.
1021
   * @return The image of the point under the transform.
1022
   */
1023
  static nsPoint MatrixTransformPoint(const nsPoint &aPoint,
1024
                                      const Matrix4x4 &aMatrix, float aFactor);
1025
1026
  /**
1027
   * Given a graphics rectangle in graphics space, return a rectangle in
1028
   * app space that contains the graphics rectangle, rounding out as necessary.
1029
   *
1030
   * @param aRect The graphics rect to round outward.
1031
   * @param aFactor The number of app units per graphics unit.
1032
   * @return The smallest rectangle in app space that contains aRect.
1033
   */
1034
  static nsRect RoundGfxRectToAppRect(const Rect &aRect, float aFactor);
1035
1036
  /**
1037
   * Given a graphics rectangle in graphics space, return a rectangle in
1038
   * app space that contains the graphics rectangle, rounding out as necessary.
1039
   *
1040
   * @param aRect The graphics rect to round outward.
1041
   * @param aFactor The number of app units per graphics unit.
1042
   * @return The smallest rectangle in app space that contains aRect.
1043
   */
1044
  static nsRect RoundGfxRectToAppRect(const gfxRect &aRect, float aFactor);
1045
1046
  /**
1047
   * Returns a subrectangle of aContainedRect that is entirely inside the rounded
1048
   * rect. Complex cases are handled conservatively by returning a smaller
1049
   * rect than necessary.
1050
   */
1051
  static nsRegion RoundedRectIntersectRect(const nsRect& aRoundedRect,
1052
                                           const nscoord aRadii[8],
1053
                                           const nsRect& aContainedRect);
1054
  static nsIntRegion RoundedRectIntersectIntRect(const nsIntRect& aRoundedRect,
1055
                                                 const RectCornerRadii& aCornerRadii,
1056
                                                 const nsIntRect& aContainedRect);
1057
1058
  /**
1059
   * Return whether any part of aTestRect is inside of the rounded
1060
   * rectangle formed by aBounds and aRadii (which are indexed by the
1061
   * enum HalfCorner constants in gfx/2d/Types.h). This is precise.
1062
   */
1063
  static bool RoundedRectIntersectsRect(const nsRect& aRoundedRect,
1064
                                        const nscoord aRadii[8],
1065
                                        const nsRect& aTestRect);
1066
1067
  static bool MaybeCreateDisplayPortInFirstScrollFrameEncountered(
1068
    nsIFrame* aFrame, nsDisplayListBuilder& aBuilder);
1069
1070
1071
  enum class PaintFrameFlags : uint32_t {
1072
    PAINT_IN_TRANSFORM = 0x01,
1073
    PAINT_SYNC_DECODE_IMAGES = 0x02,
1074
    PAINT_WIDGET_LAYERS = 0x04,
1075
    PAINT_IGNORE_SUPPRESSION = 0x08,
1076
    PAINT_DOCUMENT_RELATIVE = 0x10,
1077
    PAINT_HIDE_CARET = 0x20,
1078
    PAINT_TO_WINDOW = 0x40,
1079
    PAINT_EXISTING_TRANSACTION = 0x80,
1080
    PAINT_NO_COMPOSITE = 0x100,
1081
    PAINT_COMPRESSED = 0x200
1082
  };
1083
1084
  /**
1085
   * Given aFrame, the root frame of a stacking context, paint it and its
1086
   * descendants to aRenderingContext.
1087
   * @param aRenderingContext a rendering context translated so that (0,0)
1088
   * is the origin of aFrame; for best results, (0,0) should transform
1089
   * to pixel-aligned coordinates. This can be null, in which case
1090
   * aFrame must be a "display root" (root frame for a root document,
1091
   * or the root of a popup) with an associated widget and we draw using
1092
   * the layer manager for the frame's widget.
1093
   * @param aDirtyRegion the region that must be painted, in the coordinates
1094
   * of aFrame.
1095
   * @param aBackstop paint the dirty area with this color before drawing
1096
   * the actual content; pass NS_RGBA(0,0,0,0) to draw no background.
1097
   * @param aBuilderMode Passed through to the display-list builder.
1098
   * @param aFlags if PAINT_IN_TRANSFORM is set, then we assume
1099
   * this is inside a transform or SVG foreignObject. If
1100
   * PAINT_SYNC_DECODE_IMAGES is set, we force synchronous decode on all
1101
   * images. If PAINT_WIDGET_LAYERS is set, aFrame must be a display root,
1102
   * and we will use the frame's widget's layer manager to paint
1103
   * even if aRenderingContext is non-null. This is useful if you want
1104
   * to force rendering to use the widget's layer manager for testing
1105
   * or speed. PAINT_WIDGET_LAYERS must be set if aRenderingContext is null.
1106
   * If PAINT_DOCUMENT_RELATIVE is used, the visible region is interpreted
1107
   * as being relative to the document (normally it's relative to the CSS
1108
   * viewport) and the document is painted as if no scrolling has occured.
1109
   * Only considered if nsIPresShell::IgnoringViewportScrolling is true.
1110
   * PAINT_TO_WINDOW sets painting to window to true on the display list
1111
   * builder even if we can't tell that we are painting to the window.
1112
   * If PAINT_EXISTING_TRANSACTION is set, then BeginTransaction() has already
1113
   * been called on aFrame's widget's layer manager and should not be
1114
   * called again.
1115
   * If PAINT_COMPRESSED is set, the FrameLayerBuilder should be set to
1116
   * compressed mode to avoid short cut optimizations.
1117
   *
1118
   * So there are three possible behaviours:
1119
   * 1) PAINT_WIDGET_LAYERS is set and aRenderingContext is null; we paint
1120
   * by calling BeginTransaction on the widget's layer manager.
1121
   * 2) PAINT_WIDGET_LAYERS is set and aRenderingContext is non-null; we
1122
   * paint by calling BeginTransactionWithTarget on the widget's layer
1123
   * manager.
1124
   * 3) PAINT_WIDGET_LAYERS is not set and aRenderingContext is non-null;
1125
   * we paint by construct a BasicLayerManager and calling
1126
   * BeginTransactionWithTarget on it. This is desirable if we're doing
1127
   * something like drawWindow in a mode where what gets rendered doesn't
1128
   * necessarily correspond to what's visible in the window; we don't
1129
   * want to mess up the widget's layer tree.
1130
   */
1131
  static nsresult PaintFrame(gfxContext* aRenderingContext, nsIFrame* aFrame,
1132
                             const nsRegion& aDirtyRegion, nscolor aBackstop,
1133
                             nsDisplayListBuilderMode aBuilderMode,
1134
                             PaintFrameFlags aFlags = PaintFrameFlags(0));
1135
1136
  /**
1137
   * Uses a binary search for find where the cursor falls in the line of text
1138
   * It also keeps track of the part of the string that has already been
1139
   * measured so it doesn't have to keep measuring the same text over and over.
1140
   *
1141
   * @param "aBaseWidth" contains the width in twips of the portion
1142
   * of the text that has already been measured, and aBaseInx contains
1143
   * the index of the text that has already been measured.
1144
   *
1145
   * @param aTextWidth returns (in twips) the length of the text that falls
1146
   * before the cursor aIndex contains the index of the text where the cursor
1147
   * falls.
1148
   */
1149
  static bool
1150
  BinarySearchForPosition(DrawTarget* aDrawTarget,
1151
                          nsFontMetrics& aFontMetrics,
1152
                          const char16_t* aText,
1153
                          int32_t    aBaseWidth,
1154
                          int32_t    aBaseInx,
1155
                          int32_t    aStartInx,
1156
                          int32_t    aEndInx,
1157
                          int32_t    aCursorPos,
1158
                          int32_t&   aIndex,
1159
                          int32_t&   aTextWidth);
1160
1161
  class BoxCallback {
1162
  public:
1163
    BoxCallback() : mIncludeCaptionBoxForTable(true) {}
1164
    virtual void AddBox(nsIFrame* aFrame) = 0;
1165
    bool mIncludeCaptionBoxForTable;
1166
  };
1167
  /**
1168
   * Collect all CSS boxes associated with aFrame and its
1169
   * continuations, "drilling down" through table wrapper frames and
1170
   * some anonymous blocks since they're not real CSS boxes.
1171
   * If aFrame is null, no boxes are returned.
1172
   * SVG frames return a single box, themselves.
1173
   */
1174
  static void GetAllInFlowBoxes(nsIFrame* aFrame, BoxCallback* aCallback);
1175
1176
  /**
1177
   * Like GetAllInFlowBoxes, but doesn't include continuations.
1178
   */
1179
  static void AddBoxesForFrame(nsIFrame* aFrame, BoxCallback* aCallback);
1180
1181
  /**
1182
   * Find the first frame descendant of aFrame (including aFrame) which is
1183
   * not an anonymous frame that getBoxQuads/getClientRects should ignore.
1184
   */
1185
  static nsIFrame* GetFirstNonAnonymousFrame(nsIFrame* aFrame);
1186
1187
  class RectCallback {
1188
  public:
1189
    virtual void AddRect(const nsRect& aRect) = 0;
1190
  };
1191
1192
  struct RectAccumulator : public RectCallback {
1193
    nsRect mResultRect;
1194
    nsRect mFirstRect;
1195
    bool mSeenFirstRect;
1196
1197
    RectAccumulator();
1198
1199
    virtual void AddRect(const nsRect& aRect) override;
1200
  };
1201
1202
  struct RectListBuilder : public RectCallback {
1203
    DOMRectList* mRectList;
1204
1205
    explicit RectListBuilder(DOMRectList* aList);
1206
    virtual void AddRect(const nsRect& aRect) override;
1207
  };
1208
1209
  static nsIFrame* GetContainingBlockForClientRect(nsIFrame* aFrame);
1210
1211
  enum {
1212
    RECTS_ACCOUNT_FOR_TRANSFORMS = 0x01,
1213
    // Two bits for specifying which box type to use.
1214
    // With neither bit set (default), use the border box.
1215
    RECTS_USE_CONTENT_BOX = 0x02,
1216
    RECTS_USE_PADDING_BOX = 0x04,
1217
    RECTS_USE_MARGIN_BOX = 0x06, // both bits set
1218
    RECTS_WHICH_BOX_MASK = 0x06 // bitmask for these two bits
1219
  };
1220
  /**
1221
   * Collect all CSS boxes (content, padding, border, or margin) associated
1222
   * with aFrame and its continuations, "drilling down" through table wrapper
1223
   * frames and some anonymous blocks since they're not real CSS boxes.
1224
   * The boxes are positioned relative to aRelativeTo (taking scrolling
1225
   * into account) and passed to the callback in frame-tree order.
1226
   * If aFrame is null, no boxes are returned.
1227
   * For SVG frames, returns one rectangle, the bounding box.
1228
   * If aFlags includes RECTS_ACCOUNT_FOR_TRANSFORMS, then when converting
1229
   * the boxes into aRelativeTo coordinates, transforms (including CSS
1230
   * and SVG transforms) are taken into account.
1231
   * If aFlags includes one of RECTS_USE_CONTENT_BOX, RECTS_USE_PADDING_BOX,
1232
   * or RECTS_USE_MARGIN_BOX, the corresponding type of box is used.
1233
   * Otherwise (by default), the border box is used.
1234
   */
1235
  static void GetAllInFlowRects(nsIFrame* aFrame, const nsIFrame* aRelativeTo,
1236
                                RectCallback* aCallback, uint32_t aFlags = 0);
1237
1238
  static void GetAllInFlowRectsAndTexts(nsIFrame* aFrame,
1239
                                        const nsIFrame* aRelativeTo,
1240
                                        RectCallback* aCallback,
1241
                                        mozilla::dom::Sequence<nsString>* aTextList,
1242
                                        uint32_t aFlags = 0);
1243
1244
  /**
1245
   * Computes the union of all rects returned by GetAllInFlowRects. If
1246
   * the union is empty, returns the first rect.
1247
   * If aFlags includes RECTS_ACCOUNT_FOR_TRANSFORMS, then when converting
1248
   * the boxes into aRelativeTo coordinates, transforms (including CSS
1249
   * and SVG transforms) are taken into account.
1250
   * If aFlags includes one of RECTS_USE_CONTENT_BOX, RECTS_USE_PADDING_BOX,
1251
   * or RECTS_USE_MARGIN_BOX, the corresponding type of box is used.
1252
   * Otherwise (by default), the border box is used.
1253
   */
1254
  static nsRect GetAllInFlowRectsUnion(nsIFrame* aFrame, const nsIFrame* aRelativeTo,
1255
                                       uint32_t aFlags = 0);
1256
1257
  enum {
1258
    EXCLUDE_BLUR_SHADOWS = 0x01
1259
  };
1260
  /**
1261
   * Takes a text-shadow array from the style properties of a given nsIFrame and
1262
   * computes the union of those shadows along with the given initial rect.
1263
   * If there are no shadows, the initial rect is returned.
1264
   */
1265
  static nsRect GetTextShadowRectsUnion(const nsRect& aTextAndDecorationsRect,
1266
                                        nsIFrame* aFrame,
1267
                                        uint32_t aFlags = 0);
1268
1269
  /**
1270
   * Computes the destination rect that a given replaced element should render
1271
   * into, based on its CSS 'object-fit' and 'object-position' properties.
1272
   *
1273
   * @param aConstraintRect The constraint rect that we have at our disposal,
1274
   *                        which would e.g. be exactly filled by the image
1275
   *                        if we had "object-fit: fill".
1276
   * @param aIntrinsicSize The replaced content's intrinsic size, as reported
1277
   *                       by nsIFrame::GetIntrinsicSize().
1278
   * @param aIntrinsicRatio The replaced content's intrinsic ratio, as reported
1279
   *                        by nsIFrame::GetIntrinsicRatio().
1280
   * @param aStylePos The nsStylePosition struct that contains the 'object-fit'
1281
   *                  and 'object-position' values that we should rely on.
1282
   *                  (This should usually be the nsStylePosition for the
1283
   *                  replaced element in question, but not always. For
1284
   *                  example, a <video>'s poster-image has a dedicated
1285
   *                  anonymous element & child-frame, but we should still use
1286
   *                  the <video>'s 'object-fit' and 'object-position' values.)
1287
   * @param aAnchorPoint [out] A point that should be pixel-aligned by functions
1288
   *                           like nsLayoutUtils::DrawImage. See documentation
1289
   *                           in nsCSSRendering.h for ComputeObjectAnchorPoint.
1290
   * @return The nsRect into which we should render the replaced content (using
1291
   *         the same coordinate space as the passed-in aConstraintRect).
1292
   */
1293
  static nsRect ComputeObjectDestRect(const nsRect& aConstraintRect,
1294
                                      const IntrinsicSize& aIntrinsicSize,
1295
                                      const nsSize& aIntrinsicRatio,
1296
                                      const nsStylePosition* aStylePos,
1297
                                      nsPoint* aAnchorPoint = nullptr);
1298
1299
  /**
1300
   * Get the font metrics corresponding to the frame's style data.
1301
   * @param aFrame the frame
1302
   * @param aSizeInflation number to multiply font size by
1303
   */
1304
  static already_AddRefed<nsFontMetrics> GetFontMetricsForFrame(
1305
    const nsIFrame* aFrame, float aSizeInflation);
1306
1307
  static already_AddRefed<nsFontMetrics>
1308
    GetInflatedFontMetricsForFrame(const nsIFrame* aFrame)
1309
0
  {
1310
0
    return GetFontMetricsForFrame(aFrame, FontSizeInflationFor(aFrame));
1311
0
  }
1312
1313
  /**
1314
   * Get the font metrics corresponding to the given style data.
1315
   * @param aComputedStyle the style data
1316
   * @param aSizeInflation number to multiply font size by
1317
   */
1318
  static already_AddRefed<nsFontMetrics> GetFontMetricsForComputedStyle(
1319
      ComputedStyle* aComputedStyle,
1320
      nsPresContext* aPresContext,
1321
      float aSizeInflation = 1.0f,
1322
      uint8_t aVariantWidth = NS_FONT_VARIANT_WIDTH_NORMAL);
1323
1324
  /**
1325
   * Get the font metrics of emphasis marks corresponding to the given
1326
   * style data. The result is same as GetFontMetricsForComputedStyle
1327
   * except that the font size is scaled down to 50%.
1328
   * @param aComputedStyle the style data
1329
   * @param aInflation number to multiple font size by
1330
   */
1331
  static already_AddRefed<nsFontMetrics> GetFontMetricsOfEmphasisMarks(
1332
      ComputedStyle* aComputedStyle,
1333
      nsPresContext* aPresContext,
1334
      float aInflation)
1335
  {
1336
    return GetFontMetricsForComputedStyle(aComputedStyle,
1337
                                          aPresContext,
1338
                                          aInflation * 0.5f);
1339
  }
1340
1341
  /**
1342
   * Find the immediate child of aParent whose frame subtree contains
1343
   * aDescendantFrame. Returns null if aDescendantFrame is not a descendant
1344
   * of aParent.
1345
   */
1346
  static nsIFrame* FindChildContainingDescendant(nsIFrame* aParent, nsIFrame* aDescendantFrame);
1347
1348
  /**
1349
   * Find the nearest ancestor that's a block
1350
   */
1351
  static nsBlockFrame* FindNearestBlockAncestor(nsIFrame* aFrame);
1352
1353
  /**
1354
   * Find the nearest ancestor that's not for generated content. Will return
1355
   * aFrame if aFrame is not for generated content.
1356
   */
1357
  static nsIFrame* GetNonGeneratedAncestor(nsIFrame* aFrame);
1358
1359
  /**
1360
   * Cast aFrame to an nsBlockFrame* or return null if it's not
1361
   * an nsBlockFrame.
1362
   */
1363
  static nsBlockFrame* GetAsBlock(nsIFrame* aFrame);
1364
1365
  /*
1366
   * Whether the frame is an nsBlockFrame which is not a wrapper block.
1367
   */
1368
  static bool IsNonWrapperBlock(nsIFrame* aFrame);
1369
1370
  /**
1371
   * If aFrame is an out of flow frame, return its placeholder, otherwise
1372
   * return its parent.
1373
   */
1374
  static nsIFrame* GetParentOrPlaceholderFor(nsIFrame* aFrame);
1375
1376
  /**
1377
   * If aFrame is an out of flow frame, return its placeholder, otherwise
1378
   * return its (possibly cross-doc) parent.
1379
   */
1380
  static nsIFrame* GetParentOrPlaceholderForCrossDoc(nsIFrame* aFrame);
1381
1382
  /**
1383
   * Get a frame's next-in-flow, or, if it doesn't have one, its
1384
   * block-in-inline-split sibling.
1385
   */
1386
  static nsIFrame*
1387
  GetNextContinuationOrIBSplitSibling(nsIFrame *aFrame);
1388
1389
  /**
1390
   * Get the first frame in the continuation-plus-ib-split-sibling chain
1391
   * containing aFrame.
1392
   */
1393
  static nsIFrame*
1394
  FirstContinuationOrIBSplitSibling(const nsIFrame *aFrame);
1395
1396
  /**
1397
   * Get the last frame in the continuation-plus-ib-split-sibling chain
1398
   * containing aFrame.
1399
   */
1400
  static nsIFrame*
1401
  LastContinuationOrIBSplitSibling(const nsIFrame *aFrame);
1402
1403
  /**
1404
   * Is FirstContinuationOrIBSplitSibling(aFrame) going to return
1405
   * aFrame?
1406
   */
1407
  static bool
1408
  IsFirstContinuationOrIBSplitSibling(nsIFrame *aFrame);
1409
1410
  /**
1411
   * Check whether aFrame is a part of the scrollbar or scrollcorner of
1412
   * the root content.
1413
   * @param aFrame the checking frame.
1414
   * @return true if the frame is a part of the scrollbar or scrollcorner of
1415
   *         the root content.
1416
   */
1417
  static bool IsViewportScrollbarFrame(nsIFrame* aFrame);
1418
1419
  /**
1420
   * Get the contribution of aFrame to its containing block's intrinsic
1421
   * size for the given physical axis.  This considers the child's intrinsic
1422
   * width, its 'width', 'min-width', and 'max-width' properties (or 'height'
1423
   * variations if that's what matches aAxis) and its padding, border and margin
1424
   * in the corresponding dimension.
1425
   * @param aPercentageBasis an optional percentage basis (in aFrame's WM).
1426
   *   If the basis is indefinite in a given axis, pass a size with
1427
   *   NS_UNCONSTRAINEDSIZE in that component.
1428
   *   If you pass Nothing() a percentage basis will be calculated from aFrame's
1429
   *   ancestors' computed size in the relevant axis, if needed.
1430
   * @param aMarginBoxMinSizeClamp make the result fit within this margin-box
1431
   * size by reducing the *content size* (flooring at zero).  This is used for:
1432
   * https://drafts.csswg.org/css-grid/#min-size-auto
1433
   */
1434
  enum class IntrinsicISizeType { MIN_ISIZE, PREF_ISIZE };
1435
  static const auto MIN_ISIZE = IntrinsicISizeType::MIN_ISIZE;
1436
  static const auto PREF_ISIZE = IntrinsicISizeType::PREF_ISIZE;
1437
  enum {
1438
    IGNORE_PADDING = 0x01,
1439
    BAIL_IF_REFLOW_NEEDED = 0x02, // returns NS_INTRINSIC_WIDTH_UNKNOWN if so
1440
    MIN_INTRINSIC_ISIZE = 0x04, // use min-width/height instead of width/height
1441
  };
1442
  static nscoord
1443
  IntrinsicForAxis(mozilla::PhysicalAxis aAxis,
1444
                   gfxContext*           aRenderingContext,
1445
                   nsIFrame*             aFrame,
1446
                   IntrinsicISizeType    aType,
1447
                   const mozilla::Maybe<LogicalSize>& aPercentageBasis = mozilla::Nothing(),
1448
                   uint32_t              aFlags = 0,
1449
                   nscoord               aMarginBoxMinSizeClamp = NS_MAXSIZE);
1450
  /**
1451
   * Calls IntrinsicForAxis with aFrame's parent's inline physical axis.
1452
   */
1453
  static nscoord IntrinsicForContainer(gfxContext*         aRenderingContext,
1454
                                       nsIFrame*           aFrame,
1455
                                       IntrinsicISizeType  aType,
1456
                                       uint32_t            aFlags = 0);
1457
1458
  /**
1459
   * Get the definite size contribution of aFrame for the given physical axis.
1460
   * This considers the child's 'min-width' property (or 'min-height' if the
1461
   * given axis is vertical), and its padding, border, and margin in the
1462
   * corresponding dimension.  If the 'min-' property is 'auto' (and 'overflow'
1463
   * is 'visible') and the corresponding 'width'/'height' is definite it returns
1464
   * the "specified size" for:
1465
   * https://drafts.csswg.org/css-grid/#min-size-auto
1466
   * Note that the "transferred size" is not handled here; use IntrinsicForAxis.
1467
   * Note that any percentage in 'width'/'height' makes it count as indefinite.
1468
   * If the 'min-' property is 'auto' and 'overflow' is not 'visible', then it
1469
   * calculates the result as if the 'min-' computed value is zero.
1470
   * Otherwise, return NS_UNCONSTRAINEDSIZE.
1471
   *
1472
   * @param aPercentageBasis the percentage basis (in aFrame's WM).
1473
   *   Pass NS_UNCONSTRAINEDSIZE if the basis is indefinite in either/both axes.
1474
   * @note this behavior is specific to Grid/Flexbox (currently) so aFrame
1475
   * should be a grid/flex item.
1476
   */
1477
  static nscoord
1478
  MinSizeContributionForAxis(mozilla::PhysicalAxis aAxis,
1479
                            gfxContext*            aRC,
1480
                            nsIFrame*              aFrame,
1481
                            IntrinsicISizeType     aType,
1482
                            const LogicalSize&     aPercentageBasis,
1483
                            uint32_t               aFlags = 0);
1484
1485
  /*
1486
   * Convert nsStyleCoord to nscoord when percentages depend on the
1487
   * containing block size.
1488
   * @param aPercentBasis The width or height of the containing block
1489
   * (whichever the client wants to use for resolving percentages).
1490
   */
1491
  static nscoord ComputeCBDependentValue(nscoord aPercentBasis,
1492
                                         const nsStyleCoord& aCoord);
1493
1494
  static nscoord ComputeBSizeDependentValue(
1495
                   nscoord              aContainingBlockBSize,
1496
                   const nsStyleCoord&  aCoord);
1497
1498
  static nscoord ComputeBSizeValue(nscoord aContainingBlockBSize,
1499
                                    nscoord aContentEdgeToBoxSizingBoxEdge,
1500
                                    const nsStyleCoord& aCoord)
1501
  {
1502
    MOZ_ASSERT(aContainingBlockBSize != nscoord_MAX || !aCoord.HasPercent(),
1503
               "caller must deal with %% of unconstrained block-size");
1504
    MOZ_ASSERT(aCoord.IsCoordPercentCalcUnit());
1505
1506
    nscoord result = aCoord.ComputeCoordPercentCalc(aContainingBlockBSize);
1507
    // Clamp calc(), and the subtraction for box-sizing.
1508
    return std::max(0, result - aContentEdgeToBoxSizingBoxEdge);
1509
  }
1510
1511
  // XXX to be removed
1512
  static bool IsAutoHeight(const nsStyleCoord &aCoord, nscoord aCBHeight)
1513
0
  {
1514
0
    return IsAutoBSize(aCoord, aCBHeight);
1515
0
  }
1516
1517
  static bool IsAutoBSize(const nsStyleCoord &aCoord, nscoord aCBBSize)
1518
  {
1519
    nsStyleUnit unit = aCoord.GetUnit();
1520
    return unit == eStyleUnit_Auto ||  // only for 'height'
1521
           unit == eStyleUnit_None ||  // only for 'max-height'
1522
           // The enumerated values were originally aimed at inline-size
1523
           // (or width, as it was before logicalization). For now, let them
1524
           // return true here, so that we don't call ComputeBSizeValue with
1525
           // value types that it doesn't understand. (See bug 1113216.)
1526
           //
1527
           // FIXME (bug 567039, bug 527285)
1528
           // This isn't correct for the 'fill' value or for the 'min-*' or
1529
           // 'max-*' properties, which need to be handled differently by
1530
           // the callers of IsAutoBSize().
1531
           unit == eStyleUnit_Enumerated ||
1532
           (aCBBSize == nscoord_MAX && aCoord.HasPercent());
1533
  }
1534
1535
  static bool IsPaddingZero(const nsStyleCoord &aCoord)
1536
  {
1537
    return (aCoord.GetUnit() == eStyleUnit_Coord &&
1538
            aCoord.GetCoordValue() == 0) ||
1539
           (aCoord.GetUnit() == eStyleUnit_Percent &&
1540
            aCoord.GetPercentValue() == 0.0f) ||
1541
           (aCoord.IsCalcUnit() &&
1542
            // clamp negative calc() to 0
1543
            aCoord.ComputeCoordPercentCalc(nscoord_MAX) <= 0 &&
1544
            aCoord.ComputeCoordPercentCalc(0) <= 0);
1545
  }
1546
1547
  static bool IsMarginZero(const nsStyleCoord &aCoord)
1548
  {
1549
    return (aCoord.GetUnit() == eStyleUnit_Coord &&
1550
            aCoord.GetCoordValue() == 0) ||
1551
           (aCoord.GetUnit() == eStyleUnit_Percent &&
1552
            aCoord.GetPercentValue() == 0.0f) ||
1553
           (aCoord.IsCalcUnit() &&
1554
            aCoord.ComputeCoordPercentCalc(nscoord_MAX) == 0 &&
1555
            aCoord.ComputeCoordPercentCalc(0) == 0);
1556
  }
1557
1558
  static void MarkDescendantsDirty(nsIFrame *aSubtreeRoot);
1559
1560
  static void MarkIntrinsicISizesDirtyIfDependentOnBSize(nsIFrame* aFrame);
1561
1562
  /*
1563
   * Calculate the used values for 'width' and 'height' when width
1564
   * and height are 'auto'. The tentWidth and tentHeight arguments should be
1565
   * the result of applying the rules for computing intrinsic sizes and ratios.
1566
   * as specified by CSS 2.1 sections 10.3.2 and 10.6.2
1567
   */
1568
  static nsSize ComputeAutoSizeWithIntrinsicDimensions(nscoord minWidth, nscoord minHeight,
1569
                                                       nscoord maxWidth, nscoord maxHeight,
1570
                                                       nscoord tentWidth, nscoord tentHeight);
1571
1572
  // Implement nsIFrame::GetPrefISize in terms of nsIFrame::AddInlinePrefISize
1573
  static nscoord PrefISizeFromInline(nsIFrame* aFrame,
1574
                                     gfxContext* aRenderingContext);
1575
1576
  // Implement nsIFrame::GetMinISize in terms of nsIFrame::AddInlineMinISize
1577
  static nscoord MinISizeFromInline(nsIFrame* aFrame,
1578
                                    gfxContext* aRenderingContext);
1579
1580
  // Get a suitable foreground color for painting aColor for aFrame.
1581
  static nscolor DarkenColorIfNeeded(nsIFrame* aFrame, nscolor aColor);
1582
1583
  // Get a suitable foreground color for painting aField for aFrame.
1584
  // Type of aFrame is made a template parameter because nsIFrame is not
1585
  // a complete type in the header. Type-safety is not harmed given that
1586
  // DarkenColorIfNeeded requires an nsIFrame pointer.
1587
  template<typename Frame, typename T, typename S>
1588
  static nscolor GetColor(Frame* aFrame, T S::* aField) {
1589
    nscolor color = aFrame->GetVisitedDependentColor(aField);
1590
    return DarkenColorIfNeeded(aFrame, color);
1591
  }
1592
1593
  // Get a baseline y position in app units that is snapped to device pixels.
1594
  static gfxFloat GetSnappedBaselineY(nsIFrame* aFrame, gfxContext* aContext,
1595
                                      nscoord aY, nscoord aAscent);
1596
  // Ditto for an x position (for vertical text). Note that for vertical-rl
1597
  // writing mode, the ascent value should be negated by the caller.
1598
  static gfxFloat GetSnappedBaselineX(nsIFrame* aFrame, gfxContext* aContext,
1599
                                      nscoord aX, nscoord aAscent);
1600
1601
  static nscoord AppUnitWidthOfString(char16_t aC,
1602
                                      nsFontMetrics& aFontMetrics,
1603
                                      DrawTarget* aDrawTarget) {
1604
    return AppUnitWidthOfString(&aC, 1, aFontMetrics, aDrawTarget);
1605
  }
1606
  static nscoord AppUnitWidthOfString(const nsString& aString,
1607
                                      nsFontMetrics& aFontMetrics,
1608
                                      DrawTarget* aDrawTarget) {
1609
    return nsLayoutUtils::AppUnitWidthOfString(aString.get(), aString.Length(),
1610
                                               aFontMetrics, aDrawTarget);
1611
  }
1612
  static nscoord AppUnitWidthOfString(const char16_t *aString,
1613
                                      uint32_t aLength,
1614
                                      nsFontMetrics& aFontMetrics,
1615
                                      DrawTarget* aDrawTarget);
1616
  static nscoord AppUnitWidthOfStringBidi(const nsString& aString,
1617
                                          const nsIFrame* aFrame,
1618
                                          nsFontMetrics& aFontMetrics,
1619
                                          gfxContext& aContext) {
1620
    return nsLayoutUtils::AppUnitWidthOfStringBidi(aString.get(),
1621
                                                   aString.Length(), aFrame,
1622
                                                   aFontMetrics, aContext);
1623
  }
1624
  static nscoord AppUnitWidthOfStringBidi(const char16_t* aString,
1625
                                          uint32_t aLength,
1626
                                          const nsIFrame* aFrame,
1627
                                          nsFontMetrics& aFontMetrics,
1628
                                          gfxContext& aContext);
1629
1630
  static bool StringWidthIsGreaterThan(const nsString& aString,
1631
                                       nsFontMetrics& aFontMetrics,
1632
                                       DrawTarget* aDrawTarget,
1633
                                       nscoord aWidth);
1634
1635
  static nsBoundingMetrics AppUnitBoundsOfString(const char16_t* aString,
1636
                                                 uint32_t aLength,
1637
                                                 nsFontMetrics& aFontMetrics,
1638
                                                 DrawTarget* aDrawTarget);
1639
1640
  static void DrawString(const nsIFrame*         aFrame,
1641
                         nsFontMetrics&          aFontMetrics,
1642
                         gfxContext*             aContext,
1643
                         const char16_t*         aString,
1644
                         int32_t                 aLength,
1645
                         nsPoint                 aPoint,
1646
                         ComputedStyle* aComputedStyle = nullptr,
1647
                         DrawStringFlags         aFlags = DrawStringFlags::eDefault);
1648
1649
  static nsPoint GetBackgroundFirstTilePos(const nsPoint& aDest,
1650
                                           const nsPoint& aFill,
1651
                                           const nsSize& aRepeatSize);
1652
1653
  /**
1654
   * Supports only LTR or RTL. Bidi (mixed direction) is not supported.
1655
   */
1656
  static void DrawUniDirString(const char16_t* aString,
1657
                               uint32_t aLength,
1658
                               const nsPoint& aPoint,
1659
                               nsFontMetrics& aFontMetrics,
1660
                               gfxContext& aContext);
1661
1662
  /**
1663
   * Helper function for drawing text-shadow. The callback's job
1664
   * is to draw whatever needs to be blurred onto the given context.
1665
   */
1666
  typedef void (* TextShadowCallback)(gfxContext* aCtx,
1667
                                      nsPoint aShadowOffset,
1668
                                      const nscolor& aShadowColor,
1669
                                      void* aData);
1670
1671
  static void PaintTextShadow(const nsIFrame*     aFrame,
1672
                              gfxContext*         aContext,
1673
                              const nsRect&       aTextRect,
1674
                              const nsRect&       aDirtyRect,
1675
                              const nscolor&      aForegroundColor,
1676
                              TextShadowCallback  aCallback,
1677
                              void*               aCallbackData);
1678
1679
  /**
1680
   * Gets the baseline to vertically center text from a font within a
1681
   * line of specified height.
1682
   * aIsInverted: true if the text is inverted relative to the block
1683
   * direction, so that the block-dir "ascent" corresponds to font
1684
   * descent. (Applies to sideways text in vertical-lr mode.)
1685
   *
1686
   * Returns the baseline position relative to the top of the line.
1687
   */
1688
  static nscoord GetCenteredFontBaseline(nsFontMetrics* aFontMetrics,
1689
                                         nscoord        aLineHeight,
1690
                                         bool           aIsInverted);
1691
1692
  /**
1693
   * Derive a baseline of |aFrame| (measured from its top border edge)
1694
   * from its first in-flow line box (not descending into anything with
1695
   * 'overflow' not 'visible', potentially including aFrame itself).
1696
   *
1697
   * Returns true if a baseline was found (and fills in aResult).
1698
   * Otherwise returns false.
1699
   */
1700
  static bool GetFirstLineBaseline(mozilla::WritingMode aWritingMode,
1701
                                   const nsIFrame* aFrame, nscoord* aResult);
1702
1703
  /**
1704
   * Just like GetFirstLineBaseline, except also returns the top and
1705
   * bottom of the line with the baseline.
1706
   *
1707
   * Returns true if a line was found (and fills in aResult).
1708
   * Otherwise returns false.
1709
   */
1710
  struct LinePosition {
1711
    nscoord mBStart, mBaseline, mBEnd;
1712
1713
    LinePosition operator+(nscoord aOffset) const {
1714
      LinePosition result;
1715
      result.mBStart = mBStart + aOffset;
1716
      result.mBaseline = mBaseline + aOffset;
1717
      result.mBEnd = mBEnd + aOffset;
1718
      return result;
1719
    }
1720
  };
1721
  static bool GetFirstLinePosition(mozilla::WritingMode aWritingMode,
1722
                                   const nsIFrame* aFrame,
1723
                                   LinePosition* aResult);
1724
1725
1726
  /**
1727
   * Derive a baseline of |aFrame| (measured from its top border edge)
1728
   * from its last in-flow line box (not descending into anything with
1729
   * 'overflow' not 'visible', potentially including aFrame itself).
1730
   *
1731
   * Returns true if a baseline was found (and fills in aResult).
1732
   * Otherwise returns false.
1733
   */
1734
  static bool GetLastLineBaseline(mozilla::WritingMode aWritingMode,
1735
                                  const nsIFrame* aFrame, nscoord* aResult);
1736
1737
  /**
1738
   * Returns a block-dir coordinate relative to this frame's origin that
1739
   * represents the logical block-end of the frame or its visible content,
1740
   * whichever is further from the origin.
1741
   * Relative positioning is ignored and margins and glyph bounds are not
1742
   * considered.
1743
   * This value will be >= mRect.BSize() and <= overflowRect.BEnd() unless
1744
   * relative positioning is applied.
1745
   */
1746
  static nscoord CalculateContentBEnd(mozilla::WritingMode aWritingMode,
1747
                                      nsIFrame* aFrame);
1748
1749
  /**
1750
   * Gets the closest frame (the frame passed in or one of its parents) that
1751
   * qualifies as a "layer"; used in DOM0 methods that depends upon that
1752
   * definition. This is the nearest frame that is either positioned or scrolled
1753
   * (the child of a scroll frame).
1754
   */
1755
  static nsIFrame* GetClosestLayer(nsIFrame* aFrame);
1756
1757
  /**
1758
   * Gets the graphics sampling filter for the frame
1759
   */
1760
  static SamplingFilter GetSamplingFilterForFrame(nsIFrame* aFrame);
1761
1762
  static inline void InitDashPattern(StrokeOptions& aStrokeOptions,
1763
                                     uint8_t aBorderStyle) {
1764
    if (aBorderStyle == NS_STYLE_BORDER_STYLE_DOTTED) {
1765
      static Float dot[] = { 1.f, 1.f };
1766
      aStrokeOptions.mDashLength = MOZ_ARRAY_LENGTH(dot);
1767
      aStrokeOptions.mDashPattern = dot;
1768
    } else if (aBorderStyle == NS_STYLE_BORDER_STYLE_DASHED) {
1769
      static Float dash[] = { 5.f, 5.f };
1770
      aStrokeOptions.mDashLength = MOZ_ARRAY_LENGTH(dash);
1771
      aStrokeOptions.mDashPattern = dash;
1772
    } else {
1773
      aStrokeOptions.mDashLength = 0;
1774
      aStrokeOptions.mDashPattern = nullptr;
1775
    }
1776
  }
1777
1778
  /**
1779
   * Convert an nsRect to a gfxRect.
1780
   */
1781
  static gfxRect RectToGfxRect(const nsRect& aRect,
1782
                               int32_t aAppUnitsPerDevPixel);
1783
1784
  static gfxPoint PointToGfxPoint(const nsPoint& aPoint,
1785
                                  int32_t aAppUnitsPerPixel) {
1786
    return gfxPoint(gfxFloat(aPoint.x) / aAppUnitsPerPixel,
1787
                    gfxFloat(aPoint.y) / aAppUnitsPerPixel);
1788
  }
1789
1790
  /* N.B. The only difference between variants of the Draw*Image
1791
   * functions below is the type of the aImage argument.
1792
   */
1793
1794
  /**
1795
   * Draw a background image.  The image's dimensions are as specified in aDest;
1796
   * the image itself is not consulted to determine a size.
1797
   * See https://wiki.mozilla.org/Gecko:Image_Snapping_and_Rendering
1798
   *   @param aContext          The context to draw to, already set up with an
1799
   *                            appropriate scale and transform for drawing in
1800
   *                            app units.
1801
   *   @param aForFrame         The nsIFrame that we're drawing this image for.
1802
   *   @param aImage            The image.
1803
   *   @param aImageSize        The unscaled size of the image being drawn.
1804
   *                            (This might be the image's size if no scaling
1805
   *                            occurs, or it might be the image's size if
1806
   *                            the image is a vector image being rendered at
1807
   *                            that size.)
1808
   *   @param aDest             The position and scaled area where one copy of
1809
   *                            the image should be drawn. This area represents
1810
   *                            the image itself in its correct position as defined
1811
   *                            with the background-position css property.
1812
   *   @param aFill             The area to be filled with copies of the image.
1813
   *   @param aRepeatSize       The distance between the positions of two subsequent
1814
   *                            repeats of the image. Sizes larger than aDest.Size()
1815
   *                            create gaps between the images.
1816
   *   @param aAnchor           A point in aFill which we will ensure is
1817
   *                            pixel-aligned in the output.
1818
   *   @param aDirty            Pixels outside this area may be skipped.
1819
   *   @param aImageFlags       Image flags of the imgIContainer::FLAG_* variety.
1820
   *   @param aExtendMode       How to extend the image over the dest rect.
1821
   */
1822
  static ImgDrawResult DrawBackgroundImage(gfxContext&         aContext,
1823
                                        nsIFrame*           aForFrame,
1824
                                        nsPresContext*      aPresContext,
1825
                                        imgIContainer*      aImage,
1826
                                        const CSSIntSize&   aImageSize,
1827
                                        SamplingFilter      aSamplingFilter,
1828
                                        const nsRect&       aDest,
1829
                                        const nsRect&       aFill,
1830
                                        const nsSize&       aRepeatSize,
1831
                                        const nsPoint&      aAnchor,
1832
                                        const nsRect&       aDirty,
1833
                                        uint32_t            aImageFlags,
1834
                                        ExtendMode          aExtendMode,
1835
                                        float               aOpacity);
1836
1837
  /**
1838
   * Draw an image.
1839
   * See https://wiki.mozilla.org/Gecko:Image_Snapping_and_Rendering
1840
   *   @param aRenderingContext Where to draw the image, set up with an
1841
   *                            appropriate scale and transform for drawing in
1842
   *                            app units.
1843
   *   @param aComputedStyle    The ComputedStyle of the nsIFrame (or
1844
   *                            pseudo-element) for which this image is being
1845
   *                            drawn.
1846
   *   @param aImage            The image.
1847
   *   @param aDest             Where one copy of the image should mapped to.
1848
   *   @param aFill             The area to be filled with copies of the
1849
   *                            image.
1850
   *   @param aAnchor           A point in aFill which we will ensure is
1851
   *                            pixel-aligned in the output.
1852
   *   @param aDirty            Pixels outside this area may be skipped.
1853
   *   @param aImageFlags       Image flags of the imgIContainer::FLAG_* variety
1854
   */
1855
  static ImgDrawResult DrawImage(gfxContext&         aContext,
1856
                                 ComputedStyle*      aComputedStyle,
1857
                                 nsPresContext*      aPresContext,
1858
                                 imgIContainer*      aImage,
1859
                                 const SamplingFilter aSamplingFilter,
1860
                                 const nsRect&       aDest,
1861
                                 const nsRect&       aFill,
1862
                                 const nsPoint&      aAnchor,
1863
                                 const nsRect&       aDirty,
1864
                                 uint32_t            aImageFlags,
1865
                                 float               aOpacity = 1.0);
1866
1867
  /**
1868
   * Draw a whole image without scaling or tiling.
1869
   *
1870
   *   @param aRenderingContext Where to draw the image, set up with an
1871
   *                            appropriate scale and transform for drawing in
1872
   *                            app units.
1873
   *   @param aImage            The image.
1874
   *   @param aDest             The top-left where the image should be drawn.
1875
   *   @param aDirty            If non-null, then pixels outside this area may
1876
   *                            be skipped.
1877
   *   @param aSVGContext       Optionally provides an SVGImageContext.
1878
   *                            Callers should pass an SVGImageContext with at
1879
   *                            least the viewport size set if aImage may be of
1880
   *                            type imgIContainer::TYPE_VECTOR, or pass
1881
   *                            Nothing() if it is of type
1882
   *                            imgIContainer::TYPE_RASTER (to save cycles
1883
   *                            constructing an SVGImageContext, since this
1884
   *                            argument will be ignored for raster images).
1885
   *   @param aImageFlags       Image flags of the imgIContainer::FLAG_* variety
1886
   *   @param aSourceArea       If non-null, this area is extracted from
1887
   *                            the image and drawn at aDest. It's
1888
   *                            in appunits. For best results it should
1889
   *                            be aligned with image pixels.
1890
   */
1891
  static ImgDrawResult DrawSingleUnscaledImage(gfxContext&          aContext,
1892
                                            nsPresContext*       aPresContext,
1893
                                            imgIContainer*       aImage,
1894
                                            const SamplingFilter aSamplingFilter,
1895
                                            const nsPoint&       aDest,
1896
                                            const nsRect*        aDirty,
1897
                                            const mozilla::Maybe<SVGImageContext>& aSVGContext,
1898
                                            uint32_t             aImageFlags,
1899
                                            const nsRect*        aSourceArea = nullptr);
1900
1901
  /**
1902
   * Draw a whole image without tiling.
1903
   *
1904
   *   @param aRenderingContext Where to draw the image, set up with an
1905
   *                            appropriate scale and transform for drawing in
1906
   *                            app units.
1907
   *   @param aImage            The image.
1908
   *   @param aDest             The area that the image should fill.
1909
   *   @param aDirty            Pixels outside this area may be skipped.
1910
   *   @param aSVGContext       Optionally provides an SVGImageContext.
1911
   *                            Callers should pass an SVGImageContext with at
1912
   *                            least the viewport size set if aImage may be of
1913
   *                            type imgIContainer::TYPE_VECTOR, or pass
1914
   *                            Nothing() if it is of type
1915
   *                            imgIContainer::TYPE_RASTER (to save cycles
1916
   *                            constructing an SVGImageContext, since this
1917
   *                            argument will be ignored for raster images).
1918
   *   @param aImageFlags       Image flags of the imgIContainer::FLAG_*
1919
   *                            variety.
1920
   *   @param aAnchor           If non-null, a point which we will ensure
1921
   *                            is pixel-aligned in the output.
1922
   *   @param aSourceArea       If non-null, this area is extracted from
1923
   *                            the image and drawn in aDest. It's
1924
   *                            in appunits. For best results it should
1925
   *                            be aligned with image pixels.
1926
   */
1927
  static ImgDrawResult DrawSingleImage(gfxContext&         aContext,
1928
                                    nsPresContext*      aPresContext,
1929
                                    imgIContainer*      aImage,
1930
                                    const SamplingFilter aSamplingFilter,
1931
                                    const nsRect&       aDest,
1932
                                    const nsRect&       aDirty,
1933
                                    const mozilla::Maybe<SVGImageContext>& aSVGContext,
1934
                                    uint32_t            aImageFlags,
1935
                                    const nsPoint*      aAnchorPoint = nullptr,
1936
                                    const nsRect*       aSourceArea = nullptr);
1937
1938
  /**
1939
   * Given an imgIContainer, this method attempts to obtain an intrinsic
1940
   * px-valued height & width for it.  If the imgIContainer has a non-pixel
1941
   * value for either height or width, this method tries to generate a pixel
1942
   * value for that dimension using the intrinsic ratio (if available).  The
1943
   * intrinsic ratio will be assigned to aIntrinsicRatio; if there's no
1944
   * intrinsic ratio then (0, 0) will be assigned.
1945
   *
1946
   * This method will always set aGotWidth and aGotHeight to indicate whether
1947
   * we were able to successfully obtain (or compute) a value for each
1948
   * dimension.
1949
   *
1950
   * NOTE: This method is similar to ComputeSizeWithIntrinsicDimensions.  The
1951
   * difference is that this one is simpler and is suited to places where we
1952
   * have less information about the frame tree.
1953
   */
1954
  static void ComputeSizeForDrawing(imgIContainer* aImage,
1955
                                    CSSIntSize&    aImageSize,
1956
                                    nsSize&        aIntrinsicRatio,
1957
                                    bool&          aGotWidth,
1958
                                    bool&          aGotHeight);
1959
1960
  /**
1961
   * Given an imgIContainer, this method attempts to obtain an intrinsic
1962
   * px-valued height & width for it. If the imgIContainer has a non-pixel
1963
   * value for either height or width, this method tries to generate a pixel
1964
   * value for that dimension using the intrinsic ratio (if available). If,
1965
   * after trying all these methods, no value is available for one or both
1966
   * dimensions, the corresponding dimension of aFallbackSize is used instead.
1967
   */
1968
  static CSSIntSize
1969
  ComputeSizeForDrawingWithFallback(imgIContainer* aImage,
1970
                                    const nsSize&  aFallbackSize);
1971
1972
  /**
1973
   * Given the image container, frame, and dest rect, determine the best fitting
1974
   * size to decode the image at, and calculate any necessary SVG parameters.
1975
   */
1976
  static mozilla::gfx::IntSize
1977
  ComputeImageContainerDrawingParameters(imgIContainer*            aImage,
1978
                                         nsIFrame*                 aForFrame,
1979
                                         const LayoutDeviceRect&   aDestRect,
1980
                                         const StackingContextHelper& aSc,
1981
                                         uint32_t                  aFlags,
1982
                                         mozilla::Maybe<SVGImageContext>& aSVGContext);
1983
1984
  /**
1985
   * Given a source area of an image (in appunits) and a destination area
1986
   * that we want to map that source area too, computes the area that
1987
   * would be covered by the whole image. This is useful for passing to
1988
   * the aDest parameter of DrawImage, when we want to draw a subimage
1989
   * of an overall image.
1990
   */
1991
  static nsRect GetWholeImageDestination(const nsSize& aWholeImageSize,
1992
                                         const nsRect& aImageSourceArea,
1993
                                         const nsRect& aDestArea);
1994
1995
  /**
1996
   * Given an image container and an orientation, returns an image container
1997
   * that contains the same image, reoriented appropriately. May return the
1998
   * original image container if no changes are needed.
1999
   *
2000
   * @param aContainer   The image container to apply the orientation to.
2001
   * @param aOrientation The desired orientation.
2002
   */
2003
  static already_AddRefed<imgIContainer>
2004
  OrientImage(imgIContainer* aContainer,
2005
              const mozilla::StyleImageOrientation& aOrientation);
2006
2007
  /**
2008
   * Determine if any corner radius is of nonzero size
2009
   *   @param aCorners the |nsStyleCorners| object to check
2010
   *   @return true unless all the coordinates are 0%, 0 or null.
2011
   *
2012
   * A corner radius with one dimension zero and one nonzero is
2013
   * treated as a nonzero-radius corner, even though it will end up
2014
   * being rendered like a zero-radius corner.  This is because such
2015
   * corners are not expected to appear outside of test cases, and it's
2016
   * simpler to implement the test this way.
2017
   */
2018
  static bool HasNonZeroCorner(const nsStyleCorners& aCorners);
2019
2020
  /**
2021
   * Determine if there is any corner radius on corners adjacent to the
2022
   * given side.
2023
   */
2024
  static bool HasNonZeroCornerOnSide(const nsStyleCorners& aCorners,
2025
                                       mozilla::Side aSide);
2026
2027
  /**
2028
   * Determine if a widget is likely to require transparency or translucency.
2029
   *   @param aBackgroundFrame The frame that the background is set on. For
2030
   *                           <window>s, this will be the canvas frame.
2031
   *   @param aCSSRootFrame    The frame that holds CSS properties affecting
2032
   *                           the widget's transparency. For menupopups,
2033
   *                           aBackgroundFrame and aCSSRootFrame will be the
2034
   *                           same.
2035
   *   @return a value suitable for passing to SetWindowTranslucency.
2036
   */
2037
  static nsTransparencyMode GetFrameTransparency(nsIFrame* aBackgroundFrame,
2038
                                                 nsIFrame* aCSSRootFrame);
2039
2040
  /**
2041
   * A frame is a popup if it has its own floating window. Menus, panels
2042
   * and combobox dropdowns are popups.
2043
   */
2044
  static bool IsPopup(const nsIFrame* aFrame);
2045
2046
  /**
2047
   * Find the nearest "display root". This is the nearest enclosing
2048
   * popup frame or the root prescontext's root frame.
2049
   */
2050
  static nsIFrame* GetDisplayRootFrame(nsIFrame* aFrame);
2051
2052
  /**
2053
   * Get the reference frame that would be used when constructing a
2054
   * display item for this frame.  Rather than using their own frame
2055
   * as a reference frame.)
2056
   *
2057
   * This duplicates some of the logic of GetDisplayRootFrame above and
2058
   * of nsDisplayListBuilder::FindReferenceFrameFor.
2059
   *
2060
   * If you have an nsDisplayListBuilder, you should get the reference
2061
   * frame from it instead of calling this.
2062
   */
2063
  static nsIFrame* GetReferenceFrame(nsIFrame* aFrame);
2064
2065
  /**
2066
   * Get textrun construction flags determined by a given style; in particular
2067
   * some combination of:
2068
   * -- TEXT_DISABLE_OPTIONAL_LIGATURES if letter-spacing is in use
2069
   * -- TEXT_OPTIMIZE_SPEED if the text-rendering CSS property and font size
2070
   * and prefs indicate we should be optimizing for speed over quality
2071
   */
2072
  static mozilla::gfx::ShapedTextFlags
2073
  GetTextRunFlagsForStyle(ComputedStyle* aComputedStyle,
2074
                          nsPresContext* aPresContext,
2075
                          const nsStyleFont* aStyleFont,
2076
                          const nsStyleText* aStyleText,
2077
                          nscoord aLetterSpacing);
2078
2079
  /**
2080
   * Get orientation flags for textrun construction.
2081
   */
2082
  static mozilla::gfx::ShapedTextFlags
2083
  GetTextRunOrientFlagsForStyle(ComputedStyle* aComputedStyle);
2084
2085
  /**
2086
   * Takes two rectangles whose origins must be the same, and computes
2087
   * the difference between their union and their intersection as two
2088
   * rectangles. (This difference is a superset of the difference
2089
   * between the two rectangles.)
2090
   */
2091
  static void GetRectDifferenceStrips(const nsRect& aR1, const nsRect& aR2,
2092
                                      nsRect* aHStrip, nsRect* aVStrip);
2093
2094
  /**
2095
   * Get a device context that can be used to get up-to-date device
2096
   * dimensions for the given window. For some reason, this is more
2097
   * complicated than it ought to be in multi-monitor situations.
2098
   */
2099
  static nsDeviceContext*
2100
  GetDeviceContextForScreenInfo(nsPIDOMWindowOuter* aWindow);
2101
2102
  /**
2103
   * Some frames with 'position: fixed' (nsStyleDisplay::mPosition ==
2104
   * NS_STYLE_POSITION_FIXED) are not really fixed positioned, since
2105
   * they're inside an element with -moz-transform.  This function says
2106
   * whether such an element is a real fixed-pos element.
2107
   */
2108
  static bool IsReallyFixedPos(const nsIFrame* aFrame);
2109
2110
  /**
2111
   * This function says whether `aFrame` would really be a fixed positioned
2112
   * frame if the frame was created with NS_STYLE_POSITION_FIXED.
2113
   *
2114
   * It is effectively the same as IsReallyFixedPos, but without asserting the
2115
   * position value. Use it only when you know what you're doing, like when
2116
   * tearing down the frame tree (where styles may have changed due to
2117
   * ::first-line reparenting and rule changes at the same time).
2118
   */
2119
  static bool MayBeReallyFixedPos(const nsIFrame* aFrame);
2120
2121
  /**
2122
   * Obtain a SourceSurface from the given DOM element, if possible.
2123
   * This obtains the most natural surface from the element; that
2124
   * is, the one that can be obtained with the fewest conversions.
2125
   *
2126
   * The flags below can modify the behaviour of this function.  The
2127
   * result is returned as a SurfaceFromElementResult struct, also
2128
   * defined below.
2129
   *
2130
   * Currently, this will do:
2131
   *  - HTML Canvas elements: will return the underlying canvas surface
2132
   *  - HTML Video elements: will return the current video frame
2133
   *  - Image elements: will return the image
2134
   *
2135
   * The above results are modified by the below flags (copying,
2136
   * forcing image surface, etc.).
2137
   */
2138
2139
  enum {
2140
    /* When creating a new surface, create an image surface */
2141
    SFE_WANT_IMAGE_SURFACE = 1 << 0,
2142
    /* Whether to extract the first frame (as opposed to the
2143
       current frame) in the case that the element is an image. */
2144
    SFE_WANT_FIRST_FRAME_IF_IMAGE = 1 << 1,
2145
    /* Whether we should skip colorspace/gamma conversion */
2146
    SFE_NO_COLORSPACE_CONVERSION = 1 << 2,
2147
    /* Specifies that the caller wants either OPAQUE or NON_PREMULT mAlphaType,
2148
       if this is can be done efficiently. */
2149
    SFE_PREFER_NO_PREMULTIPLY_ALPHA = 1 << 3,
2150
    /* Whether we should skip getting a surface for vector images and
2151
       return a DirectDrawInfo containing an imgIContainer instead. */
2152
    SFE_NO_RASTERIZING_VECTORS = 1 << 4,
2153
    /* If image type is vector, the return surface size will same as
2154
       element size, not image's intrinsic size. */
2155
    SFE_USE_ELEMENT_SIZE_IF_VECTOR = 1 << 5
2156
  };
2157
2158
  struct DirectDrawInfo {
2159
    /* imgIContainer to directly draw to a context */
2160
    nsCOMPtr<imgIContainer> mImgContainer;
2161
    /* which frame to draw */
2162
    uint32_t mWhichFrame;
2163
    /* imgIContainer flags to use when drawing */
2164
    uint32_t mDrawingFlags;
2165
  };
2166
2167
  struct SurfaceFromElementResult {
2168
    friend class mozilla::dom::CanvasRenderingContext2D;
2169
    friend class nsLayoutUtils;
2170
2171
    /* If SFEResult contains a valid surface, it either mLayersImage or mSourceSurface
2172
     * will be non-null, and GetSourceSurface() will not be null.
2173
     *
2174
     * For valid surfaces, mSourceSurface may be null if mLayersImage is non-null, but
2175
     * GetSourceSurface() will create mSourceSurface from mLayersImage when called.
2176
     */
2177
2178
    /* Video elements (at least) often are already decoded as layers::Images. */
2179
    RefPtr<mozilla::layers::Image> mLayersImage;
2180
2181
protected:
2182
    /* GetSourceSurface() fills this and returns its non-null value if this SFEResult
2183
     * was successful. */
2184
    RefPtr<mozilla::gfx::SourceSurface> mSourceSurface;
2185
2186
public:
2187
    /* Contains info for drawing when there is no mSourceSurface. */
2188
    DirectDrawInfo mDrawInfo;
2189
2190
    /* The size of the surface */
2191
    mozilla::gfx::IntSize mSize;
2192
    /* The principal associated with the element whose surface was returned.
2193
       If there is a surface, this will never be null. */
2194
    nsCOMPtr<nsIPrincipal> mPrincipal;
2195
    /* The image request, if the element is an nsIImageLoadingContent */
2196
    nsCOMPtr<imgIRequest> mImageRequest;
2197
    /* Whether the element was "write only", that is, the bits should not be exposed to content */
2198
    bool mIsWriteOnly;
2199
    /* Whether the element was still loading.  Some consumers need to handle
2200
       this case specially. */
2201
    bool mIsStillLoading;
2202
    /* Whether the element has a valid size. */
2203
    bool mHasSize;
2204
    /* Whether the element used CORS when loading. */
2205
    bool mCORSUsed;
2206
2207
    gfxAlphaType mAlphaType;
2208
2209
    // Methods:
2210
2211
    SurfaceFromElementResult();
2212
2213
    // Gets mSourceSurface, or makes a SourceSurface from mLayersImage.
2214
    const RefPtr<mozilla::gfx::SourceSurface>& GetSourceSurface();
2215
  };
2216
2217
  // This function can be called on any thread.
2218
  static SurfaceFromElementResult
2219
  SurfaceFromOffscreenCanvas(mozilla::dom::OffscreenCanvas *aOffscreenCanvas,
2220
                             uint32_t aSurfaceFlags,
2221
                             RefPtr<DrawTarget>& aTarget);
2222
  static SurfaceFromElementResult
2223
  SurfaceFromOffscreenCanvas(mozilla::dom::OffscreenCanvas *aOffscreenCanvas,
2224
0
                             uint32_t aSurfaceFlags = 0) {
2225
0
    RefPtr<DrawTarget> target = nullptr;
2226
0
    return SurfaceFromOffscreenCanvas(aOffscreenCanvas, aSurfaceFlags, target);
2227
0
  }
2228
2229
  static SurfaceFromElementResult SurfaceFromElement(mozilla::dom::Element *aElement,
2230
                                                     uint32_t aSurfaceFlags,
2231
                                                     RefPtr<DrawTarget>& aTarget);
2232
  static SurfaceFromElementResult SurfaceFromElement(mozilla::dom::Element *aElement,
2233
0
                                                     uint32_t aSurfaceFlags = 0) {
2234
0
    RefPtr<DrawTarget> target = nullptr;
2235
0
    return SurfaceFromElement(aElement, aSurfaceFlags, target);
2236
0
  }
2237
2238
  // There are a bunch of callers of SurfaceFromElement.  Just mark it as
2239
  MOZ_CAN_RUN_SCRIPT_BOUNDARY
2240
  static SurfaceFromElementResult SurfaceFromElement(nsIImageLoadingContent *aElement,
2241
                                                     uint32_t aSurfaceFlags,
2242
                                                     RefPtr<DrawTarget>& aTarget);
2243
  // Need an HTMLImageElement overload, because otherwise the
2244
  // nsIImageLoadingContent and mozilla::dom::Element overloads are ambiguous
2245
  // for HTMLImageElement.
2246
  static SurfaceFromElementResult SurfaceFromElement(mozilla::dom::HTMLImageElement *aElement,
2247
                                                     uint32_t aSurfaceFlags,
2248
                                                     RefPtr<DrawTarget>& aTarget);
2249
  static SurfaceFromElementResult SurfaceFromElement(mozilla::dom::HTMLCanvasElement *aElement,
2250
                                                     uint32_t aSurfaceFlags,
2251
                                                     RefPtr<DrawTarget>& aTarget);
2252
  static SurfaceFromElementResult SurfaceFromElement(mozilla::dom::HTMLVideoElement *aElement,
2253
                                                     uint32_t aSurfaceFlags,
2254
                                                     RefPtr<DrawTarget>& aTarget);
2255
2256
  /**
2257
   * When the document is editable by contenteditable attribute of its root
2258
   * content or body content.
2259
   *
2260
   * Be aware, this returns nullptr if it's in designMode.
2261
   *
2262
   * For example:
2263
   *
2264
   *  <html contenteditable="true"><body></body></html>
2265
   *    returns the <html>.
2266
   *
2267
   *  <html><body contenteditable="true"></body></html>
2268
   *  <body contenteditable="true"></body>
2269
   *    With these cases, this returns the <body>.
2270
   *    NOTE: The latter case isn't created normally, however, it can be
2271
   *          created by script with XHTML.
2272
   *
2273
   *  <body><p contenteditable="true"></p></body>
2274
   *    returns nullptr because <body> isn't editable.
2275
   */
2276
  static mozilla::dom::Element*
2277
  GetEditableRootContentByContentEditable(nsIDocument* aDocument);
2278
2279
  static void AddExtraBackgroundItems(nsDisplayListBuilder& aBuilder,
2280
                                      nsDisplayList& aList,
2281
                                      nsIFrame* aFrame,
2282
                                      const nsRect& aCanvasArea,
2283
                                      const nsRegion& aVisibleRegion,
2284
                                      nscolor aBackstop);
2285
2286
  /**
2287
   * Returns true if the passed in prescontext needs the dark grey background
2288
   * that goes behind the page of a print preview presentation.
2289
   */
2290
  static bool NeedsPrintPreviewBackground(nsPresContext* aPresContext);
2291
2292
  typedef nsClassHashtable<nsPtrHashKey<gfxFontEntry>,
2293
                           mozilla::dom::InspectorFontFace> UsedFontFaceTable;
2294
2295
  /**
2296
   * Adds all font faces used in the frame tree starting from aFrame
2297
   * to the list aFontFaceList.
2298
   * aMaxRanges: maximum number of text ranges to record for each face.
2299
   */
2300
  static nsresult GetFontFacesForFrames(nsIFrame* aFrame,
2301
                                        UsedFontFaceTable& aResult,
2302
                                        uint32_t aMaxRanges,
2303
                                        bool aSkipCollapsedWhitespace);
2304
2305
  /**
2306
   * Adds all font faces used within the specified range of text in aFrame,
2307
   * and optionally its continuations, to the list in aFontFaceList.
2308
   * Pass 0 and INT32_MAX for aStartOffset and aEndOffset to specify the
2309
   * entire text is to be considered.
2310
   * aMaxRanges: maximum number of text ranges to record for each face.
2311
   */
2312
  static void GetFontFacesForText(nsIFrame* aFrame,
2313
                                  int32_t aStartOffset,
2314
                                  int32_t aEndOffset,
2315
                                  bool aFollowContinuations,
2316
                                  UsedFontFaceTable& aResult,
2317
                                  uint32_t aMaxRanges,
2318
                                  bool aSkipCollapsedWhitespace);
2319
2320
  /**
2321
   * Walks the frame tree starting at aFrame looking for textRuns.
2322
   * If |clear| is true, just clears the TEXT_RUN_MEMORY_ACCOUNTED flag
2323
   * on each textRun found (and |aMallocSizeOf| is not used).
2324
   * If |clear| is false, adds the storage used for each textRun to the
2325
   * total, and sets the TEXT_RUN_MEMORY_ACCOUNTED flag to avoid double-
2326
   * accounting. (Runs with this flag already set will be skipped.)
2327
   * Expected usage pattern is therefore to call twice:
2328
   *    (void)SizeOfTextRunsForFrames(rootFrame, nullptr, true);
2329
   *    total = SizeOfTextRunsForFrames(rootFrame, mallocSizeOf, false);
2330
   */
2331
  static size_t SizeOfTextRunsForFrames(nsIFrame* aFrame,
2332
                                        mozilla::MallocSizeOf aMallocSizeOf,
2333
                                        bool clear);
2334
2335
  /**
2336
   * Returns true if the frame has any current CSS transitions.
2337
   * A current transition is any transition that has not yet finished playing
2338
   * including paused transitions.
2339
   */
2340
  static bool HasCurrentTransitions(const nsIFrame* aFrame);
2341
2342
  /**
2343
   * Returns true if |aFrame| has an animation of |aProperty| regardless of
2344
   * whether the property is overridden by !important rule.
2345
   */
2346
  static bool HasAnimationOfProperty(const nsIFrame* aFrame,
2347
                                     nsCSSPropertyID aProperty);
2348
2349
  /**
2350
   * Returns true if |aEffectSet| has an animation of |aProperty| regardless of
2351
   * whether the property is overridden by !important rule.
2352
   */
2353
  static bool HasAnimationOfProperty(mozilla::EffectSet* aEffectSet,
2354
                                     nsCSSPropertyID aProperty);
2355
2356
  /**
2357
   * Returns true if |aFrame| has an animation of |aProperty| which is
2358
   * not overridden by !important rules.
2359
   */
2360
  static bool HasEffectiveAnimation(const nsIFrame* aFrame,
2361
                                    nsCSSPropertyID aProperty);
2362
2363
  /**
2364
   * Checks if off-main-thread animations are enabled.
2365
   */
2366
  static bool AreAsyncAnimationsEnabled();
2367
2368
  /**
2369
   * Checks if we should warn about animations that can't be async
2370
   */
2371
  static bool IsAnimationLoggingEnabled();
2372
2373
  /**
2374
   * Checks if retained display lists are enabled.
2375
   */
2376
  static bool AreRetainedDisplayListsEnabled();
2377
2378
  static bool DisplayRootHasRetainedDisplayListBuilder(nsIFrame* aFrame);
2379
2380
  /**
2381
   * Find a suitable scale for a element (aFrame's content) over the course of any
2382
   * animations and transitions of the CSS transform property on the
2383
   * element that run on the compositor thread.
2384
   * It will check the maximum and minimum scale during the animations and
2385
   * transitions and return a suitable value for performance and quality.
2386
   * Will return scale(1,1) if there are no such animations.
2387
   * Always returns a positive value.
2388
   * @param aVisibleSize is the size of the area we want to paint
2389
   * @param aDisplaySize is the size of the display area of the pres context
2390
   */
2391
  static Size ComputeSuitableScaleForAnimation(const nsIFrame* aFrame,
2392
                                               const nsSize& aVisibleSize,
2393
                                               const nsSize& aDisplaySize);
2394
2395
  /**
2396
   * Checks whether we want to use the GPU to scale images when
2397
   * possible.
2398
   */
2399
  static bool GPUImageScalingEnabled();
2400
2401
  /**
2402
   * Checks whether we want to layerize animated images whenever possible.
2403
   */
2404
  static bool AnimatedImageLayersEnabled();
2405
2406
  /**
2407
   * Checks whether support for inter-character ruby is enabled.
2408
   */
2409
  static bool IsInterCharacterRubyEnabled();
2410
2411
  /**
2412
   * Checks whether content-select is enabled.
2413
   */
2414
  static bool IsContentSelectEnabled();
2415
2416
  static bool InterruptibleReflowEnabled()
2417
  {
2418
    return sInterruptibleReflowEnabled;
2419
  }
2420
2421
  /**
2422
   * Unions the overflow areas of the children of aFrame with aOverflowAreas.
2423
   * aSkipChildLists specifies any child lists that should be skipped.
2424
   * kSelectPopupList and kPopupList are always skipped.
2425
   */
2426
  static void UnionChildOverflow(nsIFrame* aFrame,
2427
                                 nsOverflowAreas& aOverflowAreas,
2428
                                 mozilla::layout::FrameChildListIDs aSkipChildLists =
2429
                                     mozilla::layout::FrameChildListIDs());
2430
2431
  /**
2432
   * Return the font size inflation *ratio* for a given frame.  This is
2433
   * the factor by which font sizes should be inflated; it is never
2434
   * smaller than 1.
2435
   */
2436
  static float FontSizeInflationFor(const nsIFrame *aFrame);
2437
2438
  /**
2439
   * Perform the first half of the computation of FontSizeInflationFor
2440
   * (see above).
2441
   * This includes determining whether inflation should be performed
2442
   * within this container and returning 0 if it should not be.
2443
   *
2444
   * The result is guaranteed not to vary between line participants
2445
   * (inlines, text frames) within a line.
2446
   *
2447
   * The result should not be used directly since font sizes slightly
2448
   * above the minimum should always be adjusted as done by
2449
   * FontSizeInflationInner.
2450
   */
2451
  static nscoord InflationMinFontSizeFor(const nsIFrame *aFrame);
2452
2453
  /**
2454
   * Perform the second half of the computation done by
2455
   * FontSizeInflationFor (see above).
2456
   *
2457
   * aMinFontSize must be the result of one of the
2458
   *   InflationMinFontSizeFor methods above.
2459
   */
2460
  static float FontSizeInflationInner(const nsIFrame *aFrame,
2461
                                      nscoord aMinFontSize);
2462
2463
  static bool FontSizeInflationEnabled(nsPresContext *aPresContext);
2464
2465
  /**
2466
   * See comment above "font.size.inflation.maxRatio" in
2467
   * modules/libpref/src/init/all.js .
2468
   */
2469
  static uint32_t FontSizeInflationMaxRatio() {
2470
    return sFontSizeInflationMaxRatio;
2471
  }
2472
2473
  /**
2474
   * See comment above "font.size.inflation.emPerLine" in
2475
   * modules/libpref/src/init/all.js .
2476
   */
2477
  static uint32_t FontSizeInflationEmPerLine() {
2478
    return sFontSizeInflationEmPerLine;
2479
  }
2480
2481
  /**
2482
   * See comment above "font.size.inflation.minTwips" in
2483
   * modules/libpref/src/init/all.js .
2484
   */
2485
  static uint32_t FontSizeInflationMinTwips() {
2486
    return sFontSizeInflationMinTwips;
2487
  }
2488
2489
  /**
2490
   * See comment above "font.size.inflation.lineThreshold" in
2491
   * modules/libpref/src/init/all.js .
2492
   */
2493
  static uint32_t FontSizeInflationLineThreshold() {
2494
    return sFontSizeInflationLineThreshold;
2495
  }
2496
2497
  static bool FontSizeInflationForceEnabled() {
2498
    return sFontSizeInflationForceEnabled;
2499
  }
2500
2501
  static bool FontSizeInflationDisabledInMasterProcess() {
2502
    return sFontSizeInflationDisabledInMasterProcess;
2503
  }
2504
2505
  /**
2506
   * See comment above "font.size.systemFontScale" in
2507
   * modules/libpref/init/all.js.
2508
   */
2509
  static float SystemFontScale() {
2510
    return sSystemFontScale / 100.0f;
2511
  }
2512
2513
  static float MaxZoom() {
2514
    return sZoomMaxPercent / 100.0f;
2515
  }
2516
2517
  static float MinZoom() {
2518
    return sZoomMinPercent / 100.0f;
2519
  }
2520
2521
0
  static bool SVGTransformBoxEnabled() {
2522
0
    return sSVGTransformBoxEnabled;
2523
0
  }
2524
2525
  static uint32_t IdlePeriodDeadlineLimit() {
2526
    return sIdlePeriodDeadlineLimit;
2527
  }
2528
2529
  static uint32_t QuiescentFramesBeforeIdlePeriod() {
2530
    return sQuiescentFramesBeforeIdlePeriod;
2531
  }
2532
2533
  /**
2534
   * See comment above "font.size.inflation.mappingIntercept" in
2535
   * modules/libpref/src/init/all.js .
2536
   */
2537
  static int32_t FontSizeInflationMappingIntercept() {
2538
    return sFontSizeInflationMappingIntercept;
2539
  }
2540
2541
  /**
2542
   * Returns true if the nglayout.debug.invalidation pref is set to true.
2543
   * Note that sInvalidationDebuggingIsEnabled is declared outside this function to
2544
   * allow it to be accessed an manipulated from breakpoint conditions.
2545
   */
2546
0
  static bool InvalidationDebuggingIsEnabled() {
2547
0
    return sInvalidationDebuggingIsEnabled || getenv("MOZ_DUMP_INVALIDATION") != 0;
2548
0
  }
2549
2550
  static void Initialize();
2551
  static void Shutdown();
2552
2553
  /**
2554
   * Register an imgIRequest object with a refresh driver.
2555
   *
2556
   * @param aPresContext The nsPresContext whose refresh driver we want to
2557
   *        register with.
2558
   * @param aRequest A pointer to the imgIRequest object which the client wants
2559
   *        to register with the refresh driver.
2560
   * @param aRequestRegistered A pointer to a boolean value which indicates
2561
   *        whether the given image request is registered. If
2562
   *        *aRequestRegistered is true, then this request will not be
2563
   *        registered again. If the request is registered by this function,
2564
   *        then *aRequestRegistered will be set to true upon the completion of
2565
   *        this function.
2566
   *
2567
   */
2568
  static void RegisterImageRequest(nsPresContext* aPresContext,
2569
                                   imgIRequest* aRequest,
2570
                                   bool* aRequestRegistered);
2571
2572
  /**
2573
   * Register an imgIRequest object with a refresh driver, but only if the
2574
   * request is for an image that is animated.
2575
   *
2576
   * @param aPresContext The nsPresContext whose refresh driver we want to
2577
   *        register with.
2578
   * @param aRequest A pointer to the imgIRequest object which the client wants
2579
   *        to register with the refresh driver.
2580
   * @param aRequestRegistered A pointer to a boolean value which indicates
2581
   *        whether the given image request is registered. If
2582
   *        *aRequestRegistered is true, then this request will not be
2583
   *        registered again. If the request is registered by this function,
2584
   *        then *aRequestRegistered will be set to true upon the completion of
2585
   *        this function.
2586
   *
2587
   */
2588
  static void RegisterImageRequestIfAnimated(nsPresContext* aPresContext,
2589
                                             imgIRequest* aRequest,
2590
                                             bool* aRequestRegistered);
2591
2592
  /**
2593
   * Deregister an imgIRequest object from a refresh driver.
2594
   *
2595
   * @param aPresContext The nsPresContext whose refresh driver we want to
2596
   *        deregister from.
2597
   * @param aRequest A pointer to the imgIRequest object with which the client
2598
   *        previously registered and now wants to deregister from the refresh
2599
   *        driver.
2600
   * @param aRequestRegistered A pointer to a boolean value which indicates
2601
   *        whether the given image request is registered. If
2602
   *        *aRequestRegistered is false, then this request will not be
2603
   *        deregistered. If the request is deregistered by this function,
2604
   *        then *aRequestRegistered will be set to false upon the completion of
2605
   *        this function.
2606
   */
2607
  static void DeregisterImageRequest(nsPresContext* aPresContext,
2608
                                     imgIRequest* aRequest,
2609
                                     bool* aRequestRegistered);
2610
2611
  /**
2612
   * Shim to nsCSSFrameConstructor::PostRestyleEvent. Exists so that we
2613
   * can avoid including nsCSSFrameConstructor.h and all its dependencies
2614
   * in content files.
2615
   */
2616
  static void PostRestyleEvent(mozilla::dom::Element* aElement,
2617
                               nsRestyleHint aRestyleHint,
2618
                               nsChangeHint aMinChangeHint);
2619
2620
  /**
2621
   * Updates a pair of x and y distances if a given point is closer to a given
2622
   * rectangle than the original distance values.  If aPoint is closer to
2623
   * aRect than aClosestXDistance and aClosestYDistance indicate, then those
2624
   * two variables are updated with the distance between aPoint and aRect,
2625
   * and true is returned.  If aPoint is not closer, then aClosestXDistance
2626
   * and aClosestYDistance are left unchanged, and false is returned.
2627
   *
2628
   * Distances are measured in the two dimensions separately; a closer x
2629
   * distance beats a closer y distance.
2630
   */
2631
  template<typename PointType, typename RectType, typename CoordType>
2632
  static bool PointIsCloserToRect(PointType aPoint, const RectType& aRect,
2633
                                  CoordType& aClosestXDistance,
2634
                                  CoordType& aClosestYDistance);
2635
  /**
2636
   * Computes the box shadow rect for the frame, or returns an empty rect if
2637
   * there are no shadows.
2638
   *
2639
   * @param aFrame Frame to compute shadows for.
2640
   * @param aFrameSize Size of aFrame (in case it hasn't been set yet).
2641
   */
2642
  static nsRect GetBoxShadowRectForFrame(nsIFrame* aFrame, const nsSize& aFrameSize);
2643
2644
#ifdef DEBUG
2645
  /**
2646
   * Assert that there are no duplicate continuations of the same frame
2647
   * within aFrameList.  Optimize the tests by assuming that all frames
2648
   * in aFrameList have parent aContainer.
2649
   */
2650
  static void
2651
  AssertNoDuplicateContinuations(nsIFrame* aContainer,
2652
                                 const nsFrameList& aFrameList);
2653
2654
  /**
2655
   * Assert that the frame tree rooted at |aSubtreeRoot| is empty, i.e.,
2656
   * that it contains no first-in-flows.
2657
   */
2658
  static void
2659
  AssertTreeOnlyEmptyNextInFlows(nsIFrame *aSubtreeRoot);
2660
#endif
2661
2662
  /**
2663
   * Helper method to get touch action behaviour from the frame
2664
   */
2665
  static uint32_t
2666
  GetTouchActionFromFrame(nsIFrame* aFrame);
2667
2668
  /**
2669
   * Helper method to transform |aBounds| from aFrame to aAncestorFrame,
2670
   * and combine it with |aPreciseTargetDest| if it is axis-aligned, or
2671
   * combine it with |aImpreciseTargetDest| if not. The transformed rect is
2672
   * clipped to |aClip|; if |aClip| has rounded corners, that also causes
2673
   * the imprecise target to be used.
2674
   */
2675
  static void
2676
  TransformToAncestorAndCombineRegions(
2677
    const nsRegion& aRegion,
2678
    nsIFrame* aFrame,
2679
    const nsIFrame* aAncestorFrame,
2680
    nsRegion* aPreciseTargetDest,
2681
    nsRegion* aImpreciseTargetDest,
2682
    mozilla::Maybe<Matrix4x4Flagged>* aMatrixCache,
2683
    const mozilla::DisplayItemClip* aClip);
2684
2685
  /**
2686
   * Populate aOutSize with the size of the content viewer corresponding
2687
   * to the given prescontext. Return true if the size was set, false
2688
   * otherwise.
2689
   */
2690
  static bool
2691
  GetContentViewerSize(nsPresContext* aPresContext,
2692
                       LayoutDeviceIntSize& aOutSize);
2693
2694
 /**
2695
  * Calculate the compostion size for a frame. See FrameMetrics.h for
2696
  * defintion of composition size (or bounds).
2697
  * Note that for the root content document's root scroll frame (RCD-RSF),
2698
  * the returned size does not change as the document's resolution changes,
2699
  * but for all other frames it does. This means that callers that pass in
2700
  * a frame that may or may not be the RCD-RSF (which is most callers),
2701
  * are likely to need special-case handling of the RCD-RSF.
2702
  */
2703
  static nsSize
2704
  CalculateCompositionSizeForFrame(nsIFrame* aFrame, bool aSubtractScrollbars = true);
2705
2706
 /**
2707
  * Calculate the composition size for the root scroll frame of the root
2708
  * content document.
2709
  * @param aFrame A frame in the root content document (or a descendant of it).
2710
  * @param aIsRootContentDocRootScrollFrame Whether aFrame is already the root
2711
  *          scroll frame of the root content document. In this case we just
2712
  *          use aFrame's own composition size.
2713
  * @param aMetrics A partially populated FrameMetrics for aFrame. Must have at
2714
  *          least mCompositionBounds, mCumulativeResolution, and
2715
  *          mDevPixelsPerCSSPixel set.
2716
  */
2717
  static CSSSize
2718
  CalculateRootCompositionSize(nsIFrame* aFrame,
2719
                               bool aIsRootContentDocRootScrollFrame,
2720
                               const FrameMetrics& aMetrics);
2721
2722
 /**
2723
  * Calculate the scrollable rect for a frame. See FrameMetrics.h for
2724
  * defintion of scrollable rect. aScrollableFrame is the scroll frame to calculate
2725
  * the scrollable rect for. If it's null then we calculate the scrollable rect
2726
  * as the rect of the root frame.
2727
  */
2728
  static nsRect
2729
  CalculateScrollableRectForFrame(nsIScrollableFrame* aScrollableFrame, nsIFrame* aRootFrame);
2730
2731
 /**
2732
  * Calculate the expanded scrollable rect for a frame. See FrameMetrics.h for
2733
  * defintion of expanded scrollable rect.
2734
  */
2735
  static nsRect
2736
  CalculateExpandedScrollableRect(nsIFrame* aFrame);
2737
2738
  /**
2739
   * Returns true if the widget owning the given frame uses asynchronous
2740
   * scrolling.
2741
   */
2742
  static bool UsesAsyncScrolling(nsIFrame* aFrame);
2743
2744
  /**
2745
   * Returns true if the widget owning the given frame has builtin APZ support
2746
   * enabled.
2747
   */
2748
  static bool AsyncPanZoomEnabled(nsIFrame* aFrame);
2749
2750
  /**
2751
   * Returns the current APZ Resolution Scale. When Java Pan/Zoom is
2752
   * enabled in Fennec it will always return 1.0.
2753
   */
2754
  static float GetCurrentAPZResolutionScale(nsIPresShell* aShell);
2755
2756
  /**
2757
   * Returns true if we need to disable async scrolling for this particular
2758
   * element. Note that this does a partial disabling - the displayport still
2759
   * exists but uses a very small margin, and the compositor doesn't apply the
2760
   * async transform. However, the content may still be layerized.
2761
   */
2762
  static bool ShouldDisableApzForElement(nsIContent* aContent);
2763
2764
  /**
2765
   * Log a key/value pair for APZ testing during a paint.
2766
   * @param aManager   The data will be written to the APZTestData associated
2767
   *                   with this layer manager.
2768
   * @param aScrollId Identifies the scroll frame to which the data pertains.
2769
   * @param aKey The key under which to log the data.
2770
   * @param aValue The value of the data to be logged.
2771
   */
2772
  static void LogTestDataForPaint(mozilla::layers::LayerManager* aManager,
2773
                                  ViewID aScrollId,
2774
                                  const std::string& aKey,
2775
0
                                  const std::string& aValue) {
2776
0
    DoLogTestDataForPaint(aManager, aScrollId, aKey, aValue);
2777
0
  }
2778
2779
  /**
2780
   * A convenience overload of LogTestDataForPaint() that accepts any type
2781
   * as the value, and passes it through mozilla::ToString() to obtain a string
2782
   * value. The type passed must support streaming to an std::ostream.
2783
   */
2784
  template <typename Value>
2785
  static void LogTestDataForPaint(mozilla::layers::LayerManager* aManager,
2786
                                  ViewID aScrollId,
2787
                                  const std::string& aKey,
2788
                                  const Value& aValue) {
2789
    DoLogTestDataForPaint(aManager, aScrollId, aKey,
2790
                          mozilla::ToString(aValue));
2791
  }
2792
2793
  /**
2794
   * Calculate a basic FrameMetrics with enough fields set to perform some
2795
   * layout calculations. The fields set are dev-to-css ratio, pres shell
2796
   * resolution, cumulative resolution, zoom, composition size, root
2797
   * composition size, scroll offset and scrollable rect.
2798
   *
2799
   * Note that for the RCD-RSF, the scroll offset returned is the layout
2800
   * viewport offset; if you need the visual viewport offset, that needs to
2801
   * be queried independently via nsIPresShell::GetVisualViewportOffset().
2802
   *
2803
   * By contrast, ComputeFrameMetrics() computes all the fields, but requires
2804
   * extra inputs and can only be called during frame layer building.
2805
   */
2806
  static FrameMetrics CalculateBasicFrameMetrics(nsIScrollableFrame* aScrollFrame);
2807
2808
  /**
2809
   * Calculate a default set of displayport margins for the given scrollframe
2810
   * and set them on the scrollframe's content element. The margins are set with
2811
   * the default priority, which may clobber previously set margins. The repaint
2812
   * mode provided is passed through to the call to SetDisplayPortMargins.
2813
   * The |aScrollFrame| parameter must be non-null and queryable to an nsIFrame.
2814
   * @return true iff the call to SetDisplayPortMargins returned true.
2815
   */
2816
  static bool CalculateAndSetDisplayPortMargins(nsIScrollableFrame* aScrollFrame,
2817
                                                RepaintMode aRepaintMode);
2818
2819
  /**
2820
   * If |aScrollFrame| WantsAsyncScroll() and we don't have a scrollable
2821
   * displayport yet (as tracked by |aBuilder|), calculate and set a
2822
   * displayport.
2823
   *
2824
   * If this is called during display list building pass DoNotRepaint in
2825
   * aRepaintMode.
2826
   *
2827
   * Returns true if there is a displayport on an async scrollable scrollframe
2828
   * after this call, either because one was just added or it already existed.
2829
   */
2830
  static bool MaybeCreateDisplayPort(nsDisplayListBuilder& aBuilder,
2831
                                     nsIFrame* aScrollFrame,
2832
                                     RepaintMode aRepaintMode);
2833
2834
  static nsIScrollableFrame* GetAsyncScrollableAncestorFrame(nsIFrame* aTarget);
2835
2836
  /**
2837
   * Sets a zero margin display port on all proper ancestors of aFrame that
2838
   * are async scrollable.
2839
   */
2840
  static void SetZeroMarginDisplayPortOnAsyncScrollableAncestors(nsIFrame* aFrame,
2841
                                                                 RepaintMode aRepaintMode);
2842
  /**
2843
   * Finds the closest ancestor async scrollable frame from aFrame that has a
2844
   * displayport and attempts to trigger the displayport expiry on that
2845
   * ancestor.
2846
   */
2847
  static void ExpireDisplayPortOnAsyncScrollableAncestor(nsIFrame* aFrame);
2848
2849
  static bool IsOutlineStyleAutoEnabled();
2850
2851
  static void SetBSizeFromFontMetrics(const nsIFrame* aFrame,
2852
                                      mozilla::ReflowOutput& aMetrics,
2853
                                      const mozilla::LogicalMargin& aFramePadding,
2854
                                      mozilla::WritingMode aLineWM,
2855
                                      mozilla::WritingMode aFrameWM);
2856
2857
  static bool HasDocumentLevelListenersForApzAwareEvents(nsIPresShell* aShell);
2858
2859
  /**
2860
   * Set the viewport size for the purpose of clamping the scroll position
2861
   * for the root scroll frame of this document
2862
   * (see nsIDOMWindowUtils.setVisualViewportSize).
2863
   */
2864
  static void SetVisualViewportSize(nsIPresShell* aPresShell,
2865
                                                      CSSSize aSize);
2866
2867
  /**
2868
   * Returns true if the given scroll origin is "higher priority" than APZ.
2869
   * In general any content programmatic scrolls (e.g. scrollTo calls) are
2870
   * higher priority, and take precedence over APZ scrolling. This function
2871
   * returns true for those, and returns false for other origins like APZ
2872
   * itself, or scroll position updates from the history restore code.
2873
   */
2874
  static bool CanScrollOriginClobberApz(nsAtom* aScrollOrigin);
2875
2876
  static ScrollMetadata ComputeScrollMetadata(nsIFrame* aForFrame,
2877
                                              nsIFrame* aScrollFrame,
2878
                                              nsIContent* aContent,
2879
                                              const nsIFrame* aReferenceFrame,
2880
                                              mozilla::layers::LayerManager* aLayerManager,
2881
                                              ViewID aScrollParentId,
2882
                                              const nsRect& aViewport,
2883
                                              const mozilla::Maybe<nsRect>& aClipRect,
2884
                                              bool aIsRoot,
2885
                                              const ContainerLayerParameters& aContainerParameters);
2886
2887
  /**
2888
   * Returns the metadata to put onto the root layer of a layer tree, if one is
2889
   * needed. The last argument is a callback function to check if the caller
2890
   * already has a metadata for a given scroll id.
2891
   */
2892
  static mozilla::Maybe<ScrollMetadata> GetRootMetadata(nsDisplayListBuilder* aBuilder,
2893
                                                        mozilla::layers::LayerManager* aLayerManager,
2894
                                                        const ContainerLayerParameters& aContainerParameters,
2895
                                                        const std::function<bool(ViewID& aScrollId)>& aCallback);
2896
2897
  /**
2898
   * If the given scroll frame needs an area excluded from its composition
2899
   * bounds due to scrollbars, return that area, otherwise return an empty
2900
   * margin.
2901
   * There is no need to exclude scrollbars in the following cases:
2902
   *   - If the scroll frame is not the RCD-RSF; in that case, the composition
2903
   *     bounds is calculated based on the scroll port which already excludes
2904
   *     the scrollbar area.
2905
   *   - If the scrollbars are overlay, since then they are drawn on top of the
2906
   *     scrollable content.
2907
   */
2908
  static nsMargin ScrollbarAreaToExcludeFromCompositionBoundsFor(nsIFrame* aScrollFrame);
2909
2910
  /**
2911
   * Looks in the layer subtree rooted at aLayer for a metrics with scroll id
2912
   * aScrollId. Returns true if such is found.
2913
   */
2914
  static bool ContainsMetricsWithId(const Layer* aLayer, const ViewID& aScrollId);
2915
2916
  static bool ShouldUseNoScriptSheet(nsIDocument* aDocument);
2917
  static bool ShouldUseNoFramesSheet(nsIDocument* aDocument);
2918
2919
  /**
2920
   * Get the text content inside the frame. This methods traverse the
2921
   * frame tree and collect the content from text frames. Note that this
2922
   * method is similiar to nsContentUtils::GetNodeTextContent, but it at
2923
   * least differs from that method in the following things:
2924
   * 1. it skips text content inside nodes like style, script, textarea
2925
   *    which don't generate an in-tree text frame for the text;
2926
   * 2. it skips elements with display property set to none;
2927
   * 3. it skips out-of-flow elements;
2928
   * 4. it includes content inside pseudo elements;
2929
   * 5. it may include part of text content of a node if a text frame
2930
   *    inside is split to different continuations.
2931
   */
2932
  static void GetFrameTextContent(nsIFrame* aFrame, nsAString& aResult);
2933
2934
  /**
2935
   * Same as GetFrameTextContent but appends the result rather than sets it.
2936
   */
2937
  static void AppendFrameTextContent(nsIFrame* aFrame, nsAString& aResult);
2938
2939
  /**
2940
   * Takes a selection, and returns selection's bounding rect which is relative
2941
   * to its root frame.
2942
   *
2943
   * @param aSel      Selection to check
2944
   */
2945
  static nsRect GetSelectionBoundingRect(mozilla::dom::Selection* aSel);
2946
2947
  /**
2948
   * Calculate the bounding rect of |aContent|, relative to the origin
2949
   * of the scrolled content of |aRootScrollFrame|.
2950
   * Where the element is contained inside a scrollable subframe, the
2951
   * bounding rect is clipped to the bounds of the subframe.
2952
   */
2953
  static CSSRect GetBoundingContentRect(const nsIContent* aContent,
2954
                                        const nsIScrollableFrame* aRootScrollFrame);
2955
2956
  /**
2957
   * Returns the first ancestor who is a float containing block.
2958
   */
2959
  static nsBlockFrame* GetFloatContainingBlock(nsIFrame* aFrame);
2960
2961
  /**
2962
   * Walks up the frame tree from |aForFrame| up to |aTopFrame|, or to the
2963
   * root of the frame tree if |aTopFrame| is nullptr, and returns true if
2964
   * a transformed frame is encountered.
2965
   */
2966
  static bool IsTransformed(nsIFrame* aForFrame, nsIFrame* aTopFrame = nullptr);
2967
2968
  /**
2969
   * Walk up from aFrame to the cross-doc root, accumulating all the APZ callback
2970
   * transforms on the content elements encountered along the way. Return the
2971
   * accumulated value.
2972
   * XXX: Note that this does not take into account CSS transforms, nor
2973
   * differences in structure between the frame tree and the layer tree (which
2974
   * is probably what we *want* to be computing).
2975
   */
2976
  static CSSPoint GetCumulativeApzCallbackTransform(nsIFrame* aFrame);
2977
2978
  /**
2979
   * Compute a rect to pre-render in cases where we want to render more of
2980
   * something than what is visible (usually to support async transformation).
2981
   * @param aDirtyRect the area that's visible
2982
   * @param aOverflow the total size of the thing we're rendering
2983
   * @param aPrerenderSize how large of an area we're willing to render
2984
   * @return A rectangle that includes |aDirtyRect|, is clamped to |aOverflow|,
2985
   *         and is no larger than |aPrerenderSize| (unless |aPrerenderSize|
2986
   *         is smaller than |aDirtyRect|, in which case the returned rect
2987
   *         will still include |aDirtyRect| and thus be larger than
2988
   *         |aPrerenderSize|).
2989
   */
2990
  static nsRect ComputePartialPrerenderArea(const nsRect& aDirtyRect,
2991
                                            const nsRect& aOverflow,
2992
                                            const nsSize& aPrerenderSize);
2993
2994
  /*
2995
   * Checks whether a node is an invisible break.
2996
   * If not, returns the first frame on the next line if such a next line exists.
2997
   *
2998
   * @return  true if the node is an invisible break.
2999
   *          aNextLineFrame is returned null in this case.
3000
   *          false if the node causes a visible break or if the node is no break.
3001
   *
3002
   * @param   aNextLineFrame  assigned to first frame on the next line if such a
3003
   *                          next line exists, null otherwise.
3004
   */
3005
  static bool IsInvisibleBreak(nsINode* aNode, nsIFrame** aNextLineFrame = nullptr);
3006
3007
  static nsRect ComputeGeometryBox(nsIFrame* aFrame,
3008
                                   StyleGeometryBox aGeometryBox);
3009
3010
  static nsPoint ComputeOffsetToUserSpace(nsDisplayListBuilder* aBuilder,
3011
                                          nsIFrame* aFrame);
3012
3013
  // Return the default value to be used for -moz-control-character-visibility,
3014
  // from preferences.
3015
  static uint8_t ControlCharVisibilityDefault();
3016
3017
  enum class FlushUserFontSet {
3018
    Yes,
3019
    No,
3020
  };
3021
3022
  static already_AddRefed<nsFontMetrics> GetMetricsFor(nsPresContext* aPresContext,
3023
                                                       bool aIsVertical,
3024
                                                       const nsStyleFont* aStyleFont,
3025
                                                       nscoord aFontSize,
3026
                                                       bool aUseUserFontSet,
3027
                                                       FlushUserFontSet aFlushUserFontSet);
3028
3029
  /**
3030
   * Appropriately add the correct font if we are using DocumentFonts or
3031
   * overriding for XUL
3032
   */
3033
  static void FixupNoneGeneric(nsFont* aFont,
3034
                               const nsPresContext* aPresContext,
3035
                               uint8_t aGenericFontID,
3036
                               const nsFont* aDefaultVariableFont);
3037
3038
  /**
3039
   * For an nsStyleFont with mSize set, apply minimum font size constraints
3040
   * from preferences, as well as -moz-min-font-size-ratio.
3041
   */
3042
  static void ApplyMinFontSize(nsStyleFont* aFont,
3043
                               const nsPresContext* aPresContext,
3044
                               nscoord aMinFontSize);
3045
3046
  static void ComputeSystemFont(nsFont* aSystemFont,
3047
                                mozilla::LookAndFeel::FontID aFontID,
3048
                                const nsPresContext* aPresContext,
3049
                                const nsFont* aDefaultVariableFont);
3050
3051
  static void ComputeFontFeatures(const nsCSSValuePairList* aFeaturesList,
3052
                                  nsTArray<gfxFontFeature>& aFeatureSettings);
3053
3054
  static void ComputeFontVariations(const nsCSSValuePairList* aVariationsList,
3055
                                    nsTArray<gfxFontVariation>& aVariationSettings);
3056
3057
  static uint32_t ParseFontLanguageOverride(const nsAString& aLangTag);
3058
3059
  /**
3060
   * Resolve a CSS <length-percentage> value to a definite size.
3061
   */
3062
  template<bool clampNegativeResultToZero>
3063
  static nscoord ResolveToLength(const nsStyleCoord& aCoord,
3064
                                 nscoord aPercentageBasis)
3065
  {
3066
    NS_WARNING_ASSERTION(aPercentageBasis >= nscoord(0), "nscoord overflow?");
3067
3068
    switch (aCoord.GetUnit()) {
3069
      case eStyleUnit_Coord:
3070
        MOZ_ASSERT(!clampNegativeResultToZero || aCoord.GetCoordValue() >= 0,
3071
                   "This value should have been rejected by the style system");
3072
        return aCoord.GetCoordValue();
3073
      case eStyleUnit_Percent:
3074
        if (aPercentageBasis == NS_UNCONSTRAINEDSIZE) {
3075
          return nscoord(0);
3076
        }
3077
        MOZ_ASSERT(!clampNegativeResultToZero || aCoord.GetPercentValue() >= 0,
3078
                   "This value should have been rejected by the style system");
3079
        return NSToCoordFloorClamped(aPercentageBasis *
3080
                                     aCoord.GetPercentValue());
3081
      case eStyleUnit_Calc: {
3082
        nsStyleCoord::Calc* calc = aCoord.GetCalcValue();
3083
        nscoord result;
3084
        if (aPercentageBasis == NS_UNCONSTRAINEDSIZE) {
3085
          result = calc->mLength;
3086
        } else {
3087
          result = calc->mLength +
3088
            NSToCoordFloorClamped(aPercentageBasis * calc->mPercent);
3089
        }
3090
        if (clampNegativeResultToZero && result < 0) {
3091
          return nscoord(0);
3092
        }
3093
        return result;
3094
      }
3095
      default:
3096
        MOZ_ASSERT_UNREACHABLE("Unexpected unit!");
3097
        return nscoord(0);
3098
    }
3099
  }
3100
3101
  /**
3102
   * Resolve a column-gap/row-gap to a definite size.
3103
   * @note This method resolves 'normal' to zero.
3104
   *   Callers who want different behavior should handle 'normal' on their own.
3105
   */
3106
  static nscoord ResolveGapToLength(const nsStyleCoord& aGap,
3107
                                    nscoord aPercentageBasis)
3108
  {
3109
    if (aGap.GetUnit() == eStyleUnit_Normal) {
3110
      return nscoord(0);
3111
    }
3112
    return ResolveToLength<true>(aGap, aPercentageBasis);
3113
  }
3114
3115
  /**
3116
   * Get the computed style from which the scrollbar style should be
3117
   * used for the given scrollbar part frame.
3118
   */
3119
  static ComputedStyle* StyleForScrollbar(nsIFrame* aScrollbarPart);
3120
3121
  /**
3122
   * Generate the motion path transform result.
3123
   **/
3124
  static mozilla::Maybe<mozilla::MotionPathData>
3125
  ResolveMotionPath(const nsIFrame* aFrame);
3126
3127
private:
3128
  static uint32_t sFontSizeInflationEmPerLine;
3129
  static uint32_t sFontSizeInflationMinTwips;
3130
  static uint32_t sFontSizeInflationLineThreshold;
3131
  static int32_t  sFontSizeInflationMappingIntercept;
3132
  static uint32_t sFontSizeInflationMaxRatio;
3133
  static bool sFontSizeInflationForceEnabled;
3134
  static bool sFontSizeInflationDisabledInMasterProcess;
3135
  static uint32_t sSystemFontScale;
3136
  static uint32_t sZoomMaxPercent;
3137
  static uint32_t sZoomMinPercent;
3138
  static bool sInvalidationDebuggingIsEnabled;
3139
  static bool sInterruptibleReflowEnabled;
3140
  static bool sSVGTransformBoxEnabled;
3141
  static uint32_t sIdlePeriodDeadlineLimit;
3142
  static uint32_t sQuiescentFramesBeforeIdlePeriod;
3143
3144
  /**
3145
   * Helper function for LogTestDataForPaint().
3146
   */
3147
  static void DoLogTestDataForPaint(mozilla::layers::LayerManager* aManager,
3148
                                    ViewID aScrollId,
3149
                                    const std::string& aKey,
3150
                                    const std::string& aValue);
3151
3152
  static bool IsAPZTestLoggingEnabled();
3153
};
3154
3155
MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(nsLayoutUtils::PaintFrameFlags)
3156
3157
template<typename PointType, typename RectType, typename CoordType>
3158
/* static */ bool
3159
nsLayoutUtils::PointIsCloserToRect(PointType aPoint, const RectType& aRect,
3160
                                   CoordType& aClosestXDistance,
3161
                                   CoordType& aClosestYDistance)
3162
{
3163
  CoordType fromLeft = aPoint.x - aRect.x;
3164
  CoordType fromRight = aPoint.x - aRect.XMost();
3165
3166
  CoordType xDistance;
3167
  if (fromLeft >= 0 && fromRight <= 0) {
3168
    xDistance = 0;
3169
  } else {
3170
    xDistance = std::min(abs(fromLeft), abs(fromRight));
3171
  }
3172
3173
  if (xDistance <= aClosestXDistance) {
3174
    if (xDistance < aClosestXDistance) {
3175
      aClosestYDistance = std::numeric_limits<CoordType>::max();
3176
    }
3177
3178
    CoordType fromTop = aPoint.y - aRect.y;
3179
    CoordType fromBottom = aPoint.y - aRect.YMost();
3180
3181
    CoordType yDistance;
3182
    if (fromTop >= 0 && fromBottom <= 0) {
3183
      yDistance = 0;
3184
    } else {
3185
      yDistance = std::min(abs(fromTop), abs(fromBottom));
3186
    }
3187
3188
    if (yDistance < aClosestYDistance) {
3189
      aClosestXDistance = xDistance;
3190
      aClosestYDistance = yDistance;
3191
      return true;
3192
    }
3193
  }
3194
3195
  return false;
3196
}
3197
3198
namespace mozilla {
3199
3200
/**
3201
 * Converts an nsPoint in app units to a Moz2D Point in pixels (whether those
3202
 * are device pixels or CSS px depends on what the caller chooses to pass as
3203
 * aAppUnitsPerPixel).
3204
 */
3205
inline gfx::Point NSPointToPoint(const nsPoint& aPoint,
3206
                                 int32_t aAppUnitsPerPixel) {
3207
  return gfx::Point(gfx::Float(aPoint.x) / aAppUnitsPerPixel,
3208
                    gfx::Float(aPoint.y) / aAppUnitsPerPixel);
3209
}
3210
3211
/**
3212
 * Converts an nsRect in app units to a Moz2D Rect in pixels (whether those
3213
 * are device pixels or CSS px depends on what the caller chooses to pass as
3214
 * aAppUnitsPerPixel).
3215
 */
3216
gfx::Rect NSRectToRect(const nsRect& aRect, double aAppUnitsPerPixel);
3217
3218
/**
3219
 * Converts an nsRect in app units to a Moz2D Rect in pixels (whether those
3220
 * are device pixels or CSS px depends on what the caller chooses to pass as
3221
 * aAppUnitsPerPixel).
3222
 *
3223
 * The passed DrawTarget is used to additionally snap the returned Rect to
3224
 * device pixels, if appropriate (as decided and carried out by Moz2D's
3225
 * MaybeSnapToDevicePixels helper, which this function calls to do any
3226
 * snapping).
3227
 */
3228
gfx::Rect NSRectToSnappedRect(const nsRect& aRect, double aAppUnitsPerPixel,
3229
                              const gfx::DrawTarget& aSnapDT);
3230
3231
/**
3232
* Converts, where possible, an nsRect in app units to a Moz2D Rect in pixels
3233
* (whether those are device pixels or CSS px depends on what the caller
3234
*  chooses to pass as aAppUnitsPerPixel).
3235
*
3236
* If snapping results in a rectangle with zero width or height, the affected
3237
* coordinates are left unsnapped
3238
*/
3239
gfx::Rect NSRectToNonEmptySnappedRect(const nsRect& aRect, double aAppUnitsPerPixel,
3240
                                      const gfx::DrawTarget& aSnapDT);
3241
3242
void StrokeLineWithSnapping(const nsPoint& aP1, const nsPoint& aP2,
3243
                            int32_t aAppUnitsPerDevPixel,
3244
                            gfx::DrawTarget& aDrawTarget,
3245
                            const gfx::Pattern& aPattern,
3246
                            const gfx::StrokeOptions& aStrokeOptions = gfx::StrokeOptions(),
3247
                            const gfx::DrawOptions& aDrawOptions = gfx::DrawOptions());
3248
3249
  namespace layout {
3250
3251
    /**
3252
     * An RAII class which will, for the duration of its lifetime,
3253
     * **if** the frame given is a container for font size inflation,
3254
     * set the current inflation container on the pres context to null
3255
     * (and then, in its destructor, restore the old value).
3256
     */
3257
    class AutoMaybeDisableFontInflation {
3258
    public:
3259
      explicit AutoMaybeDisableFontInflation(nsIFrame *aFrame);
3260
3261
      ~AutoMaybeDisableFontInflation();
3262
    private:
3263
      nsPresContext *mPresContext;
3264
      bool mOldValue;
3265
    };
3266
3267
    void MaybeSetupTransactionIdAllocator(layers::LayerManager* aManager,
3268
                                          nsPresContext* aPresContext);
3269
3270
  } // namespace layout
3271
} // namespace mozilla
3272
3273
class nsSetAttrRunnable : public mozilla::Runnable
3274
{
3275
public:
3276
  nsSetAttrRunnable(mozilla::dom::Element* aElement, nsAtom* aAttrName,
3277
                    const nsAString& aValue);
3278
  nsSetAttrRunnable(mozilla::dom::Element* aElement, nsAtom* aAttrName,
3279
                    int32_t aValue);
3280
3281
  NS_DECL_NSIRUNNABLE
3282
3283
  RefPtr<Element> mElement;
3284
  RefPtr<nsAtom> mAttrName;
3285
  nsAutoString mValue;
3286
};
3287
3288
class nsUnsetAttrRunnable : public mozilla::Runnable
3289
{
3290
public:
3291
  nsUnsetAttrRunnable(mozilla::dom::Element* aElement, nsAtom* aAttrName);
3292
3293
  NS_DECL_NSIRUNNABLE
3294
3295
  RefPtr<Element> mElement;
3296
  RefPtr<nsAtom> mAttrName;
3297
};
3298
3299
// This class allows you to easily set any pointer variable and ensure it's
3300
// set to nullptr when leaving its scope.
3301
template<typename T>
3302
class MOZ_RAII SetAndNullOnExit
3303
{
3304
public:
3305
  SetAndNullOnExit(T* &aVariable, T* aValue) {
3306
    aVariable = aValue;
3307
    mVariable = &aVariable;
3308
  }
3309
  ~SetAndNullOnExit() {
3310
    *mVariable = nullptr;
3311
  }
3312
private:
3313
  T** mVariable;
3314
};
3315
3316
#endif // nsLayoutUtils_h__