Bug 1556505. Handle offset surfaces in the other backends. r=rhunt

This brings DrawTargetCairo and DrawTargetD2D1 inline with DrawTargetSkia's
ability to handle SourceSurfaceOffset properly.

Differential Revision: https://phabricator.services.mozilla.com/D33536

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Jeff Muizelaar 2019-06-03 19:08:58 +00:00
parent 7e29cc5e05
commit fee767003f
2 changed files with 12 additions and 6 deletions

View File

@ -1417,7 +1417,7 @@ void DrawTargetCairo::MaskSurface(const Pattern& aSource, SourceSurface* aMask,
cairo_pattern_t* mask = cairo_pattern_create_for_surface(surf);
cairo_matrix_t matrix;
cairo_matrix_init_translate(&matrix, -aOffset.x, -aOffset.y);
cairo_matrix_init_translate(&matrix, -aOffset.x - aMask->GetRect().x, -aOffset.y - aMask->GetRect().y);
cairo_pattern_set_matrix(mask, &matrix);
cairo_set_operator(mContext, GfxOpToCairoOp(aOptions.mCompositionOp));
@ -1507,8 +1507,10 @@ void DrawTargetCairo::PushLayer(bool aOpaque, Float aOpacity,
cairo_surface_t* surf = GetCairoSurfaceForSourceSurface(aMask);
if (surf) {
layer.mMaskPattern = cairo_pattern_create_for_surface(surf);
Matrix maskTransform = aMaskTransform;
maskTransform.PreTranslate(aMask->GetRect().X(), aMask->GetRect().Y());
cairo_matrix_t mat;
GfxMatrixToCairoMatrix(aMaskTransform, mat);
GfxMatrixToCairoMatrix(maskTransform, mat);
cairo_matrix_invert(&mat);
cairo_pattern_set_matrix(layer.mMaskPattern, &mat);
cairo_surface_destroy(surf);

View File

@ -430,7 +430,8 @@ void DrawTargetD2D1::MaskSurface(const Pattern& aSource, SourceSurface* aMask,
IntSize size =
IntSize::Truncate(aMask->GetSize().width, aMask->GetSize().height);
Rect dest = Rect(aOffset.x, aOffset.y, Float(size.width), Float(size.height));
Rect dest = Rect(aOffset.x + aMask->GetRect().x, aOffset.y + aMask->GetRect().y,
Float(size.width), Float(size.height));
HRESULT hr = image->QueryInterface((ID2D1Bitmap**)getter_AddRefs(bitmap));
if (!bitmap || FAILED(hr)) {
@ -444,13 +445,15 @@ void DrawTargetD2D1::MaskSurface(const Pattern& aSource, SourceSurface* aMask,
hr = mDC->CreateImageBrush(
image,
D2D1::ImageBrushProperties(D2D1::RectF(0, 0, size.width, size.height)),
D2D1::BrushProperties(1.0f, D2D1::IdentityMatrix()),
D2D1::BrushProperties(
1.0f, D2D1::Matrix3x2F::Translation(aMask->GetRect().x,
aMask->GetRect().y)),
getter_AddRefs(maskBrush));
MOZ_ASSERT(SUCCEEDED(hr));
mDC->PushLayer(D2D1::LayerParameters1(D2D1::InfiniteRect(), nullptr,
D2D1_ANTIALIAS_MODE_PER_PRIMITIVE,
D2D1::IdentityMatrix(), 1.0f,
D2D1::Matrix3x2F::Translation(aMask->GetRect().x, aMask->GetRect().y), 1.0f,
maskBrush, D2D1_LAYER_OPTIONS1_NONE),
nullptr);
@ -472,7 +475,7 @@ void DrawTargetD2D1::MaskSurface(const Pattern& aSource, SourceSurface* aMask,
// FillOpacityMask only works if the antialias mode is MODE_ALIASED
mDC->SetAntialiasMode(D2D1_ANTIALIAS_MODE_ALIASED);
Rect maskRect = Rect(0.f, 0.f, Float(size.width), Float(size.height));
Rect maskRect = Rect(aMask->GetRect().x, aMask->GetRect().y, Float(size.width), Float(size.height));
RefPtr<ID2D1Brush> brush = CreateBrushForPattern(aSource, aOptions.mAlpha);
mDC->FillOpacityMask(bitmap, brush, D2D1_OPACITY_MASK_CONTENT_GRAPHICS,
D2DRect(dest), D2DRect(maskRect));
@ -973,6 +976,7 @@ void DrawTargetD2D1::PushLayer(bool aOpaque, Float aOpacity,
mDC->SetTransform(D2D1::IdentityMatrix());
mTransformDirty = true;
maskTransform = maskTransform.PreTranslate(aMask->GetRect().X(), aMask->GetRect().Y());
// The mask is given in user space. Our layer will apply it in device space.
maskTransform = maskTransform * mTransform;