Bug 1316719 - Apply scale to the mask layer's contents. r=mattwoodrow

MozReview-Commit-ID: 7nd3oL8bFLw

--HG--
extra : rebase_source : 936d43c69ffd530d6995839328b30f2052e25a1e
extra : histedit_source : 51e86c503451e03a9215e58a16a42e5656321ca1
This commit is contained in:
Markus Stange 2016-11-11 13:18:28 -05:00
Родитель b5d327f9be
Коммит 28cb955754
6 изменённых файлов: 141 добавлений и 18 удалений

Просмотреть файл

@ -1570,13 +1570,13 @@ struct CSSMaskLayerUserData : public LayerUserData
: mImageLayers(nsStyleImageLayers::LayerType::Mask)
{ }
CSSMaskLayerUserData(nsIFrame* aFrame, const nsRect& aBound)
CSSMaskLayerUserData(nsIFrame* aFrame, const nsIntRect& aBounds)
: mImageLayers(aFrame->StyleSVGReset()->mMask),
mContentRect(aFrame->GetContentRectRelativeToSelf()),
mPaddingRect(aFrame->GetPaddingRectRelativeToSelf()),
mBorderRect(aFrame->GetRectRelativeToSelf()),
mMarginRect(aFrame->GetMarginRectRelativeToSelf()),
mBounds(aBound)
mBounds(aBounds)
{
Hash(aFrame);
}
@ -1650,7 +1650,7 @@ private:
nsRect mBorderRect;
nsRect mMarginRect;
nsRect mBounds;
nsIntRect mBounds;
uint32_t mHash;
};
@ -3914,26 +3914,22 @@ ContainerState::SetupMaskLayerForCSSMask(Layer* aLayer,
bool snap;
nsRect bounds = aMaskItem->GetBounds(mBuilder, &snap);
CSSMaskLayerUserData newUserData(aMaskItem->Frame(), bounds);
nsIntRect itemRect = ScaleToOutsidePixels(bounds, snap);
CSSMaskLayerUserData newUserData(aMaskItem->Frame(), itemRect);
if (*oldUserData == newUserData) {
aLayer->SetMaskLayer(maskLayer);
return;
}
const nsIFrame* frame = aMaskItem->Frame();
int32_t A2D = frame->PresContext()->AppUnitsPerDevPixel();
Rect devBounds = NSRectToRect(bounds, A2D);
uint32_t maxSize = mManager->GetMaxTextureSize();
gfx::Size surfaceSize(std::min<gfx::Float>(devBounds.Width(), maxSize),
std::min<gfx::Float>(devBounds.Height(), maxSize));
IntSize surfaceSizeInt(NSToIntCeil(surfaceSize.width),
NSToIntCeil(surfaceSize.height));
int32_t maxSize = mManager->GetMaxTextureSize();
IntSize surfaceSize(std::min(itemRect.width, maxSize),
std::min(itemRect.height, maxSize));
if (surfaceSizeInt.IsEmpty()) {
if (surfaceSize.IsEmpty()) {
return;
}
MaskImageData imageData(surfaceSizeInt, mManager);
MaskImageData imageData(surfaceSize, mManager);
RefPtr<DrawTarget> dt = imageData.CreateDrawTarget();
if (!dt || !dt->IsValid()) {
NS_WARNING("Could not create DrawTarget for mask layer.");
@ -3941,8 +3937,8 @@ ContainerState::SetupMaskLayerForCSSMask(Layer* aLayer,
}
RefPtr<gfxContext> maskCtx = gfxContext::CreateOrNull(dt);
gfxPoint offset = nsLayoutUtils::PointToGfxPoint(bounds.TopLeft(), A2D);
maskCtx->SetMatrix(gfxMatrix::Translation(-offset));
maskCtx->SetMatrix(gfxMatrix::Translation(-itemRect.TopLeft()));
maskCtx->Multiply(gfxMatrix::Scaling(mParameters.mXScale, mParameters.mYScale));
if (!aMaskItem->PaintMask(mBuilder, maskCtx)) {
// Mostly because of mask resource is not ready.
@ -3951,9 +3947,8 @@ ContainerState::SetupMaskLayerForCSSMask(Layer* aLayer,
// Setup mask layer offset.
Matrix4x4 matrix;
matrix.PreTranslate(offset.x, offset.y, 0);
matrix.PreTranslate(itemRect.x, itemRect.y, 0);
matrix.PreTranslate(mParameters.mOffset.x, mParameters.mOffset.y, 0);
matrix.PreScale(mParameters.mXScale, mParameters.mYScale, 1.0);
maskLayer->SetBaseTransform(matrix);

Просмотреть файл

@ -0,0 +1,19 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>reference: 0.8 opacity green circle</title>
<style>
body {
margin: 0;
}
div {
margin: 100px 200px;
width: 200px;
height: 200px;
background-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 200 200"><circle cx="100" cy="100" r="100" fill="green" fill-opacity="0.8"/></svg>');
}
</style>
<div></div>

Просмотреть файл

@ -0,0 +1,42 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>mask-image with scale transform</title>
<style>
body {
margin: 0;
}
#transform {
width: 10px;
height: 10px;
transform: scale(20);
transform-origin: top left;
padding: 5px 10px;
}
#opacity {
opacity: 0.8;
}
#mask {
width: 10px;
height: 10px;
background: green;
mask-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 10 10"><circle cx="5" cy="5" r="5" fill="black"/></svg>');
}
#activator {
border: 1px solid transparent;
will-change: transform;
}
</style>
<div id="transform">
<div id="opacity">
<div id="mask">
<div id="activator"></div>
</div>
</div>
</div>

Просмотреть файл

@ -0,0 +1,35 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>mask-image with scale transform</title>
<style>
body {
margin: 0;
}
#transform {
width: 10px;
height: 10px;
transform: scale(20);
transform-origin: top left;
padding: 5px 10px;
}
#opacity {
opacity: 0.8;
}
#mask {
width: 10px;
height: 10px;
background: green;
mask-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 10 10"><circle cx="5" cy="5" r="5" fill="black"/></svg>');
}
</style>
<div id="transform">
<div id="opacity">
<div id="mask"></div>
</div>
</div>

Просмотреть файл

@ -0,0 +1,29 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>mask-image with scale transform</title>
<style>
body {
margin: 0;
}
#transform {
width: 10px;
height: 10px;
transform: scale(20);
transform-origin: top left;
padding: 5px 10px;
}
#mask {
width: 10px;
height: 10px;
background: green;
mask-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 10 10"><circle cx="5" cy="5" r="5" fill="black" fill-opacity="0.8"/></svg>');
}
</style>
<div id="transform">
<div id="mask"></div>
</div>

Просмотреть файл

@ -1974,6 +1974,9 @@ fuzzy(8,1900) == 1291528.html 1291528-ref.html
# background color.
fuzzy(255,1000) skip-if(!cocoaWidget) == 1294102-1.html 1294102-1-ref.html
== 1315632-1.html 1315632-1-ref.html
fuzzy(2,40000) == 1316719-1a.html 1316719-1-ref.html
fuzzy(2,40000) == 1316719-1b.html 1316719-1-ref.html
fuzzy(2,40000) == 1316719-1c.html 1316719-1-ref.html
HTTP == 652991-1a.html 652991-1-ref.html
HTTP == 652991-1b.html 652991-1-ref.html