forked from mozilla/gecko-dev
-
Notifications
You must be signed in to change notification settings - Fork 2
/
nsIFrame.h
3283 lines (2890 loc) · 126 KB
/
nsIFrame.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 sw=2 et tw=78: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/* interface for all rendering objects */
#ifndef nsIFrame_h___
#define nsIFrame_h___
#ifndef MOZILLA_INTERNAL_API
#error This header/class should only be used within Mozilla code. It should not be used by extensions.
#endif
#define MAX_REFLOW_DEPTH 200
/* nsIFrame is in the process of being deCOMtaminated, i.e., this file is eventually
going to be eliminated, and all callers will use nsFrame instead. At the moment
we're midway through this process, so you will see inlined functions and member
variables in this file. -dwh */
#include <stdio.h>
#include "nsQueryFrame.h"
#include "nsStyleContext.h"
#include "nsStyleStruct.h"
#include "nsStyleStructFwd.h"
#include "nsHTMLReflowMetrics.h"
#include "nsFrameList.h"
#include "nsIContent.h"
#include "nsAlgorithm.h"
#include "mozilla/layout/FrameChildList.h"
#include "FramePropertyTable.h"
#include "mozilla/Attributes.h"
#ifdef ACCESSIBILITY
#include "mozilla/a11y/AccTypes.h"
#endif
/**
* New rules of reflow:
* 1. you get a WillReflow() followed by a Reflow() followed by a DidReflow() in order
* (no separate pass over the tree)
* 2. it's the parent frame's responsibility to size/position the child's view (not
* the child frame's responsibility as it is today) during reflow (and before
* sending the DidReflow() notification)
* 3. positioning of child frames (and their views) is done on the way down the tree,
* and sizing of child frames (and their views) on the way back up
* 4. if you move a frame (outside of the reflow process, or after reflowing it),
* then you must make sure that its view (or its child frame's views) are re-positioned
* as well. It's reasonable to not position the view until after all reflowing the
* entire line, for example, but the frame should still be positioned and sized (and
* the view sized) during the reflow (i.e., before sending the DidReflow() notification)
* 5. the view system handles moving of widgets, i.e., it's not our problem
*/
struct nsHTMLReflowState;
class nsHTMLReflowCommand;
struct gfxMatrix;
class nsIAtom;
class nsPresContext;
class nsIPresShell;
class nsRenderingContext;
class nsView;
class nsIWidget;
class nsIDOMRange;
class nsISelectionController;
class nsBoxLayoutState;
class nsBoxLayout;
class nsILineIterator;
class nsDisplayListBuilder;
class nsDisplayListSet;
class nsDisplayList;
class gfxSkipChars;
class gfxSkipCharsIterator;
class gfxContext;
class nsLineList_iterator;
class nsAbsoluteContainingBlock;
struct nsPeekOffsetStruct;
struct nsPoint;
struct nsRect;
struct nsSize;
struct nsMargin;
struct CharacterDataChangeInfo;
namespace mozilla {
namespace layers {
class Layer;
}
}
/**
* Indication of how the frame can be split. This is used when doing runaround
* of floats, and when pulling up child frames from a next-in-flow.
*
* The choices are splittable, not splittable at all, and splittable in
* a non-rectangular fashion. This last type only applies to block-level
* elements, and indicates whether splitting can be used when doing runaround.
* If you can split across page boundaries, but you expect each continuing
* frame to be the same width then return frSplittable and not
* frSplittableNonRectangular.
*
* @see #GetSplittableType()
*/
typedef uint32_t nsSplittableType;
#define NS_FRAME_NOT_SPLITTABLE 0 // Note: not a bit!
#define NS_FRAME_SPLITTABLE 0x1
#define NS_FRAME_SPLITTABLE_NON_RECTANGULAR 0x3
#define NS_FRAME_IS_SPLITTABLE(type)\
(0 != ((type) & NS_FRAME_SPLITTABLE))
#define NS_FRAME_IS_NOT_SPLITTABLE(type)\
(0 == ((type) & NS_FRAME_SPLITTABLE))
#define NS_INTRINSIC_WIDTH_UNKNOWN nscoord_MIN
//----------------------------------------------------------------------
/**
* Frame state bits. Any bits not listed here are reserved for future
* extensions, but must be stored by the frames.
*/
typedef uint64_t nsFrameState;
#define NS_FRAME_STATE_BIT(n_) (nsFrameState(1) << (n_))
#define NS_FRAME_IN_REFLOW NS_FRAME_STATE_BIT(0)
// This bit is set when a frame is created. After it has been reflowed
// once (during the DidReflow with a finished state) the bit is
// cleared.
#define NS_FRAME_FIRST_REFLOW NS_FRAME_STATE_BIT(1)
// For a continuation frame, if this bit is set, then this a "fluid"
// continuation, i.e., across a line boundary. Otherwise it's a "hard"
// continuation, e.g. a bidi continuation.
#define NS_FRAME_IS_FLUID_CONTINUATION NS_FRAME_STATE_BIT(2)
// If this bit is set, then a reference to the frame is being held
// elsewhere. The frame may want to send a notification when it is
// destroyed to allow these references to be cleared.
#define NS_FRAME_EXTERNAL_REFERENCE NS_FRAME_STATE_BIT(4)
// If this bit is set, this frame or one of its descendants has a
// percentage height that depends on an ancestor of this frame.
// (Or it did at one point in the past, since we don't necessarily clear
// the bit when it's no longer needed; it's an optimization.)
#define NS_FRAME_CONTAINS_RELATIVE_HEIGHT NS_FRAME_STATE_BIT(5)
// If this bit is set, then the frame corresponds to generated content
#define NS_FRAME_GENERATED_CONTENT NS_FRAME_STATE_BIT(6)
// If this bit is set the frame is a continuation that is holding overflow,
// i.e. it is a next-in-flow created to hold overflow after the box's
// height has ended. This means the frame should be a) at the top of the
// page and b) invisible: no borders, zero height, ignored in margin
// collapsing, etc. See nsContainerFrame.h
#define NS_FRAME_IS_OVERFLOW_CONTAINER NS_FRAME_STATE_BIT(7)
// If this bit is set, then the frame has been moved out of the flow,
// e.g., it is absolutely positioned or floated
#define NS_FRAME_OUT_OF_FLOW NS_FRAME_STATE_BIT(8)
// Frame can be an abs/fixed pos. container, if its style says so.
// MarkAs[Not]AbsoluteContainingBlock will assert that this bit is set.
// NS_FRAME_HAS_ABSPOS_CHILDREN must not be set when this bit is unset.
#define NS_FRAME_CAN_HAVE_ABSPOS_CHILDREN NS_FRAME_STATE_BIT(9)
// If this bit is set, then the frame and _all_ of its descendant frames need
// to be reflowed.
// This bit is set when the frame is first created.
// This bit is cleared by DidReflow after the required call to Reflow has
// finished.
// Do not set this bit yourself if you plan to pass the frame to
// nsIPresShell::FrameNeedsReflow. Pass the right arguments instead.
#define NS_FRAME_IS_DIRTY NS_FRAME_STATE_BIT(10)
// If this bit is set then the frame is too deep in the frame tree, and
// we'll stop updating it and its children, to prevent stack overflow
// and the like.
#define NS_FRAME_TOO_DEEP_IN_FRAME_TREE NS_FRAME_STATE_BIT(11)
// If this bit is set, then either:
// 1. the frame has at least one child that has the NS_FRAME_IS_DIRTY bit or
// NS_FRAME_HAS_DIRTY_CHILDREN bit set, or
// 2. the frame has had at least one child removed since the last reflow, or
// 3. the frame has had a style change that requires the frame to be reflowed
// but does not _necessarily_ require its descendants to be reflowed (e.g.,
// for a 'height', 'width', 'margin', etc. change, it's up to the
// applicable Reflow methods to decide whether the frame's children
// _actually_ need to be reflowed).
// If this bit is set but the NS_FRAME_IS_DIRTY is not set, then Reflow still
// needs to be called on the frame, but Reflow will likely not do as much work
// as it would if NS_FRAME_IS_DIRTY were set. See the comment documenting
// nsFrame::Reflow for more.
// This bit is cleared by DidReflow after the required call to Reflow has
// finished.
// Do not set this bit yourself if you plan to pass the frame to
// nsIPresShell::FrameNeedsReflow. Pass the right arguments instead.
#define NS_FRAME_HAS_DIRTY_CHILDREN NS_FRAME_STATE_BIT(12)
// If this bit is set, the frame has an associated view
#define NS_FRAME_HAS_VIEW NS_FRAME_STATE_BIT(13)
// If this bit is set, the frame was created from anonymous content.
#define NS_FRAME_INDEPENDENT_SELECTION NS_FRAME_STATE_BIT(14)
// If this bit is set, the frame is "special" (lame term, I know),
// which means that it is part of the mangled frame hierarchy that
// results when an inline has been split because of a nested block.
// See the comments in nsCSSFrameConstructor::ConstructInline for
// more details.
#define NS_FRAME_IS_SPECIAL NS_FRAME_STATE_BIT(15)
// If this bit is set, then transforms (e.g. CSS or SVG transforms) are allowed
// to affect the frame, and a transform may currently be in affect. If this bit
// is not set, then any transforms on the frame will be ignored.
// This is used primarily in GetTransformMatrix to optimize for the
// common case.
#define NS_FRAME_MAY_BE_TRANSFORMED NS_FRAME_STATE_BIT(16)
#ifdef IBMBIDI
// If this bit is set, the frame itself is a bidi continuation,
// or is incomplete (its next sibling is a bidi continuation)
#define NS_FRAME_IS_BIDI NS_FRAME_STATE_BIT(17)
#endif
// If this bit is set the frame has descendant with a view
#define NS_FRAME_HAS_CHILD_WITH_VIEW NS_FRAME_STATE_BIT(18)
// If this bit is set, then reflow may be dispatched from the current
// frame instead of the root frame.
#define NS_FRAME_REFLOW_ROOT NS_FRAME_STATE_BIT(19)
// Bits 20-31 and 60-63 of the frame state are reserved for implementations.
#define NS_FRAME_IMPL_RESERVED nsFrameState(0xF0000000FFF00000)
#define NS_FRAME_RESERVED ~NS_FRAME_IMPL_RESERVED
// This bit is set on floats whose parent does not contain their
// placeholder. This can happen for two reasons: (1) the float was
// split, and this piece is the continuation, or (2) the entire float
// didn't fit on the page.
// Note that this bit is also shared by text frames for
// TEXT_FORCE_TRIM_WHITESPACE. That's OK because we only check the
// NS_FRAME_IS_PUSHED_FLOAT bit on frames which we already know are
// out-of-flow.
#define NS_FRAME_IS_PUSHED_FLOAT NS_FRAME_STATE_BIT(32)
// This bit acts as a loop flag for recursive paint server drawing.
#define NS_FRAME_DRAWING_AS_PAINTSERVER NS_FRAME_STATE_BIT(33)
// Frame is a display root and the retained layer tree needs to be updated
// at the next paint via display list construction.
// Only meaningful for display roots, so we don't really need a global state
// bit; we could free up this bit with a little extra complexity.
#define NS_FRAME_UPDATE_LAYER_TREE NS_FRAME_STATE_BIT(36)
// Frame can accept absolutely positioned children.
#define NS_FRAME_HAS_ABSPOS_CHILDREN NS_FRAME_STATE_BIT(37)
// A display item for this frame has been painted as part of a ThebesLayer.
#define NS_FRAME_PAINTED_THEBES NS_FRAME_STATE_BIT(38)
// Frame is or is a descendant of something with a fixed height, unless that
// ancestor is a body or html element, and has no closer ancestor that is
// overflow:auto or overflow:scroll.
#define NS_FRAME_IN_CONSTRAINED_HEIGHT NS_FRAME_STATE_BIT(39)
// This is only set during painting
#define NS_FRAME_FORCE_DISPLAY_LIST_DESCEND_INTO NS_FRAME_STATE_BIT(40)
// Is this frame a container for font size inflation, i.e., is it a
// frame whose width is used to determine the inflation factor for
// everything whose nearest ancestor container for this frame?
#define NS_FRAME_FONT_INFLATION_CONTAINER NS_FRAME_STATE_BIT(41)
// Does this frame manage a region in which we do font size inflation,
// i.e., roughly, is it an element establishing a new block formatting
// context?
#define NS_FRAME_FONT_INFLATION_FLOW_ROOT NS_FRAME_STATE_BIT(42)
// This bit is set on SVG frames that are laid out using SVG's coordinate
// system based layout (as opposed to any of the CSS layout models). Note that
// this does not include nsSVGOuterSVGFrame since it takes part is CSS layout.
#define NS_FRAME_SVG_LAYOUT NS_FRAME_STATE_BIT(43)
// Is this frame allowed to have generated (::before/::after) content?
#define NS_FRAME_MAY_HAVE_GENERATED_CONTENT NS_FRAME_STATE_BIT(44)
// This bit is set on frames that create ContainerLayers with component
// alpha children. With BasicLayers we avoid creating these, so we mark
// the frames for future reference.
#define NS_FRAME_NO_COMPONENT_ALPHA NS_FRAME_STATE_BIT(45)
// The frame is a descendant of nsSVGTextFrame2 and is thus used for SVG
// text layout.
#define NS_FRAME_IS_SVG_TEXT NS_FRAME_STATE_BIT(47)
// Frame is marked as needing painting
#define NS_FRAME_NEEDS_PAINT NS_FRAME_STATE_BIT(48)
// Frame has a descendant frame that needs painting - This includes
// cross-doc children.
#define NS_FRAME_DESCENDANT_NEEDS_PAINT NS_FRAME_STATE_BIT(49)
// Frame is a descendant of a popup
#define NS_FRAME_IN_POPUP NS_FRAME_STATE_BIT(50)
// Frame has only descendant frames that needs painting - This includes
// cross-doc children. This guarantees that all descendents have
// NS_FRAME_NEEDS_PAINT and NS_FRAME_ALL_DESCENDANTS_NEED_PAINT, or they
// have no display items.
#define NS_FRAME_ALL_DESCENDANTS_NEED_PAINT NS_FRAME_STATE_BIT(51)
// Frame is marked as NS_FRAME_NEEDS_PAINT and also has an explicit
// rect stored to invalidate.
#define NS_FRAME_HAS_INVALID_RECT NS_FRAME_STATE_BIT(52)
// Box layout bits
#define NS_STATE_IS_HORIZONTAL NS_FRAME_STATE_BIT(22)
#define NS_STATE_IS_DIRECTION_NORMAL NS_FRAME_STATE_BIT(31)
// Helper macros
#define NS_SUBTREE_DIRTY(_frame) \
(((_frame)->GetStateBits() & \
(NS_FRAME_IS_DIRTY | NS_FRAME_HAS_DIRTY_CHILDREN)) != 0)
//----------------------------------------------------------------------
enum nsSelectionAmount {
eSelectCharacter = 0, // a single Unicode character;
// do not use this (prefer Cluster) unless you
// are really sure it's what you want
eSelectCluster = 1, // a grapheme cluster: this is usually the right
// choice for movement or selection by "character"
// as perceived by the user
eSelectWord = 2,
eSelectLine = 3, // previous drawn line in flow.
eSelectBeginLine = 4,
eSelectEndLine = 5,
eSelectNoAmount = 6, // just bounce back current offset.
eSelectParagraph = 7, // select a "paragraph"
eSelectWordNoSpace = 8 // select a "word" without selecting the following
// space, no matter what the default platform
// behavior is
};
enum nsDirection {
eDirNext = 0,
eDirPrevious= 1
};
enum nsSpread {
eSpreadNone = 0,
eSpreadAcross = 1,
eSpreadDown = 2
};
// Carried out margin flags
#define NS_CARRIED_TOP_MARGIN_IS_AUTO 0x1
#define NS_CARRIED_BOTTOM_MARGIN_IS_AUTO 0x2
//----------------------------------------------------------------------
/**
* Reflow status returned by the reflow methods. There are three
* completion statuses, represented by two bit flags.
*
* NS_FRAME_COMPLETE means the frame is fully complete.
*
* NS_FRAME_NOT_COMPLETE bit flag means the frame does not map all its
* content, and that the parent frame should create a continuing frame.
* If this bit isn't set it means the frame does map all its content.
* This bit is mutually exclusive with NS_FRAME_OVERFLOW_INCOMPLETE.
*
* NS_FRAME_OVERFLOW_INCOMPLETE bit flag means that the frame has
* overflow that is not complete, but its own box is complete.
* (This happens when content overflows a fixed-height box.)
* The reflower should place and size the frame and continue its reflow,
* but needs to create an overflow container as a continuation for this
* frame. See nsContainerFrame.h for more information.
* This bit is mutually exclusive with NS_FRAME_NOT_COMPLETE.
*
* Please use the SET macro for handling
* NS_FRAME_NOT_COMPLETE and NS_FRAME_OVERFLOW_INCOMPLETE.
*
* NS_FRAME_REFLOW_NEXTINFLOW bit flag means that the next-in-flow is
* dirty, and also needs to be reflowed. This status only makes sense
* for a frame that is not complete, i.e. you wouldn't set both
* NS_FRAME_COMPLETE and NS_FRAME_REFLOW_NEXTINFLOW.
*
* The low 8 bits of the nsReflowStatus are reserved for future extensions;
* the remaining 24 bits are zero (and available for extensions; however
* API's that accept/return nsReflowStatus must not receive/return any
* extension bits).
*
* @see #Reflow()
*/
typedef uint32_t nsReflowStatus;
#define NS_FRAME_COMPLETE 0 // Note: not a bit!
#define NS_FRAME_NOT_COMPLETE 0x1
#define NS_FRAME_REFLOW_NEXTINFLOW 0x2
#define NS_FRAME_OVERFLOW_INCOMPLETE 0x4
#define NS_FRAME_IS_COMPLETE(status) \
(0 == ((status) & NS_FRAME_NOT_COMPLETE))
#define NS_FRAME_IS_NOT_COMPLETE(status) \
(0 != ((status) & NS_FRAME_NOT_COMPLETE))
#define NS_FRAME_OVERFLOW_IS_INCOMPLETE(status) \
(0 != ((status) & NS_FRAME_OVERFLOW_INCOMPLETE))
#define NS_FRAME_IS_FULLY_COMPLETE(status) \
(NS_FRAME_IS_COMPLETE(status) && !NS_FRAME_OVERFLOW_IS_INCOMPLETE(status))
// These macros set or switch incompete statuses without touching th
// NS_FRAME_REFLOW_NEXTINFLOW bit.
#define NS_FRAME_SET_INCOMPLETE(status) \
status = (status & ~NS_FRAME_OVERFLOW_INCOMPLETE) | NS_FRAME_NOT_COMPLETE
#define NS_FRAME_SET_OVERFLOW_INCOMPLETE(status) \
status = (status & ~NS_FRAME_NOT_COMPLETE) | NS_FRAME_OVERFLOW_INCOMPLETE
// This macro tests to see if an nsReflowStatus is an error value
// or just a regular return value
#define NS_IS_REFLOW_ERROR(_status) (int32_t(_status) < 0)
/**
* Extensions to the reflow status bits defined by nsIFrameReflow
*/
// This bit is set, when a break is requested. This bit is orthogonal
// to the nsIFrame::nsReflowStatus completion bits.
#define NS_INLINE_BREAK 0x0100
// When a break is requested, this bit when set indicates that the
// break should occur after the frame just reflowed; when the bit is
// clear the break should occur before the frame just reflowed.
#define NS_INLINE_BREAK_BEFORE 0x0000
#define NS_INLINE_BREAK_AFTER 0x0200
// The type of break requested can be found in these bits.
#define NS_INLINE_BREAK_TYPE_MASK 0xF000
// Set when a break was induced by completion of a first-letter
#define NS_INLINE_BREAK_FIRST_LETTER_COMPLETE 0x10000
//----------------------------------------
// Macros that use those bits
#define NS_INLINE_IS_BREAK(_status) \
(0 != ((_status) & NS_INLINE_BREAK))
#define NS_INLINE_IS_BREAK_AFTER(_status) \
(0 != ((_status) & NS_INLINE_BREAK_AFTER))
#define NS_INLINE_IS_BREAK_BEFORE(_status) \
(NS_INLINE_BREAK == ((_status) & (NS_INLINE_BREAK|NS_INLINE_BREAK_AFTER)))
#define NS_INLINE_GET_BREAK_TYPE(_status) (((_status) >> 12) & 0xF)
#define NS_INLINE_MAKE_BREAK_TYPE(_type) ((_type) << 12)
// Construct a line-break-before status. Note that there is no
// completion status for a line-break before because we *know* that
// the frame will be reflowed later and hence it's current completion
// status doesn't matter.
#define NS_INLINE_LINE_BREAK_BEFORE() \
(NS_INLINE_BREAK | NS_INLINE_BREAK_BEFORE | \
NS_INLINE_MAKE_BREAK_TYPE(NS_STYLE_CLEAR_LINE))
// Take a completion status and add to it the desire to have a
// line-break after. For this macro we do need the completion status
// because the user of the status will need to know whether to
// continue the frame or not.
#define NS_INLINE_LINE_BREAK_AFTER(_completionStatus) \
((_completionStatus) | NS_INLINE_BREAK | NS_INLINE_BREAK_AFTER | \
NS_INLINE_MAKE_BREAK_TYPE(NS_STYLE_CLEAR_LINE))
// A frame is "truncated" if the part of the frame before the first
// possible break point was unable to fit in the available vertical
// space. Therefore, the entire frame should be moved to the next page.
// A frame that begins at the top of the page must never be "truncated".
// Doing so would likely cause an infinite loop.
#define NS_FRAME_TRUNCATED 0x0010
#define NS_FRAME_IS_TRUNCATED(status) \
(0 != ((status) & NS_FRAME_TRUNCATED))
#define NS_FRAME_SET_TRUNCATION(status, aReflowState, aMetrics) \
aReflowState.SetTruncated(aMetrics, &status);
// Merge the incompleteness, truncation and NS_FRAME_REFLOW_NEXTINFLOW
// status from aSecondary into aPrimary.
void NS_MergeReflowStatusInto(nsReflowStatus* aPrimary,
nsReflowStatus aSecondary);
//----------------------------------------------------------------------
/**
* DidReflow status values.
*/
MOZ_BEGIN_ENUM_CLASS(nsDidReflowStatus, uint32_t)
NOT_FINISHED,
FINISHED
MOZ_END_ENUM_CLASS(nsDidReflowStatus)
/**
* When there is no scrollable overflow rect, the visual overflow rect
* may be stored as four 1-byte deltas each strictly LESS THAN 0xff, for
* the four edges of the rectangle, or the four bytes may be read as a
* single 32-bit "overflow-rect type" value including at least one 0xff
* byte as an indicator that the value does NOT represent four deltas.
* If all four deltas are zero, this means that no overflow rect has
* actually been set (this is the initial state of newly-created frames).
*/
#define NS_FRAME_OVERFLOW_DELTA_MAX 0xfe // max delta we can store
#define NS_FRAME_OVERFLOW_NONE 0x00000000 // there are no overflow rects;
// code relies on this being
// the all-zero value
#define NS_FRAME_OVERFLOW_LARGE 0x000000ff // overflow is stored as a
// separate rect property
//----------------------------------------------------------------------
/**
* A frame in the layout model. This interface is supported by all frame
* objects.
*
* Frames can have multiple child lists: the default child list
* (referred to as the <i>principal</i> child list, and additional named
* child lists. There is an ordering of frames within a child list, but
* there is no order defined between frames in different child lists of
* the same parent frame.
*
* Frames are NOT reference counted. Use the Destroy() member function
* to destroy a frame. The lifetime of the frame hierarchy is bounded by the
* lifetime of the presentation shell which owns the frames.
*
* nsIFrame is a private Gecko interface. If you are not Gecko then you
* should not use it. If you're not in layout, then you won't be able to
* link to many of the functions defined here. Too bad.
*
* If you're not in layout but you must call functions in here, at least
* restrict yourself to calling virtual methods, which won't hurt you as badly.
*/
class nsIFrame : public nsQueryFrame
{
public:
typedef mozilla::FramePropertyDescriptor FramePropertyDescriptor;
typedef mozilla::FrameProperties FrameProperties;
typedef mozilla::layers::Layer Layer;
typedef mozilla::layout::FrameChildList ChildList;
typedef mozilla::layout::FrameChildListID ChildListID;
typedef mozilla::layout::FrameChildListIDs ChildListIDs;
typedef mozilla::layout::FrameChildListIterator ChildListIterator;
typedef mozilla::layout::FrameChildListArrayIterator ChildListArrayIterator;
NS_DECL_QUERYFRAME_TARGET(nsIFrame)
nsPresContext* PresContext() const {
return GetStyleContext()->GetRuleNode()->GetPresContext();
}
/**
* Called to initialize the frame. This is called immediately after creating
* the frame.
*
* If the frame is a continuing frame, then aPrevInFlow indicates the previous
* frame (the frame that was split).
*
* If you want a view associated with your frame, you should create the view
* now.
*
* @param aContent the content object associated with the frame
* @param aGeometricParent the geometric parent frame
* @param aContentParent the content parent frame
* @param aContext the style context associated with the frame
* @param aPrevInFlow the prev-in-flow frame
*/
NS_IMETHOD Init(nsIContent* aContent,
nsIFrame* aParent,
nsIFrame* aPrevInFlow) = 0;
/**
* Destroys this frame and each of its child frames (recursively calls
* Destroy() for each child). If this frame is a first-continuation, this
* also removes the frame from the primary frame map and clears undisplayed
* content for its content node.
* If the frame is a placeholder, it also ensures the out-of-flow frame's
* removal and destruction.
*/
void Destroy() { DestroyFrom(this); }
protected:
/**
* Return true if the frame is part of a Selection.
* Helper method to implement the public IsSelected() API.
*/
virtual bool IsFrameSelected() const;
/**
* Implements Destroy(). Do not call this directly except from within a
* DestroyFrom() implementation.
*
* @note This will always be called, so it is not necessary to override
* Destroy() in subclasses of nsFrame, just DestroyFrom().
*
* @param aDestructRoot is the root of the subtree being destroyed
*/
virtual void DestroyFrom(nsIFrame* aDestructRoot) = 0;
friend class nsFrameList; // needed to pass aDestructRoot through to children
friend class nsLineBox; // needed to pass aDestructRoot through to children
public:
/**
* Called to set the initial list of frames. This happens after the frame
* has been initialized.
*
* This is only called once for a given child list, and won't be called
* at all for child lists with no initial list of frames.
*
* @param aListID the child list identifier.
* @param aChildList list of child frames. Each of the frames has its
* NS_FRAME_IS_DIRTY bit set. Must not be empty.
* This method cannot handle the child list returned by
* GetAbsoluteListID().
* @return NS_ERROR_INVALID_ARG if there is no child list with the specified
* name,
* NS_ERROR_UNEXPECTED if the frame is an atomic frame or if the
* initial list of frames has already been set for that child list,
* NS_OK otherwise. In this case, SetInitialChildList empties out
* aChildList in the process of moving the frames over to its own
* child list.
* @see #Init()
*/
NS_IMETHOD SetInitialChildList(ChildListID aListID,
nsFrameList& aChildList) = 0;
/**
* This method is responsible for appending frames to the frame
* list. The implementation should append the frames to the specified
* child list and then generate a reflow command.
*
* @param aListID the child list identifier.
* @param aFrameList list of child frames to append. Each of the frames has
* its NS_FRAME_IS_DIRTY bit set. Must not be empty.
* @return NS_ERROR_INVALID_ARG if there is no child list with the specified
* name,
* NS_ERROR_UNEXPECTED if the frame is an atomic frame,
* NS_OK otherwise. In this case, AppendFrames empties out
* aFrameList in the process of moving the frames over to its own
* child list.
*/
NS_IMETHOD AppendFrames(ChildListID aListID,
nsFrameList& aFrameList) = 0;
/**
* This method is responsible for inserting frames into the frame
* list. The implementation should insert the new frames into the specified
* child list and then generate a reflow command.
*
* @param aListID the child list identifier.
* @param aPrevFrame the frame to insert frames <b>after</b>
* @param aFrameList list of child frames to insert <b>after</b> aPrevFrame.
* Each of the frames has its NS_FRAME_IS_DIRTY bit set
* @return NS_ERROR_INVALID_ARG if there is no child list with the specified
* name,
* NS_ERROR_UNEXPECTED if the frame is an atomic frame,
* NS_OK otherwise. In this case, InsertFrames empties out
* aFrameList in the process of moving the frames over to its own
* child list.
*/
NS_IMETHOD InsertFrames(ChildListID aListID,
nsIFrame* aPrevFrame,
nsFrameList& aFrameList) = 0;
/**
* This method is responsible for removing a frame in the frame
* list. The implementation should do something with the removed frame
* and then generate a reflow command. The implementation is responsible
* for destroying aOldFrame (the caller mustn't destroy aOldFrame).
*
* @param aListID the child list identifier.
* @param aOldFrame the frame to remove
* @return NS_ERROR_INVALID_ARG if there is no child list with the specified
* name,
* NS_ERROR_FAILURE if the child frame is not in the specified
* child list,
* NS_ERROR_UNEXPECTED if the frame is an atomic frame,
* NS_OK otherwise
*/
NS_IMETHOD RemoveFrame(ChildListID aListID,
nsIFrame* aOldFrame) = 0;
/**
* Get the content object associated with this frame. Does not add a reference.
*/
nsIContent* GetContent() const { return mContent; }
/**
* Get the frame that should be the parent for the frames of child elements
* May return nullptr during reflow
*/
virtual nsIFrame* GetContentInsertionFrame() { return this; }
/**
* Move any frames on our overflow list to the end of our principal list.
* @return true if there were any overflow frames
*/
virtual bool DrainSelfOverflowList() { return false; }
/**
* Get the frame that should be scrolled if the content associated
* with this frame is targeted for scrolling. For frames implementing
* nsIScrollableFrame this will return the frame itself. For frames
* like nsTextControlFrame that contain a scrollframe, will return
* that scrollframe.
*/
virtual nsIScrollableFrame* GetScrollTargetFrame() { return nullptr; }
/**
* Get the offsets of the frame. most will be 0,0
*
*/
NS_IMETHOD GetOffsets(int32_t &start, int32_t &end) const = 0;
/**
* Reset the offsets when splitting frames during Bidi reordering
*
*/
virtual void AdjustOffsetsForBidi(int32_t aStart, int32_t aEnd) {}
/**
* Get the style context associated with this frame.
*
*/
nsStyleContext* GetStyleContext() const { return mStyleContext; }
void SetStyleContext(nsStyleContext* aContext)
{
if (aContext != mStyleContext) {
nsStyleContext* oldStyleContext = mStyleContext;
mStyleContext = aContext;
if (aContext) {
aContext->AddRef();
DidSetStyleContext(oldStyleContext);
}
if (oldStyleContext)
oldStyleContext->Release();
}
}
void SetStyleContextWithoutNotification(nsStyleContext* aContext)
{
if (aContext != mStyleContext) {
if (mStyleContext)
mStyleContext->Release();
mStyleContext = aContext;
if (aContext) {
aContext->AddRef();
}
}
}
// Style post processing hook
// Attention: the old style context is the one we're forgetting,
// and hence possibly completely bogus for GetStyle* purposes.
// Use PeekStyleData instead.
virtual void DidSetStyleContext(nsStyleContext* aOldStyleContext) = 0;
/**
* Get the style data associated with this frame. This returns a
* const style struct pointer that should never be modified. See
* |nsIStyleContext::GetStyleData| for more information.
*
* The use of the typesafe functions below is preferred to direct use
* of this function.
*/
virtual const void* GetStyleDataExternal(nsStyleStructID aSID) const = 0;
/**
* Define typesafe getter functions for each style struct by
* preprocessing the list of style structs. These functions are the
* preferred way to get style data. The macro creates functions like:
* const nsStyleBorder* GetStyleBorder();
* const nsStyleColor* GetStyleColor();
*/
#ifdef _IMPL_NS_LAYOUT
#define STYLE_STRUCT(name_, checkdata_cb_, ctor_args_) \
const nsStyle##name_ * GetStyle##name_ () const { \
NS_ASSERTION(mStyleContext, "No style context found!"); \
return mStyleContext->GetStyle##name_ (); \
}
#else
#define STYLE_STRUCT(name_, checkdata_cb_, ctor_args_) \
const nsStyle##name_ * GetStyle##name_ () const { \
return static_cast<const nsStyle##name_*>( \
GetStyleDataExternal(eStyleStruct_##name_)); \
}
#endif
#include "nsStyleStructList.h"
#undef STYLE_STRUCT
#ifdef _IMPL_NS_LAYOUT
/** Also forward GetVisitedDependentColor to the style context */
nscolor GetVisitedDependentColor(nsCSSProperty aProperty)
{ return mStyleContext->GetVisitedDependentColor(aProperty); }
#endif
/**
* These methods are to access any additional style contexts that
* the frame may be holding. These are contexts that are children
* of the frame's primary context and are NOT used as style contexts
* for any child frames. These contexts also MUST NOT have any child
* contexts whatsoever. If you need to insert style contexts into the
* style tree, then you should create pseudo element frames to own them
* The indicies must be consecutive and implementations MUST return an
* NS_ERROR_INVALID_ARG if asked for an index that is out of range.
*/
virtual nsStyleContext* GetAdditionalStyleContext(int32_t aIndex) const = 0;
virtual void SetAdditionalStyleContext(int32_t aIndex,
nsStyleContext* aStyleContext) = 0;
/**
* Accessor functions for geometric parent
*/
nsIFrame* GetParent() const { return mParent; }
virtual void SetParent(nsIFrame* aParent) = 0;
/**
* Bounding rect of the frame. The values are in app units, and the origin is
* relative to the upper-left of the geometric parent. The size includes the
* content area, borders, and padding.
*
* Note: moving or sizing the frame does not affect the view's size or
* position.
*/
nsRect GetRect() const { return mRect; }
nsPoint GetPosition() const { return nsPoint(mRect.x, mRect.y); }
nsSize GetSize() const { return nsSize(mRect.width, mRect.height); }
/**
* When we change the size of the frame's border-box rect, we may need to
* reset the overflow rect if it was previously stored as deltas.
* (If it is currently a "large" overflow and could be re-packed as deltas,
* we don't bother as the cost of the allocation has already been paid.)
*/
void SetRect(const nsRect& aRect) {
if (mOverflow.mType != NS_FRAME_OVERFLOW_LARGE &&
mOverflow.mType != NS_FRAME_OVERFLOW_NONE) {
nsOverflowAreas overflow = GetOverflowAreas();
mRect = aRect;
SetOverflowAreas(overflow);
} else {
mRect = aRect;
}
}
void SetSize(const nsSize& aSize) {
SetRect(nsRect(mRect.TopLeft(), aSize));
}
void SetPosition(const nsPoint& aPt) { mRect.MoveTo(aPt); }
/**
* Return frame's computed offset due to relative positioning
*/
nsPoint GetRelativeOffset(const nsStyleDisplay* aDisplay = nullptr) const;
virtual nsPoint GetPositionOfChildIgnoringScrolling(nsIFrame* aChild)
{ return aChild->GetPosition(); }
nsPoint GetPositionIgnoringScrolling() {
return mParent ? mParent->GetPositionOfChildIgnoringScrolling(this)
: GetPosition();
}
static void DestroyRegion(void* aPropertyValue)
{
delete static_cast<nsRegion*>(aPropertyValue);
}
static void DestroyMargin(void* aPropertyValue)
{
delete static_cast<nsMargin*>(aPropertyValue);
}
static void DestroyRect(void* aPropertyValue)
{
delete static_cast<nsRect*>(aPropertyValue);
}
static void DestroyPoint(void* aPropertyValue)
{
delete static_cast<nsPoint*>(aPropertyValue);
}
static void DestroyOverflowAreas(void* aPropertyValue)
{
delete static_cast<nsOverflowAreas*>(aPropertyValue);
}
static void DestroySurface(void* aPropertyValue)
{
static_cast<gfxASurface*>(aPropertyValue)->Release();
}
#ifdef _MSC_VER
// XXX Workaround MSVC issue by making the static FramePropertyDescriptor
// non-const. See bug 555727.
#define NS_PROPERTY_DESCRIPTOR_CONST
#else
#define NS_PROPERTY_DESCRIPTOR_CONST const
#endif
#define NS_DECLARE_FRAME_PROPERTY(prop, dtor) \
static const FramePropertyDescriptor* prop() { \
static NS_PROPERTY_DESCRIPTOR_CONST FramePropertyDescriptor descriptor = { dtor, nullptr }; \
return &descriptor; \
}
// Don't use this unless you really know what you're doing!
#define NS_DECLARE_FRAME_PROPERTY_WITH_FRAME_IN_DTOR(prop, dtor) \
static const FramePropertyDescriptor* prop() { \
static NS_PROPERTY_DESCRIPTOR_CONST FramePropertyDescriptor descriptor = { nullptr, dtor }; \
return &descriptor; \
}
NS_DECLARE_FRAME_PROPERTY(IBSplitSpecialSibling, nullptr)
NS_DECLARE_FRAME_PROPERTY(IBSplitSpecialPrevSibling, nullptr)
NS_DECLARE_FRAME_PROPERTY(ComputedOffsetProperty, DestroyPoint)
NS_DECLARE_FRAME_PROPERTY(OutlineInnerRectProperty, DestroyRect)
NS_DECLARE_FRAME_PROPERTY(PreEffectsBBoxProperty, DestroyRect)
NS_DECLARE_FRAME_PROPERTY(PreTransformOverflowAreasProperty,
DestroyOverflowAreas)
// The initial overflow area passed to FinishAndStoreOverflow. This is only set
// on frames that Preserve3D(), and when at least one of the overflow areas
// differs from the frame bound rect.
NS_DECLARE_FRAME_PROPERTY(InitialOverflowProperty, DestroyOverflowAreas)
NS_DECLARE_FRAME_PROPERTY(UsedMarginProperty, DestroyMargin)
NS_DECLARE_FRAME_PROPERTY(UsedPaddingProperty, DestroyMargin)
NS_DECLARE_FRAME_PROPERTY(UsedBorderProperty, DestroyMargin)
NS_DECLARE_FRAME_PROPERTY(ScrollLayerCount, nullptr)
NS_DECLARE_FRAME_PROPERTY(LineBaselineOffset, nullptr)
NS_DECLARE_FRAME_PROPERTY(CachedBackgroundImage, DestroySurface)
NS_DECLARE_FRAME_PROPERTY(InvalidationRect, DestroyRect)
/**
* Return the distance between the border edge of the frame and the
* margin edge of the frame. Like GetRect(), returns the dimensions
* as of the most recent reflow.
*
* This doesn't include any margin collapsing that may have occurred.
*
* It also treats 'auto' margins as zero, and treats any margins that
* should have been turned into 'auto' because of overconstraint as
* having their original values.
*/
virtual nsMargin GetUsedMargin() const;
/**
* Return the distance between the border edge of the frame (which is
* its rect) and the padding edge of the frame. Like GetRect(), returns
* the dimensions as of the most recent reflow.
*
* Note that this differs from GetStyleBorder()->GetBorder() in that
* this describes region of the frame's box, and
* GetStyleBorder()->GetBorder() describes a border. They differ only
* for tables, particularly border-collapse tables.
*/
virtual nsMargin GetUsedBorder() const;
/**
* Return the distance between the padding edge of the frame and the
* content edge of the frame. Like GetRect(), returns the dimensions
* as of the most recent reflow.
*/
virtual nsMargin GetUsedPadding() const;
nsMargin GetUsedBorderAndPadding() const {
return GetUsedBorder() + GetUsedPadding();
}
/**
* Apply the result of GetSkipSides() on this frame to an nsMargin by
* setting to zero any sides that are skipped.
*/