Merge mozilla-central and tracemonkey. (a=blockers)
[mozilla-central.git] / layout / generic / nsHTMLReflowMetrics.h
blob8ea5d44bc974353d38cd258a8b8888629ca2bf7e
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* ***** BEGIN LICENSE BLOCK *****
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 * http://www.mozilla.org/MPL/
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the
13 * License.
15 * The Original Code is mozilla.org code.
17 * The Initial Developer of the Original Code is
18 * Netscape Communications Corporation.
19 * Portions created by the Initial Developer are Copyright (C) 1998
20 * the Initial Developer. All Rights Reserved.
22 * Contributor(s):
24 * Alternatively, the contents of this file may be used under the terms of
25 * either of the GNU General Public License Version 2 or later (the "GPL"),
26 * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 * in which case the provisions of the GPL or the LGPL are applicable instead
28 * of those above. If you wish to allow use of your version of this file only
29 * under the terms of either the GPL or the LGPL, and not to allow others to
30 * use your version of this file under the terms of the MPL, indicate your
31 * decision by deleting the provisions above and replace them with the notice
32 * and other provisions required by the GPL or the LGPL. If you do not delete
33 * the provisions above, a recipient may use your version of this file under
34 * the terms of any one of the MPL, the GPL or the LGPL.
36 * ***** END LICENSE BLOCK ***** */
38 /* struct containing the output from nsIFrame::Reflow */
40 #ifndef nsHTMLReflowMetrics_h___
41 #define nsHTMLReflowMetrics_h___
43 #include <stdio.h>
44 #include "nsISupports.h"
45 #include "nsMargin.h"
46 #include "nsRect.h"
47 // for MOZ_MATHML
48 #include "nsIRenderingContext.h" //to get struct nsBoundingMetrics
50 //----------------------------------------------------------------------
52 // Option flags
53 #ifdef MOZ_MATHML
54 #define NS_REFLOW_CALC_BOUNDING_METRICS 0x0001
55 #endif
57 /**
58 * When we store overflow areas as an array of scrollable and visual
59 * overflow, we use these indices.
61 * eOverflowType_LENGTH is needed (for gcc 4.5.*, at least) to ensure
62 * that 2 is a valid value of nsOverflowType for use in
63 * NS_FOR_FRAME_OVERFLOW_TYPES.
65 enum nsOverflowType { eVisualOverflow, eScrollableOverflow,
66 eOverflowType_LENGTH };
68 #define NS_FOR_FRAME_OVERFLOW_TYPES(var_) \
69 for (nsOverflowType var_ = nsOverflowType(0); var_ < 2; \
70 var_ = nsOverflowType(var_ + 1))
72 struct nsOverflowAreas {
73 private:
74 nsRect mRects[2];
75 public:
76 nsRect& Overflow(size_t aIndex) {
77 NS_ASSERTION(0 <= aIndex && aIndex < 2, "index out of range");
78 return mRects[aIndex];
80 const nsRect& Overflow(size_t aIndex) const {
81 NS_ASSERTION(0 <= aIndex && aIndex < 2, "index out of range");
82 return mRects[aIndex];
85 nsRect& VisualOverflow() { return mRects[eVisualOverflow]; }
86 const nsRect& VisualOverflow() const { return mRects[eVisualOverflow]; }
88 nsRect& ScrollableOverflow() { return mRects[eScrollableOverflow]; }
89 const nsRect& ScrollableOverflow() const { return mRects[eScrollableOverflow]; }
91 nsOverflowAreas() {
92 // default-initializes to zero due to nsRect's default constructor
95 nsOverflowAreas(const nsRect& aVisualOverflow,
96 const nsRect& aScrollableOverflow)
98 mRects[eVisualOverflow] = aVisualOverflow;
99 mRects[eScrollableOverflow] = aScrollableOverflow;
102 nsOverflowAreas(const nsOverflowAreas& aOther) {
103 *this = aOther;
106 nsOverflowAreas& operator=(const nsOverflowAreas& aOther) {
107 mRects[0] = aOther.mRects[0];
108 mRects[1] = aOther.mRects[1];
109 return *this;
112 bool operator==(const nsOverflowAreas& aOther) const {
113 // Scrollable overflow is a point-set rectangle and visual overflow
114 // is a pixel-set rectangle.
115 return VisualOverflow() == aOther.VisualOverflow() &&
116 ScrollableOverflow().IsExactEqual(aOther.ScrollableOverflow());
119 bool operator!=(const nsOverflowAreas& aOther) const {
120 return !(*this == aOther);
123 nsOverflowAreas operator+(const nsPoint& aPoint) const {
124 nsOverflowAreas result(*this);
125 result += aPoint;
126 return result;
129 nsOverflowAreas& operator+=(const nsPoint& aPoint) {
130 mRects[0] += aPoint;
131 mRects[1] += aPoint;
132 return *this;
135 void Clear() {
136 mRects[0].SetRect(0, 0, 0, 0);
137 mRects[1].SetRect(0, 0, 0, 0);
140 // Mutates |this| by unioning both overflow areas with |aOther|.
141 void UnionWith(const nsOverflowAreas& aOther);
143 // Mutates |this| by unioning both overflow areas with |aRect|.
144 void UnionAllWith(const nsRect& aRect);
146 // Mutates |this| by setting both overflow areas to |aRect|.
147 void SetAllTo(const nsRect& aRect);
151 * An nsCollapsingMargin represents a vertical collapsing margin between
152 * blocks as described in section 8.3.1 of CSS2,
153 * <URL: http://www.w3.org/TR/REC-CSS2/box.html#collapsing-margins >.
155 * All adjacent vertical margins collapse, and the resulting margin is
156 * the sum of the largest positive margin included and the smallest (most
157 * negative) negative margin included.
159 struct nsCollapsingMargin {
160 private:
161 nscoord mMostPos; // the largest positive margin included
162 nscoord mMostNeg; // the smallest negative margin included
164 public:
165 nsCollapsingMargin()
166 : mMostPos(0),
167 mMostNeg(0)
171 nsCollapsingMargin(const nsCollapsingMargin& aOther)
172 : mMostPos(aOther.mMostPos),
173 mMostNeg(aOther.mMostNeg)
177 PRBool operator==(const nsCollapsingMargin& aOther)
179 return mMostPos == aOther.mMostPos &&
180 mMostNeg == aOther.mMostNeg;
183 PRBool operator!=(const nsCollapsingMargin& aOther)
185 return !(*this == aOther);
188 nsCollapsingMargin& operator=(const nsCollapsingMargin& aOther)
190 mMostPos = aOther.mMostPos;
191 mMostNeg = aOther.mMostNeg;
192 return *this;
195 void Include(nscoord aCoord)
197 if (aCoord > mMostPos)
198 mMostPos = aCoord;
199 else if (aCoord < mMostNeg)
200 mMostNeg = aCoord;
203 void Include(const nsCollapsingMargin& aOther)
205 if (aOther.mMostPos > mMostPos)
206 mMostPos = aOther.mMostPos;
207 if (aOther.mMostNeg < mMostNeg)
208 mMostNeg = aOther.mMostNeg;
211 void Zero()
213 mMostPos = 0;
214 mMostNeg = 0;
217 PRBool IsZero() const
219 return (mMostPos == 0) && (mMostNeg == 0);
222 nscoord get() const
224 return mMostPos + mMostNeg;
229 * Reflow metrics used to return the frame's desired size and alignment
230 * information.
232 * @see #Reflow()
234 struct nsHTMLReflowMetrics {
235 nscoord width, height; // [OUT] desired width and height (border-box)
236 nscoord ascent; // [OUT] baseline (from top), or ASK_FOR_BASELINE
238 enum { ASK_FOR_BASELINE = nscoord_MAX };
240 #ifdef MOZ_MATHML
241 // Metrics that _exactly_ enclose the text to allow precise MathML placements.
242 // If the NS_REFLOW_CALC_BOUNDING_METRICS flag is set, then the caller is
243 // requesting that you also compute additional details about your inner
244 // bounding box and italic correction. For example, the bounding box of
245 // msup is the smallest rectangle that _exactly_ encloses both the text
246 // of the base and the text of the superscript.
247 nsBoundingMetrics mBoundingMetrics; // [OUT]
248 #endif
250 // Carried out bottom margin values. This is the collapsed
251 // (generational) bottom margin value.
252 nsCollapsingMargin mCarriedOutBottomMargin;
254 // For frames that have content that overflow their content area
255 // (HasOverflowAreas() is true) these rectangles represent the total
256 // area of the frame including visible overflow, i.e., don't include
257 // overflowing content that is hidden. The rects are in the local
258 // coordinate space of the frame, and should be at least as big as the
259 // desired size. If there is no content that overflows, then the
260 // overflow area is identical to the desired size and should be {0, 0,
261 // width, height}.
262 nsOverflowAreas mOverflowAreas;
264 nsRect& VisualOverflow()
265 { return mOverflowAreas.VisualOverflow(); }
266 const nsRect& VisualOverflow() const
267 { return mOverflowAreas.VisualOverflow(); }
268 nsRect& ScrollableOverflow()
269 { return mOverflowAreas.ScrollableOverflow(); }
270 const nsRect& ScrollableOverflow() const
271 { return mOverflowAreas.ScrollableOverflow(); }
273 // Set all of mOverflowAreas to (0, 0, width, height).
274 void SetOverflowAreasToDesiredBounds();
276 // Union all of mOverflowAreas with (0, 0, width, height).
277 void UnionOverflowAreasWithDesiredBounds();
279 PRUint32 mFlags;
281 // XXXldb Should |aFlags| generally be passed from parent to child?
282 // Some places do it, and some don't. |aFlags| should perhaps go away
283 // entirely.
284 nsHTMLReflowMetrics(PRUint32 aFlags = 0) {
285 mFlags = aFlags;
286 #ifdef MOZ_MATHML
287 mBoundingMetrics.Clear();
288 #endif
290 // XXX These are OUT parameters and so they shouldn't have to be
291 // initialized, but there are some bad frame classes that aren't
292 // properly setting them when returning from Reflow()...
293 width = height = 0;
294 ascent = ASK_FOR_BASELINE;
297 nsHTMLReflowMetrics& operator=(const nsHTMLReflowMetrics& aOther)
299 mFlags = aOther.mFlags;
300 mCarriedOutBottomMargin = aOther.mCarriedOutBottomMargin;
301 mOverflowAreas = aOther.mOverflowAreas;
302 #ifdef MOZ_MATHML
303 mBoundingMetrics = aOther.mBoundingMetrics;
304 #endif
306 width = aOther.width;
307 height = aOther.height;
308 ascent = aOther.ascent;
309 return *this;
314 #endif /* nsHTMLReflowMetrics_h___ */