1 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* ***** BEGIN LICENSE BLOCK *****
3 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 : *
5 : * The contents of this file are subject to the Mozilla Public License Version
6 : * 1.1 (the "License"); you may not use this file except in compliance with
7 : * the License. You may obtain a copy of the License at
8 : * http://www.mozilla.org/MPL/
9 : *
10 : * Software distributed under the License is distributed on an "AS IS" basis,
11 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 : * for the specific language governing rights and limitations under the
13 : * License.
14 : *
15 : * The Original Code is mozilla.org code.
16 : *
17 : * The Initial Developer of the Original Code is
18 : * Netscape Communications Corporation.
19 : * Portions created by the Initial Developer are Copyright (C) 1998
20 : * the Initial Developer. All Rights Reserved.
21 : *
22 : * Contributor(s):
23 : *
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.
35 : *
36 : * ***** END LICENSE BLOCK ***** */
37 :
38 : /* struct containing the output from nsIFrame::Reflow */
39 :
40 : #ifndef nsHTMLReflowMetrics_h___
41 : #define nsHTMLReflowMetrics_h___
42 :
43 : #include <stdio.h>
44 : #include "nsISupports.h"
45 : #include "nsMargin.h"
46 : #include "nsRect.h"
47 : #include "nsBoundingMetrics.h"
48 :
49 : //----------------------------------------------------------------------
50 :
51 : // Option flags
52 : #define NS_REFLOW_CALC_BOUNDING_METRICS 0x0001
53 :
54 : /**
55 : * When we store overflow areas as an array of scrollable and visual
56 : * overflow, we use these indices.
57 : *
58 : * eOverflowType_LENGTH is needed (for gcc 4.5.*, at least) to ensure
59 : * that 2 is a valid value of nsOverflowType for use in
60 : * NS_FOR_FRAME_OVERFLOW_TYPES.
61 : */
62 : enum nsOverflowType { eVisualOverflow, eScrollableOverflow,
63 : eOverflowType_LENGTH };
64 :
65 : #define NS_FOR_FRAME_OVERFLOW_TYPES(var_) \
66 : for (nsOverflowType var_ = nsOverflowType(0); var_ < 2; \
67 : var_ = nsOverflowType(var_ + 1))
68 :
69 0 : struct nsOverflowAreas {
70 : private:
71 : nsRect mRects[2];
72 : public:
73 0 : nsRect& Overflow(size_t aIndex) {
74 0 : NS_ASSERTION(0 <= aIndex && aIndex < 2, "index out of range");
75 0 : return mRects[aIndex];
76 : }
77 0 : const nsRect& Overflow(size_t aIndex) const {
78 0 : NS_ASSERTION(0 <= aIndex && aIndex < 2, "index out of range");
79 0 : return mRects[aIndex];
80 : }
81 :
82 0 : nsRect& VisualOverflow() { return mRects[eVisualOverflow]; }
83 0 : const nsRect& VisualOverflow() const { return mRects[eVisualOverflow]; }
84 :
85 0 : nsRect& ScrollableOverflow() { return mRects[eScrollableOverflow]; }
86 0 : const nsRect& ScrollableOverflow() const { return mRects[eScrollableOverflow]; }
87 :
88 0 : nsOverflowAreas() {
89 : // default-initializes to zero due to nsRect's default constructor
90 0 : }
91 :
92 0 : nsOverflowAreas(const nsRect& aVisualOverflow,
93 : const nsRect& aScrollableOverflow)
94 0 : {
95 0 : mRects[eVisualOverflow] = aVisualOverflow;
96 0 : mRects[eScrollableOverflow] = aScrollableOverflow;
97 0 : }
98 :
99 0 : nsOverflowAreas(const nsOverflowAreas& aOther) {
100 0 : *this = aOther;
101 0 : }
102 :
103 0 : nsOverflowAreas& operator=(const nsOverflowAreas& aOther) {
104 0 : mRects[0] = aOther.mRects[0];
105 0 : mRects[1] = aOther.mRects[1];
106 0 : return *this;
107 : }
108 :
109 0 : bool operator==(const nsOverflowAreas& aOther) const {
110 : // Scrollable overflow is a point-set rectangle and visual overflow
111 : // is a pixel-set rectangle.
112 0 : return VisualOverflow().IsEqualInterior(aOther.VisualOverflow()) &&
113 0 : ScrollableOverflow().IsEqualEdges(aOther.ScrollableOverflow());
114 : }
115 :
116 0 : bool operator!=(const nsOverflowAreas& aOther) const {
117 0 : return !(*this == aOther);
118 : }
119 :
120 0 : nsOverflowAreas operator+(const nsPoint& aPoint) const {
121 0 : nsOverflowAreas result(*this);
122 0 : result += aPoint;
123 : return result;
124 : }
125 :
126 0 : nsOverflowAreas& operator+=(const nsPoint& aPoint) {
127 0 : mRects[0] += aPoint;
128 0 : mRects[1] += aPoint;
129 0 : return *this;
130 : }
131 :
132 0 : void Clear() {
133 0 : mRects[0].SetRect(0, 0, 0, 0);
134 0 : mRects[1].SetRect(0, 0, 0, 0);
135 0 : }
136 :
137 : // Mutates |this| by unioning both overflow areas with |aOther|.
138 : void UnionWith(const nsOverflowAreas& aOther);
139 :
140 : // Mutates |this| by unioning both overflow areas with |aRect|.
141 : void UnionAllWith(const nsRect& aRect);
142 :
143 : // Mutates |this| by setting both overflow areas to |aRect|.
144 : void SetAllTo(const nsRect& aRect);
145 : };
146 :
147 : /**
148 : * An nsCollapsingMargin represents a vertical collapsing margin between
149 : * blocks as described in section 8.3.1 of CSS2,
150 : * <URL: http://www.w3.org/TR/REC-CSS2/box.html#collapsing-margins >.
151 : *
152 : * All adjacent vertical margins collapse, and the resulting margin is
153 : * the sum of the largest positive margin included and the smallest (most
154 : * negative) negative margin included.
155 : */
156 : struct nsCollapsingMargin {
157 : private:
158 : nscoord mMostPos; // the largest positive margin included
159 : nscoord mMostNeg; // the smallest negative margin included
160 :
161 : public:
162 0 : nsCollapsingMargin()
163 : : mMostPos(0),
164 0 : mMostNeg(0)
165 : {
166 0 : }
167 :
168 0 : nsCollapsingMargin(const nsCollapsingMargin& aOther)
169 : : mMostPos(aOther.mMostPos),
170 0 : mMostNeg(aOther.mMostNeg)
171 : {
172 0 : }
173 :
174 0 : bool operator==(const nsCollapsingMargin& aOther)
175 : {
176 : return mMostPos == aOther.mMostPos &&
177 0 : mMostNeg == aOther.mMostNeg;
178 : }
179 :
180 0 : bool operator!=(const nsCollapsingMargin& aOther)
181 : {
182 0 : return !(*this == aOther);
183 : }
184 :
185 0 : nsCollapsingMargin& operator=(const nsCollapsingMargin& aOther)
186 : {
187 0 : mMostPos = aOther.mMostPos;
188 0 : mMostNeg = aOther.mMostNeg;
189 0 : return *this;
190 : }
191 :
192 0 : void Include(nscoord aCoord)
193 : {
194 0 : if (aCoord > mMostPos)
195 0 : mMostPos = aCoord;
196 0 : else if (aCoord < mMostNeg)
197 0 : mMostNeg = aCoord;
198 0 : }
199 :
200 0 : void Include(const nsCollapsingMargin& aOther)
201 : {
202 0 : if (aOther.mMostPos > mMostPos)
203 0 : mMostPos = aOther.mMostPos;
204 0 : if (aOther.mMostNeg < mMostNeg)
205 0 : mMostNeg = aOther.mMostNeg;
206 0 : }
207 :
208 0 : void Zero()
209 : {
210 0 : mMostPos = 0;
211 0 : mMostNeg = 0;
212 0 : }
213 :
214 0 : bool IsZero() const
215 : {
216 0 : return (mMostPos == 0) && (mMostNeg == 0);
217 : }
218 :
219 0 : nscoord get() const
220 : {
221 0 : return mMostPos + mMostNeg;
222 : }
223 : };
224 :
225 : /**
226 : * Reflow metrics used to return the frame's desired size and alignment
227 : * information.
228 : *
229 : * @see #Reflow()
230 : */
231 0 : struct nsHTMLReflowMetrics {
232 : nscoord width, height; // [OUT] desired width and height (border-box)
233 : nscoord ascent; // [OUT] baseline (from top), or ASK_FOR_BASELINE
234 :
235 : PRUint32 mFlags;
236 :
237 : enum { ASK_FOR_BASELINE = nscoord_MAX };
238 :
239 : // Metrics that _exactly_ enclose the text to allow precise MathML placements.
240 : // If the NS_REFLOW_CALC_BOUNDING_METRICS flag is set, then the caller is
241 : // requesting that you also compute additional details about your inner
242 : // bounding box and italic correction. For example, the bounding box of
243 : // msup is the smallest rectangle that _exactly_ encloses both the text
244 : // of the base and the text of the superscript.
245 : nsBoundingMetrics mBoundingMetrics; // [OUT]
246 :
247 : // Carried out bottom margin values. This is the collapsed
248 : // (generational) bottom margin value.
249 : nsCollapsingMargin mCarriedOutBottomMargin;
250 :
251 : // For frames that have content that overflow their content area
252 : // (HasOverflowAreas() is true) these rectangles represent the total
253 : // area of the frame including visible overflow, i.e., don't include
254 : // overflowing content that is hidden. The rects are in the local
255 : // coordinate space of the frame, and should be at least as big as the
256 : // desired size. If there is no content that overflows, then the
257 : // overflow area is identical to the desired size and should be {0, 0,
258 : // width, height}.
259 : nsOverflowAreas mOverflowAreas;
260 :
261 0 : nsRect& VisualOverflow()
262 0 : { return mOverflowAreas.VisualOverflow(); }
263 0 : const nsRect& VisualOverflow() const
264 0 : { return mOverflowAreas.VisualOverflow(); }
265 0 : nsRect& ScrollableOverflow()
266 0 : { return mOverflowAreas.ScrollableOverflow(); }
267 : const nsRect& ScrollableOverflow() const
268 : { return mOverflowAreas.ScrollableOverflow(); }
269 :
270 : // Set all of mOverflowAreas to (0, 0, width, height).
271 : void SetOverflowAreasToDesiredBounds();
272 :
273 : // Union all of mOverflowAreas with (0, 0, width, height).
274 : void UnionOverflowAreasWithDesiredBounds();
275 :
276 : // XXXldb Should |aFlags| generally be passed from parent to child?
277 : // Some places do it, and some don't. |aFlags| should perhaps go away
278 : // entirely.
279 : // XXX width/height/ascent are OUT parameters and so they shouldn't
280 : // have to be initialized, but there are some bad frame classes that
281 : // aren't properly setting them when returning from Reflow()...
282 0 : nsHTMLReflowMetrics(PRUint32 aFlags = 0)
283 0 : : width(0), height(0), ascent(ASK_FOR_BASELINE), mFlags(aFlags)
284 0 : {}
285 : };
286 :
287 : #endif /* nsHTMLReflowMetrics_h___ */
|