Bug 455279. Fix mask alpha computation so that it works when the incoming gfxContext has a non-identity transform. r=longsonr,sr=mats

This commit is contained in:
Robert O'Callahan 2008-09-22 14:14:54 +12:00
Родитель d5cda1d9de
Коммит 5ad965518f
4 изменённых файлов: 30 добавлений и 13 удалений

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

@ -0,0 +1,8 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/licenses/publicdomain/
-->
<svg xmlns="http://www.w3.org/2000/svg" width="400" height="400">
<rect width="50%" height="50%" fill="lime"/>
</svg>

После

Ширина:  |  Высота:  |  Размер: 239 B

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

@ -0,0 +1,17 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/licenses/publicdomain/
-->
<svg xmlns="http://www.w3.org/2000/svg" width="400" height="400">
<defs>
<mask id="m1" maskUnits="objectBoundingBox" maskContentUnits="objectBoundingBox">
<rect x="0" y="0" width="1" height="1" fill="white"/>
</mask>
</defs>
<foreignObject width="100%" height="100%" transform="scale(0.5)">
<svg style="width:100%; height:100%;">
<rect width="100%" height="100%" fill="lime" mask="url(#m1)"/>
</svg>
</foreignObject>
</svg>

После

Ширина:  |  Высота:  |  Размер: 579 B

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

@ -52,6 +52,7 @@ fails == inline-in-xul-basic-01.xul pass.svg
== invalid-text-01.svg pass.svg == invalid-text-01.svg pass.svg
== linearGradient-basic-01.svg pass.svg == linearGradient-basic-01.svg pass.svg
== linearGradient-basic-02.svg pass.svg == linearGradient-basic-02.svg pass.svg
== mask-transformed-01.svg mask-transformed-01-ref.svg
== nested-viewBox-01.svg pass.svg == nested-viewBox-01.svg pass.svg
== objectBoundingBox-and-pattern-01a.svg objectBoundingBox-and-pattern-01-ref.svg == objectBoundingBox-and-pattern-01a.svg objectBoundingBox-and-pattern-01-ref.svg
== objectBoundingBox-and-pattern-01b.svg objectBoundingBox-and-pattern-01-ref.svg == objectBoundingBox-and-pattern-01b.svg objectBoundingBox-and-pattern-01-ref.svg

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

@ -106,20 +106,13 @@ nsSVGMaskFrame::ComputeMaskAlpha(nsSVGRenderState *aContext,
nsSVGUtils::PaintChildWithEffects(aContext, nsnull, kid); nsSVGUtils::PaintChildWithEffects(aContext, nsnull, kid);
} }
gfxRect clipExtents = gfx->GetClipExtents();
gfx->Restore(); gfx->Restore();
nsRefPtr<gfxPattern> pattern = gfx->PopGroup(); nsRefPtr<gfxPattern> pattern = gfx->PopGroup();
if (!pattern || pattern->CairoStatus()) if (!pattern || pattern->CairoStatus())
return nsnull; return nsnull;
nsRefPtr<gfxASurface> surface = pattern->GetSurface();
if (!surface || surface->CairoStatus())
return nsnull;
surface->SetDeviceOffset(gfxPoint(0,0));
gfxRect clipExtents = gfx->GetClipExtents();
#ifdef DEBUG_tor #ifdef DEBUG_tor
fprintf(stderr, "clip extent: %f,%f %fx%f\n", fprintf(stderr, "clip extent: %f,%f %fx%f\n",
clipExtents.X(), clipExtents.Y(), clipExtents.X(), clipExtents.Y(),
@ -143,10 +136,11 @@ nsSVGMaskFrame::ComputeMaskAlpha(nsSVGRenderState *aContext,
new gfxImageSurface(surfaceSize, gfxASurface::ImageFormatARGB32); new gfxImageSurface(surfaceSize, gfxASurface::ImageFormatARGB32);
if (!image || image->CairoStatus()) if (!image || image->CairoStatus())
return nsnull; return nsnull;
image->SetDeviceOffset(-clipExtents.pos);
gfxContext transferCtx(image); gfxContext transferCtx(image);
transferCtx.SetOperator(gfxContext::OPERATOR_SOURCE); transferCtx.SetOperator(gfxContext::OPERATOR_SOURCE);
transferCtx.SetSource(surface); transferCtx.SetPattern(pattern);
transferCtx.Paint(); transferCtx.Paint();
PRUint8 *data = image->Data(); PRUint8 *data = image->Data();
@ -172,10 +166,7 @@ nsSVGMaskFrame::ComputeMaskAlpha(nsSVGRenderState *aContext,
} }
gfxPattern *retval = new gfxPattern(image); gfxPattern *retval = new gfxPattern(image);
if (retval) { NS_IF_ADDREF(retval);
retval->SetMatrix(gfxMatrix().Translate(-clipExtents.pos));
NS_ADDREF(retval);
}
return retval; return retval;
} }