本文整理匯總了C++中DrawTarget::DrawSurface方法的典型用法代碼示例。如果您正苦於以下問題:C++ DrawTarget::DrawSurface方法的具體用法?C++ DrawTarget::DrawSurface怎麽用?C++ DrawTarget::DrawSurface使用的例子?那麽, 這裏精選的方法代碼示例或許可以為您提供幫助。您也可以進一步了解該方法所在類DrawTarget
的用法示例。
在下文中一共展示了DrawTarget::DrawSurface方法的13個代碼示例,這些例子默認根據受歡迎程度排序。您可以為喜歡或者感覺有用的代碼點讚,您的評價將有助於係統推薦出更棒的C++代碼示例。
示例1: pattern
static void
RepeatOrStretchSurface(DrawTarget& aDT, SourceSurface* aSurface,
const Rect& aDest, const Rect& aSrc, Rect& aSkipRect)
{
if (aSkipRect.Contains(aDest)) {
return;
}
if ((!aDT.GetTransform().IsRectilinear() &&
aDT.GetBackendType() != BackendType::CAIRO) ||
(aDT.GetBackendType() == BackendType::DIRECT2D)) {
// Use stretching if possible, since it leads to less seams when the
// destination is transformed. However, don't do this if we're using cairo,
// because if cairo is using pixman it won't render anything for large
// stretch factors because pixman's internal fixed point precision is not
// high enough to handle those scale factors.
// Calling FillRect on a D2D backend with a repeating pattern is much slower
// than DrawSurface, so special case the D2D backend here.
aDT.DrawSurface(aSurface, aDest, aSrc);
return;
}
SurfacePattern pattern(aSurface, ExtendMode::REPEAT,
Matrix::Translation(aDest.TopLeft() - aSrc.TopLeft()),
Filter::GOOD, RoundedToInt(aSrc));
aDT.FillRect(aDest, pattern);
}
示例2: dstRect
void
ClientLayerManager::MakeSnapshotIfRequired()
{
if (!mShadowTarget) {
return;
}
if (mWidget) {
if (CompositorChild* remoteRenderer = GetRemoteRenderer()) {
nsIntRect bounds = ToOutsideIntRect(mShadowTarget->GetClipExtents());
SurfaceDescriptor inSnapshot;
if (!bounds.IsEmpty() &&
mForwarder->AllocSurfaceDescriptor(bounds.Size().ToIntSize(),
gfxContentType::COLOR_ALPHA,
&inSnapshot) &&
remoteRenderer->SendMakeSnapshot(inSnapshot, bounds)) {
RefPtr<DataSourceSurface> surf = GetSurfaceForDescriptor(inSnapshot);
DrawTarget* dt = mShadowTarget->GetDrawTarget();
Rect dstRect(bounds.x, bounds.y, bounds.width, bounds.height);
Rect srcRect(0, 0, bounds.width, bounds.height);
dt->DrawSurface(surf, dstRect, srcRect,
DrawSurfaceOptions(),
DrawOptions(1.0f, CompositionOp::OP_OVER));
}
mForwarder->DestroySharedSurface(&inSnapshot);
}
}
mShadowTarget = nullptr;
}
示例3: widgetRect
void
ClientLayerManager::MakeSnapshotIfRequired()
{
if (!mShadowTarget) {
return;
}
if (mWidget) {
if (CompositorChild* remoteRenderer = GetRemoteRenderer()) {
nsIntRect bounds;
mWidget->GetBounds(bounds);
IntSize widgetSize = bounds.Size().ToIntSize();
SurfaceDescriptor inSnapshot, snapshot;
if (mForwarder->AllocSurfaceDescriptor(widgetSize,
gfxContentType::COLOR_ALPHA,
&inSnapshot) &&
// The compositor will usually reuse |snapshot| and return
// it through |outSnapshot|, but if it doesn't, it's
// responsible for freeing |snapshot|.
remoteRenderer->SendMakeSnapshot(inSnapshot, &snapshot)) {
RefPtr<DataSourceSurface> surf = GetSurfaceForDescriptor(snapshot);
DrawTarget* dt = mShadowTarget->GetDrawTarget();
Rect widgetRect(Point(0, 0), Size(widgetSize.width, widgetSize.height));
dt->DrawSurface(surf, widgetRect, widgetRect,
DrawSurfaceOptions(),
DrawOptions(1.0f, CompositionOp::OP_OVER));
}
if (IsSurfaceDescriptorValid(snapshot)) {
mForwarder->DestroySharedSurface(&snapshot);
}
}
}
mShadowTarget = nullptr;
}
示例4: backingSize
void
gfxQuartzNativeDrawing::EndNativeDrawing()
{
NS_ASSERTION(mCGContext, "EndNativeDrawing called without BeginNativeDrawing");
MOZ_ASSERT(!mContext->IsCairo(), "BeginNativeDrawing succeeded with cairo context?");
mBorrowedContext.Finish();
if (mDrawTarget) {
DrawTarget *dest = mContext->GetDrawTarget();
RefPtr<SourceSurface> source = mDrawTarget->Snapshot();
IntSize backingSize(NSToIntFloor(mNativeRect.width * mBackingScale),
NSToIntFloor(mNativeRect.height * mBackingScale));
Matrix oldTransform = dest->GetTransform();
Matrix newTransform = oldTransform;
newTransform.Translate(mNativeRect.x, mNativeRect.y);
newTransform.Scale(1.0f / mBackingScale, 1.0f / mBackingScale);
dest->SetTransform(newTransform);
dest->DrawSurface(source,
gfx::Rect(0, 0, backingSize.width, backingSize.height),
gfx::Rect(0, 0, backingSize.width, backingSize.height));
dest->SetTransform(oldTransform);
}
}
示例5: pathRect
/***
* Blur an inset box shadow by doing:
* 1) Create a minimal box shadow path that creates a frame.
* 2) Draw the box shadow portion over the destination surface.
* 3) The "inset" part is created by a clip rect that properly clips
* the alpha mask so that it has clean edges. We still create the full
* proper alpha mask, but let the clip deal with the clean edges.
*
* All parameters should already be in device pixels.
*/
void
gfxAlphaBoxBlur::BlurInsetBox(gfxContext* aDestinationCtx,
const Rect aDestinationRect,
const Rect aShadowClipRect,
const gfxIntSize aBlurRadius,
const gfxIntSize aSpreadRadius,
const Color& aShadowColor,
bool aHasBorderRadius,
const RectCornerRadii& aInnerClipRadii,
const Rect aSkipRect)
{
if ((aBlurRadius.width <= 0 && aBlurRadius.height <= 0)) {
// The outer path must be rounded out
// If not blurring, we're done now.
Rect pathRect(aDestinationRect);
pathRect.RoundOut();
FillDestinationPath(aDestinationCtx, pathRect, aShadowClipRect,
aShadowColor, aHasBorderRadius, aInnerClipRadii);
return;
}
DrawTarget* destDrawTarget = aDestinationCtx->GetDrawTarget();
Rect outerRect;
Rect innerRect;
Margin pathMargins;
ComputeRectsForInsetBoxShadow(aBlurRadius, aSpreadRadius,
aDestinationRect, aShadowClipRect,
outerRect, innerRect,
pathMargins);
IntPoint topLeft;
RefPtr<SourceSurface> minInsetBlur = GetInsetBlur(outerRect, innerRect,
aBlurRadius, aSpreadRadius,
aInnerClipRadii, aShadowColor,
aHasBorderRadius,
topLeft, aDestinationCtx);
if (!minInsetBlur) {
return;
}
Rect destRectOuter(aDestinationRect);
destRectOuter.RoundIn();
Rect destRectInner(destRectOuter);
destRectInner.Deflate(pathMargins);
Rect srcRectOuter(outerRect);
srcRectOuter.MoveBy(abs(topLeft.x), abs(topLeft.y));
Rect srcRectInner(srcRectOuter);
srcRectInner.Deflate(pathMargins);
if (srcRectOuter.IsEqualInterior(srcRectInner)) {
destDrawTarget->DrawSurface(minInsetBlur, destRectOuter, srcRectOuter);
} else {
DrawBoxShadows(*destDrawTarget, minInsetBlur,
destRectOuter, destRectInner,
srcRectOuter, srcRectInner,
aSkipRect);
}
}
示例6:
static void
DrawCorner(DrawTarget& aDT, SourceSurface* aSurface,
const Rect& aDest, const Rect& aSrc, Rect& aSkipRect)
{
if (aSkipRect.Contains(aDest)) {
return;
}
aDT.DrawSurface(aSurface, aDest, aSrc);
}
示例7: srcOuter
/***
* Blur an inset box shadow by doing:
* 1) Create a minimal box shadow path that creates a frame.
* 2) Draw the box shadow portion over the destination surface.
* 3) The "inset" part is created by a clip rect that properly clips
* the alpha mask so that it has clean edges. We still create the full
* proper alpha mask, but let the clip deal with the clean edges.
*
* All parameters should already be in device pixels.
*/
void
gfxAlphaBoxBlur::BlurInsetBox(gfxContext* aDestinationCtx,
const Rect aDestinationRect,
const Rect aShadowClipRect,
const IntSize aBlurRadius,
const IntSize aSpreadRadius,
const Color& aShadowColor,
bool aHasBorderRadius,
const RectCornerRadii& aInnerClipRadii,
const Rect aSkipRect,
const Point aShadowOffset)
{
DrawTarget* destDrawTarget = aDestinationCtx->GetDrawTarget();
// Blur inset shadows ALWAYS have a 0 spread radius.
if ((aBlurRadius.width <= 0 && aBlurRadius.height <= 0)) {
FillDestinationPath(aDestinationCtx, aDestinationRect, aShadowClipRect,
aShadowColor, aHasBorderRadius, aInnerClipRadii);
return;
}
IntMargin extendDest;
IntMargin slice;
bool didMoveOffset;
RefPtr<SourceSurface> minInsetBlur = GetInsetBlur(extendDest, slice,
aDestinationRect, aShadowClipRect,
aBlurRadius, aSpreadRadius,
aInnerClipRadii, aShadowColor,
aHasBorderRadius, aShadowOffset,
didMoveOffset, destDrawTarget);
if (!minInsetBlur) {
return;
}
Rect srcOuter(Point(), Size(minInsetBlur->GetSize()));
Rect srcInner = srcOuter;
srcInner.Deflate(Margin(slice));
Rect dstOuter(aDestinationRect);
if (!didMoveOffset) {
dstOuter.MoveBy(aShadowOffset);
}
dstOuter.Inflate(Margin(extendDest));
Rect dstInner = dstOuter;
dstInner.Deflate(Margin(slice));
if (dstOuter.Size() == srcOuter.Size()) {
destDrawTarget->DrawSurface(minInsetBlur, dstOuter, srcOuter);
} else {
DrawBoxShadows(*destDrawTarget, minInsetBlur,
dstOuter, dstInner,
srcOuter, srcInner,
aSkipRect);
}
}
示例8: dstRect
void
ClientLayerManager::MakeSnapshotIfRequired()
{
if (!mShadowTarget) {
return;
}
if (mWidget) {
if (CompositorBridgeChild* remoteRenderer = GetRemoteRenderer()) {
// The compositor doesn't draw to a different sized surface
// when there's a rotation. Instead we rotate the result
// when drawing into dt
LayoutDeviceIntRect outerBounds;
mWidget->GetBounds(outerBounds);
IntRect bounds = ToOutsideIntRect(mShadowTarget->GetClipExtents());
if (mTargetRotation) {
bounds =
RotateRect(bounds, outerBounds.ToUnknownRect(), mTargetRotation);
}
SurfaceDescriptor inSnapshot;
if (!bounds.IsEmpty() &&
mForwarder->AllocSurfaceDescriptor(bounds.Size(),
gfxContentType::COLOR_ALPHA,
&inSnapshot)) {
// Make a copy of |inSnapshot| because the call to send it over IPC
// will call forget() on the Shmem inside, and zero it out.
SurfaceDescriptor outSnapshot = inSnapshot;
if (remoteRenderer->SendMakeSnapshot(inSnapshot, bounds)) {
RefPtr<DataSourceSurface> surf = GetSurfaceForDescriptor(outSnapshot);
DrawTarget* dt = mShadowTarget->GetDrawTarget();
Rect dstRect(bounds.x, bounds.y, bounds.width, bounds.height);
Rect srcRect(0, 0, bounds.width, bounds.height);
gfx::Matrix rotate =
ComputeTransformForUnRotation(outerBounds.ToUnknownRect(),
mTargetRotation);
gfx::Matrix oldMatrix = dt->GetTransform();
dt->SetTransform(rotate * oldMatrix);
dt->DrawSurface(surf, dstRect, srcRect,
DrawSurfaceOptions(),
DrawOptions(1.0f, CompositionOp::OP_OVER));
dt->SetTransform(oldMatrix);
}
mForwarder->DestroySurfaceDescriptor(&outSnapshot);
}
}
}
mShadowTarget = nullptr;
}
示例9: dstRect
void
ClientLayerManager::MakeSnapshotIfRequired()
{
if (!mShadowTarget) {
return;
}
if (mWidget) {
if (CompositorChild* remoteRenderer = GetRemoteRenderer()) {
// The compositor doesn't draw to a different sized surface
// when there's a rotation. Instead we rotate the result
// when drawing into dt
nsIntRect outerBounds;
mWidget->GetBounds(outerBounds);
nsIntRect bounds = ToOutsideIntRect(mShadowTarget->GetClipExtents());
if (mTargetRotation) {
bounds = RotateRect(bounds, outerBounds, mTargetRotation);
}
SurfaceDescriptor inSnapshot;
if (!bounds.IsEmpty() &&
mForwarder->AllocSurfaceDescriptor(bounds.Size().ToIntSize(),
gfxContentType::COLOR_ALPHA,
&inSnapshot) &&
remoteRenderer->SendMakeSnapshot(inSnapshot, bounds)) {
RefPtr<DataSourceSurface> surf = GetSurfaceForDescriptor(inSnapshot);
DrawTarget* dt = mShadowTarget->GetDrawTarget();
Rect dstRect(bounds.x, bounds.y, bounds.width, bounds.height);
Rect srcRect(0, 0, bounds.width, bounds.height);
gfx::Matrix rotate = ComputeTransformForUnRotation(outerBounds, mTargetRotation);
gfx::Matrix oldMatrix = dt->GetTransform();
dt->SetTransform(oldMatrix * rotate);
dt->DrawSurface(surf, dstRect, srcRect,
DrawSurfaceOptions(),
DrawOptions(1.0f, CompositionOp::OP_OVER));
dt->SetTransform(oldMatrix);
}
mForwarder->DestroySharedSurface(&inSnapshot);
}
}
mShadowTarget = nullptr;
}
示例10: backingSize
void
gfxQuartzNativeDrawing::EndNativeDrawing()
{
NS_ASSERTION(mCGContext, "EndNativeDrawing called without BeginNativeDrawing");
if (mBorrowedContext.cg) {
MOZ_ASSERT(!mContext->IsCairo());
mBorrowedContext.Finish();
if (mDrawTarget) {
DrawTarget *dest = mContext->GetDrawTarget();
RefPtr<SourceSurface> source = mDrawTarget->Snapshot();
IntSize backingSize(NSToIntFloor(mNativeRect.width * mBackingScale),
NSToIntFloor(mNativeRect.height * mBackingScale));
Matrix oldTransform = dest->GetTransform();
Matrix newTransform = oldTransform;
newTransform.Translate(mNativeRect.x, mNativeRect.y);
newTransform.Scale(1.0f / mBackingScale, 1.0f / mBackingScale);
dest->SetTransform(newTransform);
dest->DrawSurface(source,
gfx::Rect(0, 0, backingSize.width, backingSize.height),
gfx::Rect(0, 0, backingSize.width, backingSize.height));
dest->SetTransform(oldTransform);
}
return;
}
cairo_quartz_finish_cg_context_with_clip(mSurfaceContext->GetCairo());
mQuartzSurface->MarkDirty();
if (mSurfaceContext != mContext) {
gfxContextMatrixAutoSaveRestore save(mContext);
// Copy back to destination
mContext->Translate(mNativeRect.TopLeft());
mContext->Scale(1.0f / mBackingScale, 1.0f / mBackingScale);
mContext->DrawSurface(mQuartzSurface, mQuartzSurface->GetSize());
}
}
示例11: affectedRect
//.........這裏部分代碼省略.........
cairo_surface_t* tempXlibSurface =
CreateTempXlibSurface(cairoTarget, drawTarget, size,
canDrawOverBackground, flags, screen, visual,
&method);
if (!tempXlibSurface)
return;
bool drawIsOpaque = (flags & DRAW_IS_OPAQUE) != 0;
if (!drawIsOpaque) {
cairo_t* tmpCtx = cairo_create(tempXlibSurface);
if (method == eCopyBackground) {
NS_ASSERTION(cairoTarget, "eCopyBackground only used when there's a cairoTarget");
cairo_set_operator(tmpCtx, CAIRO_OPERATOR_SOURCE);
gfxPoint pt = -(offset + deviceTranslation);
cairo_set_source_surface(tmpCtx, cairoTarget, pt.x, pt.y);
// The copy from the tempXlibSurface to the target context should
// use operator SOURCE, but that would need a mask to bound the
// operation. Here we only copy opaque backgrounds so operator
// OVER will behave like SOURCE masked by the surface.
NS_ASSERTION(cairo_surface_get_content(tempXlibSurface) == CAIRO_CONTENT_COLOR,
"Don't copy background with a transparent surface");
} else {
cairo_set_operator(tmpCtx, CAIRO_OPERATOR_CLEAR);
}
cairo_paint(tmpCtx);
cairo_destroy(tmpCtx);
}
if (!DrawOntoTempSurface(tempXlibSurface, -drawingRect.TopLeft())) {
cairo_surface_destroy(tempXlibSurface);
return;
}
SurfaceFormat moz2DFormat =
cairo_surface_get_content(tempXlibSurface) == CAIRO_CONTENT_COLOR ?
SurfaceFormat::B8G8R8A8 : SurfaceFormat::B8G8R8X8;
if (method != eAlphaExtraction) {
if (drawTarget) {
NativeSurface native;
native.mFormat = moz2DFormat;
native.mType = NativeSurfaceType::CAIRO_SURFACE;
native.mSurface = tempXlibSurface;
native.mSize = size;
RefPtr<SourceSurface> sourceSurface =
drawTarget->CreateSourceSurfaceFromNativeSurface(native);
if (sourceSurface) {
drawTarget->DrawSurface(sourceSurface,
Rect(offset.x, offset.y, size.width, size.height),
Rect(0, 0, size.width, size.height));
}
} else {
nsRefPtr<gfxASurface> tmpSurf = gfxASurface::Wrap(tempXlibSurface);
ctx->SetSource(tmpSurf, offset);
ctx->Paint();
}
cairo_surface_destroy(tempXlibSurface);
return;
}
nsRefPtr<gfxImageSurface> blackImage =
CopyXlibSurfaceToImage(tempXlibSurface, size, gfxImageFormat::ARGB32);
cairo_t* tmpCtx = cairo_create(tempXlibSurface);
cairo_set_source_rgba(tmpCtx, 1.0, 1.0, 1.0, 1.0);
cairo_set_operator(tmpCtx, CAIRO_OPERATOR_SOURCE);
cairo_paint(tmpCtx);
cairo_destroy(tmpCtx);
DrawOntoTempSurface(tempXlibSurface, -drawingRect.TopLeft());
nsRefPtr<gfxImageSurface> whiteImage =
CopyXlibSurfaceToImage(tempXlibSurface, size, gfxImageFormat::RGB24);
if (blackImage->CairoStatus() == CAIRO_STATUS_SUCCESS &&
whiteImage->CairoStatus() == CAIRO_STATUS_SUCCESS) {
if (!gfxAlphaRecovery::RecoverAlpha(blackImage, whiteImage)) {
cairo_surface_destroy(tempXlibSurface);
return;
}
gfxASurface* paintSurface = blackImage;
if (drawTarget) {
NativeSurface native;
native.mFormat = moz2DFormat;
native.mType = NativeSurfaceType::CAIRO_SURFACE;
native.mSurface = paintSurface->CairoSurface();
native.mSize = size;
RefPtr<SourceSurface> sourceSurface =
drawTarget->CreateSourceSurfaceFromNativeSurface(native);
if (sourceSurface) {
drawTarget->DrawSurface(sourceSurface,
Rect(offset.x, offset.y, size.width, size.height),
Rect(0, 0, size.width, size.height));
}
} else {
ctx->SetSource(paintSurface, offset);
ctx->Paint();
}
}
cairo_surface_destroy(tempXlibSurface);
}
示例12: srcOuter
/* static */ void
gfxAlphaBoxBlur::BlurRectangle(gfxContext* aDestinationCtx,
const gfxRect& aRect,
const RectCornerRadii* aCornerRadii,
const gfxPoint& aBlurStdDev,
const Color& aShadowColor,
const gfxRect& aDirtyRect,
const gfxRect& aSkipRect)
{
IntSize blurRadius = CalculateBlurRadius(aBlurStdDev);
bool mirrorCorners = !aCornerRadii || aCornerRadii->AreRadiiSame();
IntRect rect = RoundedToInt(ToRect(aRect));
IntMargin blurMargin;
IntMargin slice;
IntSize minSize;
RefPtr<SourceSurface> boxShadow = GetBlur(aDestinationCtx,
rect.Size(), blurRadius,
aCornerRadii, aShadowColor, mirrorCorners,
blurMargin, slice, minSize);
if (!boxShadow) {
return;
}
DrawTarget* destDrawTarget = aDestinationCtx->GetDrawTarget();
destDrawTarget->PushClipRect(ToRect(aDirtyRect));
// Copy the right parts from boxShadow into destDrawTarget. The middle parts
// will be stretched, border-image style.
Rect srcOuter(Point(blurMargin.left, blurMargin.top), Size(minSize));
Rect srcInner(srcOuter);
srcOuter.Inflate(Margin(blurMargin));
srcInner.Deflate(Margin(slice));
Rect dstOuter(rect);
Rect dstInner(rect);
dstOuter.Inflate(Margin(blurMargin));
dstInner.Deflate(Margin(slice));
Rect skipRect = ToRect(aSkipRect);
if (minSize == rect.Size()) {
// The target rect is smaller than the minimal size so just draw the surface
if (mirrorCorners) {
DrawMirroredBoxShadow(destDrawTarget, boxShadow, dstOuter);
} else {
destDrawTarget->DrawSurface(boxShadow, dstOuter, srcOuter);
}
} else {
if (mirrorCorners) {
DrawMirroredMinBoxShadow(destDrawTarget, boxShadow, dstOuter, dstInner,
srcOuter, srcInner, skipRect, true);
} else {
DrawMinBoxShadow(destDrawTarget, boxShadow, dstOuter, dstInner,
srcOuter, srcInner, skipRect, true);
}
}
// A note about anti-aliasing and seems between adjacent parts:
// We don't explicitly disable anti-aliasing in the DrawSurface calls above,
// so if there's a transform on destDrawTarget that is not pixel-aligned,
// there will be seams between adjacent parts of the box-shadow. It's hard to
// avoid those without the use of an intermediate surface.
// You might think that we could avoid those by just turning of AA, but there
// is a problem with that: Box-shadow rendering needs to clip out the
// element's border box, and we'd like that clip to have anti-aliasing -
// especially if the element has rounded corners! So we can't do that unless
// we have a way to say "Please anti-alias the clip, but don't antialias the
// destination rect of the DrawSurface call".
// On OS X there is an additional problem with turning off AA: CoreGraphics
// will not just fill the pixels that have their pixel center inside the
// filled shape. Instead, it will fill all the pixels which are partially
// covered by the shape. So for pixels on the edge between two adjacent parts,
// all those pixels will be painted to by both parts, which looks very bad.
destDrawTarget->PopClip();
}
示例13: srcBlur
void
gfxAlphaBoxBlur::BlurInsetBox(gfxContext* aDestinationCtx,
const Rect& aDestinationRect,
const Rect& aShadowClipRect,
const IntSize& aBlurRadius,
const Color& aShadowColor,
const RectCornerRadii* aInnerClipRadii,
const Rect& aSkipRect,
const Point& aShadowOffset)
{
if ((aBlurRadius.width == 0 && aBlurRadius.height == 0)
|| aShadowClipRect.IsEmpty()) {
FillDestinationPath(aDestinationCtx, aDestinationRect, aShadowClipRect,
aShadowColor, aInnerClipRadii);
return;
}
DrawTarget* destDrawTarget = aDestinationCtx->GetDrawTarget();
Margin innerMargin;
Margin blurMargin;
GetBlurMargins(aInnerClipRadii, aBlurRadius, blurMargin, innerMargin);
Rect whitespaceRect;
Rect outerRect;
bool useDestRect =
GetInsetBoxShadowRects(blurMargin, innerMargin, aShadowClipRect,
aDestinationRect, whitespaceRect, outerRect);
// Check that the inset margin between the outer and whitespace rects is symmetric,
// and that all corner radii are the same, in which case the blur can be mirrored.
Margin checkMargin = outerRect - whitespaceRect;
bool mirrorCorners =
checkMargin.left == checkMargin.right &&
checkMargin.top == checkMargin.bottom &&
(!aInnerClipRadii || aInnerClipRadii->AreRadiiSame());
RefPtr<SourceSurface> minBlur =
GetInsetBlur(outerRect, whitespaceRect, useDestRect, aShadowColor,
aBlurRadius, aInnerClipRadii, destDrawTarget, mirrorCorners);
if (!minBlur) {
return;
}
if (useDestRect) {
Rect destBlur = aDestinationRect;
destBlur.Inflate(blurMargin);
if (mirrorCorners) {
DrawMirroredBoxShadow(destDrawTarget, minBlur.get(), destBlur);
} else {
Rect srcBlur(Point(0, 0), Size(minBlur->GetSize()));
MOZ_ASSERT(srcBlur.Size() == destBlur.Size());
destDrawTarget->DrawSurface(minBlur, destBlur, srcBlur);
}
} else {
Rect srcOuter(outerRect);
Rect srcInner(srcOuter);
srcInner.Deflate(blurMargin); // The outer color fill
srcInner.Deflate(innerMargin); // The inner whitespace
// The shadow clip rect already takes into account the spread radius
Rect outerFillRect(aShadowClipRect);
outerFillRect.Inflate(blurMargin);
FillDestinationPath(aDestinationCtx, aDestinationRect, outerFillRect, aShadowColor);
// Inflate once for the frame around the whitespace
Rect destRect(aShadowClipRect);
destRect.Inflate(blurMargin);
// Deflate for the blurred in white space
Rect destInnerRect(aShadowClipRect);
destInnerRect.Deflate(innerMargin);
if (mirrorCorners) {
DrawMirroredMinBoxShadow(destDrawTarget, minBlur,
destRect, destInnerRect,
srcOuter, srcInner,
aSkipRect);
} else {
DrawMinBoxShadow(destDrawTarget, minBlur,
destRect, destInnerRect,
srcOuter, srcInner,
aSkipRect);
}
}
}