/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* 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/. */
uint32_t end = mRoundedClipRects.Length(); if (!end) { return;
}
// Push clips for any rects that come BEFORE the rect at |aEnd - 1|, if any:
ApplyRoundedRectClipsTo(aContext, aAppUnitsPerDevPixel, 0, end - 1);
// Now fill the rect at |aEnd - 1|:
RefPtr<Path> roundedRect = MakeRoundedRectPath(
aDrawTarget, aAppUnitsPerDevPixel, mRoundedClipRects[end - 1]);
aDrawTarget.Fill(roundedRect, ColorPattern(aColor));
// Finally, pop any clips that we may have pushed: for (uint32_t i = 0; i < end - 1; ++i) {
aContext->PopClip();
}
}
nsRect result = aRect.Intersect(mClipRect); for (uint32_t i = 0, iEnd = mRoundedClipRects.Length(); i < iEnd; ++i) {
result = result.Intersect(mRoundedClipRects[i].mRect);
} return result;
}
void DisplayItemClip::RemoveRoundedCorners() { if (mRoundedClipRects.IsEmpty()) { return;
}
// If the two rectangles are totally disjoint, just add them both - otherwise // we'd end up adding one big enclosing rect if (!rect1.Intersects(rect2) ||
memcmp(aR1.mRadii, aR2.mRadii, sizeof(aR1.mRadii))) {
aOut->Or(*aOut, rect1.Intersect(aBounds));
aOut->Or(*aOut, rect2.Intersect(aOtherBounds)); return;
}
// At this point, we know that the radii haven't changed, and that the bounds // are different in some way. To explain how this works, consider the case // where the rounded rect has just been translated along the X direction. // | ______________________ _ _ _ _ _ _ | // | / / \ \ | // | | | | // | | aR1 | | aR2 | | // | | | | // | \ __________\___________ / _ _ _ _ _ / | // | | // The invalidation region will be as if we lopped off the left rounded part // of aR2, and the right rounded part of aR1, and XOR'd them: // | ______________________ _ _ _ _ _ _ | // | -/-----------/- -\-----------\- | // | |-------------- --|------------ | // | |-----aR1---|-- --|-----aR2---| | // | |-------------- --|------------ | // | -\ __________\-__________-/ _ _ _ _ _ /- | // | | // The logic below just implements this idea, but generalized to both the // X and Y dimensions. The "(...)Adjusted(...)" values represent the lopped // off sides.
nscoord highestAdjustedBottom = std::min(
rect1.YMost() - aR1.mRadii[eCornerBottomLeftY],
std::min(rect1.YMost() - aR1.mRadii[eCornerBottomRightY],
std::min(rect2.YMost() - aR2.mRadii[eCornerBottomLeftY],
rect2.YMost() - aR2.mRadii[eCornerBottomRightY])));
nscoord lowestAdjustedTop =
std::max(rect1.Y() + aR1.mRadii[eCornerTopLeftY],
std::max(rect1.Y() + aR1.mRadii[eCornerTopRightY],
std::max(rect2.Y() + aR2.mRadii[eCornerTopLeftY],
rect2.Y() + aR2.mRadii[eCornerTopRightY])));
// We only want to add an invalidation rect if the bounds have changed. If we // always added all of the 4 rects below, we would always be invalidating a // border around the rects, even in cases where we just translated along the X // or Y axis.
nsRegion r; // First, or with the Y delta rects, wide along the X axis if (rect1.Y() != rect2.Y()) {
r.Or(r, nsRect(minLeft, highestTop, maxRight - minLeft,
lowestAdjustedTop - highestTop));
} if (rect1.YMost() != rect2.YMost()) {
r.Or(r, nsRect(minLeft, highestAdjustedBottom, maxRight - minLeft,
lowestBottom - highestAdjustedBottom));
} // Then, or with the X delta rects, wide along the Y axis if (rect1.X() != rect2.X()) {
r.Or(r, nsRect(minLeft, highestTop, maxAdjustedLeft - minLeft,
lowestBottom - highestTop));
} if (rect1.XMost() != rect2.XMost()) {
r.Or(r, nsRect(minAdjustedRight, highestTop, maxRight - minAdjustedRight,
lowestBottom - highestTop));
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.