/usr/include/thunderbird/DisplayListClipState.h is in thunderbird-dev 1:52.8.0-1~deb8u1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
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 | /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* 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/. */
#ifndef DISPLAYLISTCLIPSTATE_H_
#define DISPLAYLISTCLIPSTATE_H_
#include "DisplayItemClip.h"
#include "DisplayItemScrollClip.h"
#include "mozilla/DebugOnly.h"
class nsIFrame;
class nsIScrollableFrame;
class nsDisplayListBuilder;
namespace mozilla {
/**
* All clip coordinates are in appunits relative to the reference frame
* for the display item we're building.
*/
class DisplayListClipState {
public:
DisplayListClipState()
: mClipContentDescendants(nullptr)
, mClipContainingBlockDescendants(nullptr)
, mCurrentCombinedClip(nullptr)
, mScrollClipContentDescendants(nullptr)
, mScrollClipContainingBlockDescendants(nullptr)
, mClipContentDescendantsScrollClip(nullptr)
, mStackingContextAncestorSC(nullptr)
{}
/**
* Returns intersection of mClipContainingBlockDescendants and
* mClipContentDescendants, allocated on aBuilder's arena.
*/
const DisplayItemClip* GetCurrentCombinedClip(nsDisplayListBuilder* aBuilder);
const DisplayItemClip* GetClipForContainingBlockDescendants() const
{
return mClipContainingBlockDescendants;
}
const DisplayItemClip* GetClipForContentDescendants() const
{
return mClipContentDescendants;
}
const DisplayItemScrollClip* GetCurrentInnermostScrollClip();
const DisplayItemScrollClip* CurrentAncestorScrollClipForStackingContextContents()
{
return mStackingContextAncestorSC;
}
class AutoSaveRestore;
friend class AutoSaveRestore;
class AutoClipContainingBlockDescendantsToContentBox;
friend class AutoClipContainingBlockDescendantsToContentBox;
class AutoClipMultiple;
friend class AutoClipMultiple;
enum {
ASSUME_DRAWING_RESTRICTED_TO_CONTENT_RECT = 0x01
};
private:
void SetClipForContainingBlockDescendants(const DisplayItemClip* aClip)
{
mClipContainingBlockDescendants = aClip;
mCurrentCombinedClip = nullptr;
}
void SetScrollClipForContainingBlockDescendants(nsDisplayListBuilder* aBuilder,
const DisplayItemScrollClip* aScrollClip);
void Clear()
{
mClipContentDescendants = nullptr;
mClipContainingBlockDescendants = nullptr;
mCurrentCombinedClip = nullptr;
// We do not clear scroll clips.
}
void EnterStackingContextContents(bool aClear)
{
if (aClear) {
mClipContentDescendants = nullptr;
mClipContainingBlockDescendants = nullptr;
mCurrentCombinedClip = nullptr;
mScrollClipContentDescendants = nullptr;
mScrollClipContainingBlockDescendants = nullptr;
mStackingContextAncestorSC = nullptr;
} else {
mStackingContextAncestorSC = GetCurrentInnermostScrollClip();
}
}
/**
* Clear the current clip, and instead add it as a scroll clip to the current
* scroll clip chain.
*/
void TurnClipIntoScrollClipForContentDescendants(nsDisplayListBuilder* aBuilder,
nsIScrollableFrame* aScrollableFrame);
void TurnClipIntoScrollClipForContainingBlockDescendants(nsDisplayListBuilder* aBuilder,
nsIScrollableFrame* aScrollableFrame);
/**
* Insert a scroll clip without clearing the current clip.
* The returned DisplayItemScrollClip will have mIsAsyncScrollable == false,
* and it can be activated once the scroll frame knows that it needs to be
* async scrollable.
*/
DisplayItemScrollClip* InsertInactiveScrollClipForContentDescendants(nsDisplayListBuilder* aBuilder,
nsIScrollableFrame* aScrollableFrame);
DisplayItemScrollClip* InsertInactiveScrollClipForContainingBlockDescendants(nsDisplayListBuilder* aBuilder,
nsIScrollableFrame* aScrollableFrame);
DisplayItemScrollClip* CreateInactiveScrollClip(nsDisplayListBuilder* aBuilder,
nsIScrollableFrame* aScrollableFrame);
/**
* Intersects the given clip rect (with optional aRadii) with the current
* mClipContainingBlockDescendants and sets mClipContainingBlockDescendants to
* the result, stored in aClipOnStack.
*/
void ClipContainingBlockDescendants(const nsRect& aRect,
const nscoord* aRadii,
DisplayItemClip& aClipOnStack);
void ClipContentDescendants(const nsRect& aRect,
const nscoord* aRadii,
DisplayItemClip& aClipOnStack);
void ClipContentDescendants(const nsRect& aRect,
const nsRect& aRoundedRect,
const nscoord* aRadii,
DisplayItemClip& aClipOnStack);
/**
* Clips containing-block descendants to the frame's content-box,
* taking border-radius into account.
* If aFlags contains ASSUME_DRAWING_RESTRICTED_TO_CONTENT_RECT then
* we assume display items will not draw outside the content rect, so
* clipping is only required if there is a border-radius. This is an
* optimization to reduce the amount of clipping required.
*/
void ClipContainingBlockDescendantsToContentBox(nsDisplayListBuilder* aBuilder,
nsIFrame* aFrame,
DisplayItemClip& aClipOnStack,
uint32_t aFlags);
/**
* All content descendants (i.e. following placeholder frames to their
* out-of-flows if necessary) should be clipped by mClipContentDescendants.
* Null if no clipping applies.
*/
const DisplayItemClip* mClipContentDescendants;
/**
* All containing-block descendants (i.e. frame descendants), including
* display items for the current frame, should be clipped by
* mClipContainingBlockDescendants.
* Null if no clipping applies.
*/
const DisplayItemClip* mClipContainingBlockDescendants;
/**
* The intersection of mClipContentDescendants and
* mClipContainingBlockDescendants.
* Allocated in the nsDisplayListBuilder arena. Null if none has been
* allocated or both mClipContentDescendants and mClipContainingBlockDescendants
* are null.
*/
const DisplayItemClip* mCurrentCombinedClip;
/**
* The same for scroll clips.
*/
const DisplayItemScrollClip* mScrollClipContentDescendants;
const DisplayItemScrollClip* mScrollClipContainingBlockDescendants;
/**
* The scroll clip that was in effect when mClipContentDescendants was set.
*/
const DisplayItemScrollClip* mClipContentDescendantsScrollClip;
/**
* A scroll clip that is an ancestor of all the scroll clips that were
* "current" on this clip state since EnterStackingContextContents was
* called.
*/
const DisplayItemScrollClip* mStackingContextAncestorSC;
};
/**
* A class to automatically save and restore the current clip state. Also
* offers methods for modifying the clip state. Only one modification is allowed
* to be in scope at a time using one of these objects; multiple modifications
* require nested objects. The interface is written this way to prevent
* dangling pointers to DisplayItemClips.
*/
class DisplayListClipState::AutoSaveRestore {
public:
explicit AutoSaveRestore(nsDisplayListBuilder* aBuilder);
void Restore()
{
if (!mClearedForStackingContextContents) {
// Forward along the ancestor scroll clip to the original clip state.
mSavedState.mStackingContextAncestorSC =
DisplayItemScrollClip::PickAncestor(mSavedState.mStackingContextAncestorSC,
mState.mStackingContextAncestorSC);
}
mState = mSavedState;
#ifdef DEBUG
mRestored = true;
#endif
}
~AutoSaveRestore()
{
Restore();
}
void Clear()
{
NS_ASSERTION(!mRestored, "Already restored!");
mState.Clear();
#ifdef DEBUG
mClipUsed = false;
#endif
}
void EnterStackingContextContents(bool aClear)
{
NS_ASSERTION(!mRestored, "Already restored!");
mState.EnterStackingContextContents(aClear);
mClearedForStackingContextContents = aClear;
}
void ExitStackingContextContents(const DisplayItemScrollClip** aOutContainerSC)
{
if (mClearedForStackingContextContents) {
// If we cleared the scroll clip, then the scroll clip that was current
// just before we cleared it is the one that needs to be set on the
// container item.
*aOutContainerSC = mSavedState.GetCurrentInnermostScrollClip();
} else {
// If we didn't clear the scroll clip, then the container item needs to
// get a scroll clip that's an ancestor of all its direct child items'
// scroll clips.
// The simplest way to satisfy this requirement would be to just take the
// root scroll clip (i.e. nullptr). However, this can cause the bounds of
// the container items to be enlarged unnecessarily, so instead we try to
// take the "deepest" scroll clip that satisfies the requirement.
// Usually this is the scroll clip that was current before we entered
// the stacking context contents (call that the "initial scroll clip").
// There are two cases in which the container scroll clip *won't* be the
// initial scroll clip (instead the container scroll clip will be a
// proper ancestor of the initial scroll clip):
// (1) If SetScrollClipForContainingBlockDescendants was called with an
// ancestor scroll clip of the initial scroll clip while we were
// building our direct child items. This happens if we entered a
// position:absolute or position:fixed element whose containing
// block is an ancestor of the frame that generated the initial
// scroll clip. Then the "ancestor scroll clip for stacking context
// contents" will be set to that scroll clip.
// (2) If one of our direct child items is a container item for which
// (1) or (2) happened.
*aOutContainerSC = mState.CurrentAncestorScrollClipForStackingContextContents();
}
Restore();
}
bool SavedStateHasRoundedCorners()
{
const DisplayItemScrollClip* scrollClip = mSavedState.GetCurrentInnermostScrollClip();
if (scrollClip && scrollClip->HasRoundedCorners()) {
return true;
}
const DisplayItemClip* clip = mSavedState.GetClipForContainingBlockDescendants();
if (clip && clip->GetRoundedRectCount() > 0) {
return true;
}
clip = mSavedState.GetClipForContentDescendants();
if (clip && clip->GetRoundedRectCount() > 0) {
return true;
}
return false;
}
void TurnClipIntoScrollClipForContentDescendants(nsDisplayListBuilder* aBuilder, nsIScrollableFrame* aScrollableFrame)
{
NS_ASSERTION(!mRestored, "Already restored!");
mState.TurnClipIntoScrollClipForContentDescendants(aBuilder, aScrollableFrame);
#ifdef DEBUG
mClipUsed = true;
#endif
}
void TurnClipIntoScrollClipForContainingBlockDescendants(nsDisplayListBuilder* aBuilder, nsIScrollableFrame* aScrollableFrame)
{
NS_ASSERTION(!mRestored, "Already restored!");
mState.TurnClipIntoScrollClipForContainingBlockDescendants(aBuilder, aScrollableFrame);
#ifdef DEBUG
mClipUsed = true;
#endif
}
DisplayItemScrollClip* InsertInactiveScrollClipForContentDescendants(nsDisplayListBuilder* aBuilder, nsIScrollableFrame* aScrollableFrame)
{
NS_ASSERTION(!mRestored, "Already restored!");
DisplayItemScrollClip* scrollClip = mState.InsertInactiveScrollClipForContentDescendants(aBuilder, aScrollableFrame);
#ifdef DEBUG
mClipUsed = true;
#endif
return scrollClip;
}
DisplayItemScrollClip* InsertInactiveScrollClipForContainingBlockDescendants(nsDisplayListBuilder* aBuilder, nsIScrollableFrame* aScrollableFrame)
{
NS_ASSERTION(!mRestored, "Already restored!");
DisplayItemScrollClip* scrollClip = mState.InsertInactiveScrollClipForContainingBlockDescendants(aBuilder, aScrollableFrame);
#ifdef DEBUG
mClipUsed = true;
#endif
return scrollClip;
}
/**
* Intersects the given clip rect (with optional aRadii) with the current
* mClipContainingBlockDescendants and sets mClipContainingBlockDescendants to
* the result, stored in aClipOnStack.
*/
void ClipContainingBlockDescendants(const nsRect& aRect,
const nscoord* aRadii = nullptr)
{
NS_ASSERTION(!mRestored, "Already restored!");
NS_ASSERTION(!mClipUsed, "mClip already used");
#ifdef DEBUG
mClipUsed = true;
#endif
mState.ClipContainingBlockDescendants(aRect, aRadii, mClip);
}
void ClipContentDescendants(const nsRect& aRect,
const nscoord* aRadii = nullptr)
{
NS_ASSERTION(!mRestored, "Already restored!");
NS_ASSERTION(!mClipUsed, "mClip already used");
#ifdef DEBUG
mClipUsed = true;
#endif
mState.ClipContentDescendants(aRect, aRadii, mClip);
}
void ClipContentDescendants(const nsRect& aRect,
const nsRect& aRoundedRect,
const nscoord* aRadii = nullptr)
{
NS_ASSERTION(!mRestored, "Already restored!");
NS_ASSERTION(!mClipUsed, "mClip already used");
#ifdef DEBUG
mClipUsed = true;
#endif
mState.ClipContentDescendants(aRect, aRoundedRect, aRadii, mClip);
}
/**
* Clips containing-block descendants to the frame's content-box,
* taking border-radius into account.
* If aFlags contains ASSUME_DRAWING_RESTRICTED_TO_CONTENT_RECT then
* we assume display items will not draw outside the content rect, so
* clipping is only required if there is a border-radius. This is an
* optimization to reduce the amount of clipping required.
*/
void ClipContainingBlockDescendantsToContentBox(nsDisplayListBuilder* aBuilder,
nsIFrame* aFrame,
uint32_t aFlags = 0)
{
NS_ASSERTION(!mRestored, "Already restored!");
NS_ASSERTION(!mClipUsed, "mClip already used");
#ifdef DEBUG
mClipUsed = true;
#endif
mState.ClipContainingBlockDescendantsToContentBox(aBuilder, aFrame, mClip, aFlags);
}
protected:
DisplayListClipState& mState;
DisplayListClipState mSavedState;
DisplayItemClip mClip;
#ifdef DEBUG
bool mClipUsed;
bool mRestored;
#endif
bool mClearedForStackingContextContents;
};
class DisplayListClipState::AutoClipContainingBlockDescendantsToContentBox : public AutoSaveRestore {
public:
AutoClipContainingBlockDescendantsToContentBox(nsDisplayListBuilder* aBuilder,
nsIFrame* aFrame,
uint32_t aFlags = 0)
: AutoSaveRestore(aBuilder)
{
#ifdef DEBUG
mClipUsed = true;
#endif
mState.ClipContainingBlockDescendantsToContentBox(aBuilder, aFrame, mClip, aFlags);
}
};
/**
* Do not use this outside of nsFrame::BuildDisplayListForChild, use
* multiple AutoSaveRestores instead. We provide this class just to ensure
* BuildDisplayListForChild is as efficient as possible.
*/
class DisplayListClipState::AutoClipMultiple : public AutoSaveRestore {
public:
explicit AutoClipMultiple(nsDisplayListBuilder* aBuilder)
: AutoSaveRestore(aBuilder)
#ifdef DEBUG
, mExtraClipUsed(false)
#endif
{}
/**
* *aClip must survive longer than this object. Be careful!!!
*/
void SetClipForContainingBlockDescendants(const DisplayItemClip* aClip)
{
mState.SetClipForContainingBlockDescendants(aClip);
}
void SetScrollClipForContainingBlockDescendants(nsDisplayListBuilder* aBuilder,
const DisplayItemScrollClip* aScrollClip)
{
mState.SetScrollClipForContainingBlockDescendants(aBuilder, aScrollClip);
}
/**
* Intersects the given clip rect (with optional aRadii) with the current
* mClipContainingBlockDescendants and sets mClipContainingBlockDescendants to
* the result, stored in aClipOnStack.
*/
void ClipContainingBlockDescendantsExtra(const nsRect& aRect,
const nscoord* aRadii)
{
NS_ASSERTION(!mRestored, "Already restored!");
NS_ASSERTION(!mExtraClipUsed, "mExtraClip already used");
#ifdef DEBUG
mExtraClipUsed = true;
#endif
mState.ClipContainingBlockDescendants(aRect, aRadii, mExtraClip);
}
protected:
DisplayItemClip mExtraClip;
#ifdef DEBUG
bool mExtraClipUsed;
#endif
};
} // namespace mozilla
#endif /* DISPLAYLISTCLIPSTATE_H_ */
|