зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1758968 - Clip drawing in DrawTargetD2D1::DrawSurfaceWithShadow. r=gfx-reviewers,nical
DrawSurfaceWithShadow is supposed to ignore transforms but still support clipping. It appears that DrawTargetD2D1 for some reason never actually implemented clipping. The DrawImage calls on the DC just need to happen within the bounds of PrepareForDrawing and FinalizeDrawing. Since PrepareForDrawing handles the overriding of the blend mode via SetPrimitiveBlend, we need to use DrawImage with D2D1_COMPOSITE_MODE_SOURCE_OVER so that it will blend appropriately. Differential Revision: https://phabricator.services.mozilla.com/D140798
This commit is contained in:
Родитель
cd456428c5
Коммит
a1ba0b4ade
|
@ -0,0 +1,13 @@
|
|||
<div style="width: 100px; height: 100px;"><canvas id="canvas" width="100" height="50"></canvas></div>
|
||||
<script>
|
||||
var can = document.getElementById('canvas');
|
||||
var ctx = can.getContext('2d');
|
||||
|
||||
ctx.shadowOffsetX = 24;
|
||||
ctx.shadowOffsetY = 24;
|
||||
ctx.shadowColor = 'blue';
|
||||
ctx.shadowBlur = 20;
|
||||
|
||||
ctx.fillStyle = 'black';
|
||||
ctx.fillRect(0,0,40,40);
|
||||
</script>
|
|
@ -0,0 +1,16 @@
|
|||
<canvas id="canvas" width="100" height="100"></canvas>
|
||||
<script>
|
||||
var can = document.getElementById('canvas');
|
||||
var ctx = can.getContext('2d');
|
||||
|
||||
ctx.shadowOffsetX = 24;
|
||||
ctx.shadowOffsetY = 24;
|
||||
ctx.shadowColor = 'blue';
|
||||
ctx.shadowBlur = 20;
|
||||
|
||||
ctx.rect(0,0,100,50);
|
||||
ctx.clip();
|
||||
|
||||
ctx.fillStyle = 'black';
|
||||
ctx.fillRect(0,0,40,40);
|
||||
</script>
|
|
@ -250,3 +250,5 @@ skip-if(Android) == visible-occluded.html visible-occluded-ref.html
|
|||
== 1719886-1.html 1719886-1-ref.html
|
||||
|
||||
skip-if(isDebugBuild) == draw-large-image.html draw-large-image-ref.html
|
||||
|
||||
== 1758968-1.html 1758968-1-ref.html
|
||||
|
|
|
@ -312,8 +312,6 @@ void DrawTargetD2D1::DrawSurfaceWithShadow(SourceSurface* aSurface,
|
|||
return;
|
||||
}
|
||||
MarkChanged();
|
||||
mDC->SetTransform(D2D1::IdentityMatrix());
|
||||
mTransformDirty = true;
|
||||
|
||||
Matrix mat;
|
||||
RefPtr<ID2D1Image> image =
|
||||
|
@ -331,35 +329,44 @@ void DrawTargetD2D1::DrawSurfaceWithShadow(SourceSurface* aSurface,
|
|||
return;
|
||||
}
|
||||
|
||||
// Step 1, create the shadow effect.
|
||||
if (!PrepareForDrawing(aOperator, ColorPattern(aColor))) {
|
||||
return;
|
||||
}
|
||||
|
||||
mDC->SetTransform(D2D1::IdentityMatrix());
|
||||
mTransformDirty = true;
|
||||
|
||||
RefPtr<ID2D1Effect> shadowEffect;
|
||||
HRESULT hr = mDC->CreateEffect(
|
||||
mFormat == SurfaceFormat::A8 ? CLSID_D2D1GaussianBlur : CLSID_D2D1Shadow,
|
||||
getter_AddRefs(shadowEffect));
|
||||
if (FAILED(hr) || !shadowEffect) {
|
||||
gfxWarning() << "Failed to create shadow effect. Code: " << hexa(hr);
|
||||
return;
|
||||
}
|
||||
shadowEffect->SetInput(0, image);
|
||||
if (mFormat == SurfaceFormat::A8) {
|
||||
shadowEffect->SetValue(D2D1_GAUSSIANBLUR_PROP_STANDARD_DEVIATION, aSigma);
|
||||
shadowEffect->SetValue(D2D1_GAUSSIANBLUR_PROP_BORDER_MODE,
|
||||
D2D1_BORDER_MODE_HARD);
|
||||
} else {
|
||||
shadowEffect->SetValue(D2D1_SHADOW_PROP_BLUR_STANDARD_DEVIATION, aSigma);
|
||||
D2D1_VECTOR_4F color = {aColor.r, aColor.g, aColor.b, aColor.a};
|
||||
shadowEffect->SetValue(D2D1_SHADOW_PROP_COLOR, color);
|
||||
}
|
||||
if (SUCCEEDED(hr) && shadowEffect) {
|
||||
shadowEffect->SetInput(0, image);
|
||||
if (mFormat == SurfaceFormat::A8) {
|
||||
shadowEffect->SetValue(D2D1_GAUSSIANBLUR_PROP_STANDARD_DEVIATION, aSigma);
|
||||
shadowEffect->SetValue(D2D1_GAUSSIANBLUR_PROP_BORDER_MODE,
|
||||
D2D1_BORDER_MODE_HARD);
|
||||
} else {
|
||||
shadowEffect->SetValue(D2D1_SHADOW_PROP_BLUR_STANDARD_DEVIATION, aSigma);
|
||||
D2D1_VECTOR_4F color = {aColor.r, aColor.g, aColor.b, aColor.a};
|
||||
shadowEffect->SetValue(D2D1_SHADOW_PROP_COLOR, color);
|
||||
}
|
||||
|
||||
D2D1_POINT_2F shadowPoint = D2DPoint(aDest + aOffset);
|
||||
mDC->DrawImage(shadowEffect, &shadowPoint, nullptr,
|
||||
D2D1_INTERPOLATION_MODE_LINEAR, D2DCompositionMode(aOperator));
|
||||
D2D1_POINT_2F shadowPoint = D2DPoint(aDest + aOffset);
|
||||
mDC->DrawImage(shadowEffect, &shadowPoint, nullptr,
|
||||
D2D1_INTERPOLATION_MODE_LINEAR,
|
||||
D2D1_COMPOSITE_MODE_SOURCE_OVER);
|
||||
} else {
|
||||
gfxWarning() << "Failed to create shadow effect. Code: " << hexa(hr);
|
||||
}
|
||||
|
||||
if (aSurface->GetFormat() != SurfaceFormat::A8) {
|
||||
D2D1_POINT_2F imgPoint = D2DPoint(aDest);
|
||||
mDC->DrawImage(image, &imgPoint, nullptr, D2D1_INTERPOLATION_MODE_LINEAR,
|
||||
D2DCompositionMode(aOperator));
|
||||
D2D1_COMPOSITE_MODE_SOURCE_OVER);
|
||||
}
|
||||
|
||||
FinalizeDrawing(aOperator, ColorPattern(aColor));
|
||||
}
|
||||
|
||||
void DrawTargetD2D1::ClearRect(const Rect& aRect) {
|
||||
|
|
Загрузка…
Ссылка в новой задаче