/work/obj-fuzz/dist/include/mozilla/ReflowOutput.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 | | /* struct containing the output from nsIFrame::Reflow */ |
8 | | |
9 | | #ifndef mozilla_ReflowOutput_h |
10 | | #define mozilla_ReflowOutput_h |
11 | | |
12 | | #include "mozilla/WritingModes.h" |
13 | | #include "nsBoundingMetrics.h" |
14 | | #include "nsRect.h" |
15 | | |
16 | | //---------------------------------------------------------------------- |
17 | | |
18 | | namespace mozilla { |
19 | | struct ReflowInput; |
20 | | } // namespace mozilla |
21 | | |
22 | | /** |
23 | | * When we store overflow areas as an array of scrollable and visual |
24 | | * overflow, we use these indices. |
25 | | * |
26 | | * eOverflowType_LENGTH is needed (for gcc 4.5.*, at least) to ensure |
27 | | * that 2 is a valid value of nsOverflowType for use in |
28 | | * NS_FOR_FRAME_OVERFLOW_TYPES. |
29 | | */ |
30 | | enum nsOverflowType { eVisualOverflow, eScrollableOverflow, |
31 | | eOverflowType_LENGTH }; |
32 | | |
33 | | #define NS_FOR_FRAME_OVERFLOW_TYPES(var_) \ |
34 | 0 | for (nsOverflowType var_ = nsOverflowType(0); var_ < 2; \ |
35 | 0 | var_ = nsOverflowType(var_ + 1)) |
36 | | |
37 | | struct nsOverflowAreas { |
38 | | private: |
39 | | nsRect mRects[2]; |
40 | | public: |
41 | 0 | nsRect& Overflow(size_t aIndex) { |
42 | 0 | NS_ASSERTION(aIndex < 2, "index out of range"); |
43 | 0 | return mRects[aIndex]; |
44 | 0 | } |
45 | 0 | const nsRect& Overflow(size_t aIndex) const { |
46 | 0 | NS_ASSERTION(aIndex < 2, "index out of range"); |
47 | 0 | return mRects[aIndex]; |
48 | 0 | } |
49 | | |
50 | 0 | nsRect& VisualOverflow() { return mRects[eVisualOverflow]; } |
51 | 0 | const nsRect& VisualOverflow() const { return mRects[eVisualOverflow]; } |
52 | | |
53 | 0 | nsRect& ScrollableOverflow() { return mRects[eScrollableOverflow]; } |
54 | 0 | const nsRect& ScrollableOverflow() const { return mRects[eScrollableOverflow]; } |
55 | | |
56 | 0 | nsOverflowAreas() { |
57 | 0 | // default-initializes to zero due to nsRect's default constructor |
58 | 0 | } |
59 | | |
60 | | nsOverflowAreas(const nsRect& aVisualOverflow, |
61 | | const nsRect& aScrollableOverflow) |
62 | 0 | { |
63 | 0 | mRects[eVisualOverflow] = aVisualOverflow; |
64 | 0 | mRects[eScrollableOverflow] = aScrollableOverflow; |
65 | 0 | } |
66 | | |
67 | 0 | nsOverflowAreas(const nsOverflowAreas& aOther) { |
68 | 0 | *this = aOther; |
69 | 0 | } |
70 | | |
71 | 0 | nsOverflowAreas& operator=(const nsOverflowAreas& aOther) { |
72 | 0 | mRects[0] = aOther.mRects[0]; |
73 | 0 | mRects[1] = aOther.mRects[1]; |
74 | 0 | return *this; |
75 | 0 | } |
76 | | |
77 | 0 | bool operator==(const nsOverflowAreas& aOther) const { |
78 | 0 | // Scrollable overflow is a point-set rectangle and visual overflow |
79 | 0 | // is a pixel-set rectangle. |
80 | 0 | return VisualOverflow().IsEqualInterior(aOther.VisualOverflow()) && |
81 | 0 | ScrollableOverflow().IsEqualEdges(aOther.ScrollableOverflow()); |
82 | 0 | } |
83 | | |
84 | 0 | bool operator!=(const nsOverflowAreas& aOther) const { |
85 | 0 | return !(*this == aOther); |
86 | 0 | } |
87 | | |
88 | 0 | nsOverflowAreas operator+(const nsPoint& aPoint) const { |
89 | 0 | nsOverflowAreas result(*this); |
90 | 0 | result += aPoint; |
91 | 0 | return result; |
92 | 0 | } |
93 | | |
94 | 0 | nsOverflowAreas& operator+=(const nsPoint& aPoint) { |
95 | 0 | mRects[0] += aPoint; |
96 | 0 | mRects[1] += aPoint; |
97 | 0 | return *this; |
98 | 0 | } |
99 | | |
100 | 0 | void Clear() { |
101 | 0 | mRects[0].SetRect(0, 0, 0, 0); |
102 | 0 | mRects[1].SetRect(0, 0, 0, 0); |
103 | 0 | } |
104 | | |
105 | | // Mutates |this| by unioning both overflow areas with |aOther|. |
106 | | void UnionWith(const nsOverflowAreas& aOther); |
107 | | |
108 | | // Mutates |this| by unioning both overflow areas with |aRect|. |
109 | | void UnionAllWith(const nsRect& aRect); |
110 | | |
111 | | // Mutates |this| by setting both overflow areas to |aRect|. |
112 | | void SetAllTo(const nsRect& aRect); |
113 | | }; |
114 | | |
115 | | /** |
116 | | * An nsCollapsingMargin represents a vertical collapsing margin between |
117 | | * blocks as described in section 8.3.1 of CSS2, |
118 | | * <URL: http://www.w3.org/TR/REC-CSS2/box.html#collapsing-margins >. |
119 | | * |
120 | | * All adjacent vertical margins collapse, and the resulting margin is |
121 | | * the sum of the largest positive margin included and the smallest (most |
122 | | * negative) negative margin included. |
123 | | */ |
124 | | struct nsCollapsingMargin { |
125 | | private: |
126 | | nscoord mMostPos; // the largest positive margin included |
127 | | nscoord mMostNeg; // the smallest negative margin included |
128 | | |
129 | | public: |
130 | | nsCollapsingMargin() |
131 | | : mMostPos(0), |
132 | | mMostNeg(0) |
133 | 0 | { |
134 | 0 | } |
135 | | |
136 | | nsCollapsingMargin(const nsCollapsingMargin& aOther) |
137 | | : mMostPos(aOther.mMostPos), |
138 | | mMostNeg(aOther.mMostNeg) |
139 | 0 | { |
140 | 0 | } |
141 | | |
142 | | bool operator==(const nsCollapsingMargin& aOther) |
143 | 0 | { |
144 | 0 | return mMostPos == aOther.mMostPos && |
145 | 0 | mMostNeg == aOther.mMostNeg; |
146 | 0 | } |
147 | | |
148 | | bool operator!=(const nsCollapsingMargin& aOther) |
149 | 0 | { |
150 | 0 | return !(*this == aOther); |
151 | 0 | } |
152 | | |
153 | | nsCollapsingMargin& operator=(const nsCollapsingMargin& aOther) |
154 | 0 | { |
155 | 0 | mMostPos = aOther.mMostPos; |
156 | 0 | mMostNeg = aOther.mMostNeg; |
157 | 0 | return *this; |
158 | 0 | } |
159 | | |
160 | | void Include(nscoord aCoord) |
161 | 0 | { |
162 | 0 | if (aCoord > mMostPos) |
163 | 0 | mMostPos = aCoord; |
164 | 0 | else if (aCoord < mMostNeg) |
165 | 0 | mMostNeg = aCoord; |
166 | 0 | } |
167 | | |
168 | | void Include(const nsCollapsingMargin& aOther) |
169 | 0 | { |
170 | 0 | if (aOther.mMostPos > mMostPos) |
171 | 0 | mMostPos = aOther.mMostPos; |
172 | 0 | if (aOther.mMostNeg < mMostNeg) |
173 | 0 | mMostNeg = aOther.mMostNeg; |
174 | 0 | } |
175 | | |
176 | | void Zero() |
177 | 0 | { |
178 | 0 | mMostPos = 0; |
179 | 0 | mMostNeg = 0; |
180 | 0 | } |
181 | | |
182 | | bool IsZero() const |
183 | 0 | { |
184 | 0 | return (mMostPos == 0) && (mMostNeg == 0); |
185 | 0 | } |
186 | | |
187 | | nscoord get() const |
188 | 0 | { |
189 | 0 | return mMostPos + mMostNeg; |
190 | 0 | } |
191 | | }; |
192 | | |
193 | | namespace mozilla { |
194 | | |
195 | | /** |
196 | | * Reflow metrics used to return the frame's desired size and alignment |
197 | | * information. |
198 | | * |
199 | | * @see #Reflow() |
200 | | */ |
201 | | class ReflowOutput { |
202 | | public: |
203 | | explicit ReflowOutput(mozilla::WritingMode aWritingMode) |
204 | | : mISize(0) |
205 | | , mBSize(0) |
206 | | , mBlockStartAscent(ASK_FOR_BASELINE) |
207 | | , mWritingMode(aWritingMode) |
208 | 0 | { |
209 | 0 | } |
210 | | |
211 | | explicit ReflowOutput(const ReflowInput& aReflowInput); |
212 | | |
213 | | // ISize and BSize are logical-coordinate dimensions: |
214 | | // ISize is the size in the writing mode's inline direction (which equates to |
215 | | // width in horizontal writing modes, height in vertical ones), and BSize is |
216 | | // the size in the block-progression direction. |
217 | 0 | nscoord ISize(mozilla::WritingMode aWritingMode) const { |
218 | 0 | NS_ASSERTION(!aWritingMode.IsOrthogonalTo(mWritingMode), |
219 | 0 | "mismatched writing mode"); |
220 | 0 | return mISize; |
221 | 0 | } |
222 | 0 | nscoord BSize(mozilla::WritingMode aWritingMode) const { |
223 | 0 | NS_ASSERTION(!aWritingMode.IsOrthogonalTo(mWritingMode), |
224 | 0 | "mismatched writing mode"); |
225 | 0 | return mBSize; |
226 | 0 | } |
227 | 0 | mozilla::LogicalSize Size(mozilla::WritingMode aWritingMode) const { |
228 | 0 | NS_ASSERTION(!aWritingMode.IsOrthogonalTo(mWritingMode), |
229 | 0 | "mismatched writing mode"); |
230 | 0 | return mozilla::LogicalSize(aWritingMode, mISize, mBSize); |
231 | 0 | } |
232 | | |
233 | 0 | nscoord& ISize(mozilla::WritingMode aWritingMode) { |
234 | 0 | NS_ASSERTION(!aWritingMode.IsOrthogonalTo(mWritingMode), |
235 | 0 | "mismatched writing mode"); |
236 | 0 | return mISize; |
237 | 0 | } |
238 | 0 | nscoord& BSize(mozilla::WritingMode aWritingMode) { |
239 | 0 | NS_ASSERTION(!aWritingMode.IsOrthogonalTo(mWritingMode), |
240 | 0 | "mismatched writing mode"); |
241 | 0 | return mBSize; |
242 | 0 | } |
243 | | |
244 | | // Set inline and block size from a LogicalSize, converting to our |
245 | | // writing mode as necessary. |
246 | | void SetSize(mozilla::WritingMode aWM, mozilla::LogicalSize aSize) |
247 | 0 | { |
248 | 0 | mozilla::LogicalSize convertedSize = aSize.ConvertTo(mWritingMode, aWM); |
249 | 0 | mBSize = convertedSize.BSize(mWritingMode); |
250 | 0 | mISize = convertedSize.ISize(mWritingMode); |
251 | 0 | } |
252 | | |
253 | | // Set both inline and block size to zero -- no need for a writing mode! |
254 | | void ClearSize() |
255 | 0 | { |
256 | 0 | mISize = mBSize = 0; |
257 | 0 | } |
258 | | |
259 | | // Width and Height are physical dimensions, independent of writing mode. |
260 | | // Accessing these is slightly more expensive than accessing the logical |
261 | | // dimensions (once vertical writing mode support is enabled); as far as |
262 | | // possible, client code should work purely with logical dimensions. |
263 | 0 | nscoord Width() const { return mWritingMode.IsVertical() ? mBSize : mISize; } |
264 | 0 | nscoord Height() const { return mWritingMode.IsVertical() ? mISize : mBSize; } |
265 | | |
266 | | // It's only meaningful to consider "ascent" on the block-start side of the |
267 | | // frame, so no need to pass a writing mode argument |
268 | | nscoord BlockStartAscent() const |
269 | 0 | { |
270 | 0 | return mBlockStartAscent; |
271 | 0 | } |
272 | | |
273 | 0 | nscoord& Width() { return mWritingMode.IsVertical() ? mBSize : mISize; } |
274 | 0 | nscoord& Height() { return mWritingMode.IsVertical() ? mISize : mBSize; } |
275 | | |
276 | | nsSize PhysicalSize() |
277 | 0 | { |
278 | 0 | return Size(mWritingMode).GetPhysicalSize(mWritingMode); |
279 | 0 | } |
280 | | |
281 | | void SetBlockStartAscent(nscoord aAscent) |
282 | 0 | { |
283 | 0 | mBlockStartAscent = aAscent; |
284 | 0 | } |
285 | | |
286 | | enum { ASK_FOR_BASELINE = nscoord_MAX }; |
287 | | |
288 | | // Metrics that _exactly_ enclose the text to allow precise MathML placements. |
289 | | nsBoundingMetrics mBoundingMetrics; // [OUT] |
290 | | |
291 | | // Carried out block-end margin values. This is the collapsed |
292 | | // (generational) block-end margin value. |
293 | | nsCollapsingMargin mCarriedOutBEndMargin; |
294 | | |
295 | | // For frames that have content that overflow their content area |
296 | | // (HasOverflowAreas() is true) these rectangles represent the total |
297 | | // area of the frame including visible overflow, i.e., don't include |
298 | | // overflowing content that is hidden. The rects are in the local |
299 | | // coordinate space of the frame, and should be at least as big as the |
300 | | // desired size. If there is no content that overflows, then the |
301 | | // overflow area is identical to the desired size and should be {0, 0, |
302 | | // width, height}. |
303 | | nsOverflowAreas mOverflowAreas; |
304 | | |
305 | | nsRect& VisualOverflow() |
306 | 0 | { return mOverflowAreas.VisualOverflow(); } |
307 | | const nsRect& VisualOverflow() const |
308 | 0 | { return mOverflowAreas.VisualOverflow(); } |
309 | | nsRect& ScrollableOverflow() |
310 | 0 | { return mOverflowAreas.ScrollableOverflow(); } |
311 | | const nsRect& ScrollableOverflow() const |
312 | 0 | { return mOverflowAreas.ScrollableOverflow(); } |
313 | | |
314 | | // Set all of mOverflowAreas to (0, 0, width, height). |
315 | | void SetOverflowAreasToDesiredBounds(); |
316 | | |
317 | | // Union all of mOverflowAreas with (0, 0, width, height). |
318 | | void UnionOverflowAreasWithDesiredBounds(); |
319 | | |
320 | 0 | mozilla::WritingMode GetWritingMode() const { return mWritingMode; } |
321 | | |
322 | | private: |
323 | | nscoord mISize, mBSize; // [OUT] desired width and height (border-box) |
324 | | nscoord mBlockStartAscent; // [OUT] baseline (in Block direction), or ASK_FOR_BASELINE |
325 | | mozilla::WritingMode mWritingMode; |
326 | | }; |
327 | | |
328 | | } // mozilla namespace |
329 | | |
330 | | #endif // mozilla_ReflowOutput_h |