mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-03 12:35:58 +00:00
Bug 1028288 Add canvas global transparency support to svgs. r=seth
This commit is contained in:
parent
f41f3ebd5b
commit
74a487913a
@ -9,6 +9,7 @@
|
||||
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsMathUtils.h"
|
||||
#include "SVGImageContext.h"
|
||||
|
||||
#include "nsContentUtils.h"
|
||||
|
||||
@ -3484,11 +3485,13 @@ CanvasRenderingContext2D::DrawDirectlyToCanvas(
|
||||
// FLAG_CLAMP is added for increased performance, since we never tile here.
|
||||
uint32_t modifiedFlags = image.mDrawingFlags | imgIContainer::FLAG_CLAMP;
|
||||
|
||||
SVGImageContext svgContext(scaledImageSize, Nothing(), CurrentState().globalAlpha);
|
||||
|
||||
nsresult rv = image.mImgContainer->
|
||||
Draw(context, scaledImageSize,
|
||||
ImageRegion::Create(gfxRect(src.x, src.y, src.width, src.height)),
|
||||
image.mWhichFrame, GraphicsFilter::FILTER_GOOD,
|
||||
Nothing(), modifiedFlags);
|
||||
Some(svgContext), modifiedFlags);
|
||||
|
||||
NS_ENSURE_SUCCESS_VOID(rv);
|
||||
}
|
||||
|
@ -31,6 +31,7 @@ gfxSurfaceDrawable::Draw(gfxContext* aContext,
|
||||
const gfxRect& aFillRect,
|
||||
bool aRepeat,
|
||||
const GraphicsFilter& aFilter,
|
||||
gfxFloat aOpacity,
|
||||
const gfxMatrix& aTransform)
|
||||
{
|
||||
ExtendMode extend = ExtendMode::CLAMP;
|
||||
@ -50,7 +51,8 @@ gfxSurfaceDrawable::Draw(gfxContext* aContext,
|
||||
|
||||
if (aContext->CurrentOperator() == gfxContext::OPERATOR_CLEAR) {
|
||||
dt->ClearRect(fillRect);
|
||||
} else if (aContext->CurrentOperator() == gfxContext::OPERATOR_SOURCE) {
|
||||
} else if (aContext->CurrentOperator() == gfxContext::OPERATOR_SOURCE &&
|
||||
aOpacity == 1.0) {
|
||||
// Emulate cairo operator source which is bound by mask!
|
||||
dt->ClearRect(fillRect);
|
||||
dt->FillRect(fillRect, pattern);
|
||||
@ -60,7 +62,7 @@ gfxSurfaceDrawable::Draw(gfxContext* aContext,
|
||||
aContext->CurrentAntialiasMode() == gfxContext::MODE_ALIASED ?
|
||||
AntialiasMode::NONE :
|
||||
AntialiasMode::SUBPIXEL;
|
||||
dt->FillRect(fillRect, pattern, DrawOptions(1.0f, op, aaMode));
|
||||
dt->FillRect(fillRect, pattern, DrawOptions(aOpacity, op, aaMode));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -96,15 +98,16 @@ gfxCallbackDrawable::Draw(gfxContext* aContext,
|
||||
const gfxRect& aFillRect,
|
||||
bool aRepeat,
|
||||
const GraphicsFilter& aFilter,
|
||||
gfxFloat aOpacity,
|
||||
const gfxMatrix& aTransform)
|
||||
{
|
||||
if (aRepeat && !mSurfaceDrawable) {
|
||||
if ((aRepeat || aOpacity != 1.0) && !mSurfaceDrawable) {
|
||||
mSurfaceDrawable = MakeSurfaceDrawable(aFilter);
|
||||
}
|
||||
|
||||
if (mSurfaceDrawable)
|
||||
return mSurfaceDrawable->Draw(aContext, aFillRect, aRepeat, aFilter,
|
||||
aTransform);
|
||||
aOpacity, aTransform);
|
||||
|
||||
if (mCallback)
|
||||
return (*mCallback)(aContext, aFillRect, aFilter, aTransform);
|
||||
@ -137,7 +140,7 @@ public:
|
||||
const GraphicsFilter& aFilter,
|
||||
const gfxMatrix& aTransform = gfxMatrix())
|
||||
{
|
||||
return mDrawable->Draw(aContext, aFillRect, false, aFilter,
|
||||
return mDrawable->Draw(aContext, aFillRect, false, aFilter, 1.0,
|
||||
aTransform);
|
||||
}
|
||||
private:
|
||||
@ -159,6 +162,7 @@ gfxPatternDrawable::Draw(gfxContext* aContext,
|
||||
const gfxRect& aFillRect,
|
||||
bool aRepeat,
|
||||
const GraphicsFilter& aFilter,
|
||||
gfxFloat aOpacity,
|
||||
const gfxMatrix& aTransform)
|
||||
{
|
||||
if (!mPattern)
|
||||
@ -174,7 +178,7 @@ gfxPatternDrawable::Draw(gfxContext* aContext,
|
||||
// will happen through this Draw() method with aRepeat = false.
|
||||
nsRefPtr<gfxCallbackDrawable> callbackDrawable = MakeCallbackDrawable();
|
||||
return callbackDrawable->Draw(aContext, aFillRect, true, aFilter,
|
||||
aTransform);
|
||||
aOpacity, aTransform);
|
||||
}
|
||||
|
||||
aContext->NewPath();
|
||||
@ -182,7 +186,7 @@ gfxPatternDrawable::Draw(gfxContext* aContext,
|
||||
mPattern->SetMatrix(aTransform * oldMatrix);
|
||||
aContext->SetPattern(mPattern);
|
||||
aContext->Rectangle(aFillRect);
|
||||
aContext->Fill();
|
||||
aContext->FillWithOpacity(aOpacity);
|
||||
mPattern->SetMatrix(oldMatrix);
|
||||
return true;
|
||||
}
|
||||
|
@ -38,6 +38,7 @@ public:
|
||||
const gfxRect& aFillRect,
|
||||
bool aRepeat,
|
||||
const GraphicsFilter& aFilter,
|
||||
gfxFloat aOpacity = 1.0,
|
||||
const gfxMatrix& aTransform = gfxMatrix()) = 0;
|
||||
virtual gfxIntSize Size() { return mSize; }
|
||||
|
||||
@ -62,6 +63,7 @@ public:
|
||||
const gfxRect& aFillRect,
|
||||
bool aRepeat,
|
||||
const GraphicsFilter& aFilter,
|
||||
gfxFloat aOpacity = 1.0,
|
||||
const gfxMatrix& aTransform = gfxMatrix());
|
||||
|
||||
protected:
|
||||
@ -107,6 +109,7 @@ public:
|
||||
const gfxRect& aFillRect,
|
||||
bool aRepeat,
|
||||
const GraphicsFilter& aFilter,
|
||||
gfxFloat aOpacity = 1.0,
|
||||
const gfxMatrix& aTransform = gfxMatrix());
|
||||
|
||||
protected:
|
||||
@ -130,6 +133,7 @@ public:
|
||||
const gfxRect& aFillRect,
|
||||
bool aRepeat,
|
||||
const GraphicsFilter& aFilter,
|
||||
gfxFloat aOpacity = 1.0,
|
||||
const gfxMatrix& aTransform = gfxMatrix());
|
||||
|
||||
protected:
|
||||
|
@ -407,7 +407,7 @@ CreateSamplingRestrictedDrawable(gfxDrawable* aDrawable,
|
||||
nsRefPtr<gfxContext> tmpCtx = new gfxContext(target);
|
||||
tmpCtx->SetOperator(OptimalFillOperator());
|
||||
aDrawable->Draw(tmpCtx, needed - needed.TopLeft(), true,
|
||||
GraphicsFilter::FILTER_FAST, gfxMatrix().Translate(needed.TopLeft()));
|
||||
GraphicsFilter::FILTER_FAST, 1.0, gfxMatrix().Translate(needed.TopLeft()));
|
||||
RefPtr<SourceSurface> surface = target->Snapshot();
|
||||
|
||||
nsRefPtr<gfxDrawable> drawable = new gfxSurfaceDrawable(surface, size, gfxMatrix().Translate(-needed.TopLeft()));
|
||||
@ -567,7 +567,8 @@ gfxUtils::DrawPixelSnapped(gfxContext* aContext,
|
||||
const ImageRegion& aRegion,
|
||||
const SurfaceFormat aFormat,
|
||||
GraphicsFilter aFilter,
|
||||
uint32_t aImageFlags)
|
||||
uint32_t aImageFlags,
|
||||
gfxFloat aOpacity)
|
||||
{
|
||||
PROFILER_LABEL("gfxUtils", "DrawPixelSnapped",
|
||||
js::ProfileEntry::Category::GRAPHICS);
|
||||
@ -617,7 +618,7 @@ gfxUtils::DrawPixelSnapped(gfxContext* aContext,
|
||||
}
|
||||
#endif
|
||||
|
||||
drawable->Draw(aContext, aRegion.Rect(), doTile, aFilter);
|
||||
drawable->Draw(aContext, aRegion.Rect(), doTile, aFilter, aOpacity);
|
||||
}
|
||||
|
||||
/* static */ int
|
||||
|
@ -81,7 +81,8 @@ public:
|
||||
const ImageRegion& aRegion,
|
||||
const mozilla::gfx::SurfaceFormat aFormat,
|
||||
GraphicsFilter aFilter,
|
||||
uint32_t aImageFlags = imgIContainer::FLAG_NONE);
|
||||
uint32_t aImageFlags = imgIContainer::FLAG_NONE,
|
||||
gfxFloat aOpacity = 1.0);
|
||||
|
||||
/**
|
||||
* Clip aContext to the region aRegion.
|
||||
|
@ -779,6 +779,7 @@ struct SVGDrawingParameters
|
||||
, viewportSize(aSVGContext ? aSVGContext->GetViewportSize() : aSize)
|
||||
, animationTime(aAnimationTime)
|
||||
, flags(aFlags)
|
||||
, opacity(aSVGContext ? aSVGContext->GetGlobalOpacity() : 1.0)
|
||||
{ }
|
||||
|
||||
gfxContext* context;
|
||||
@ -790,6 +791,7 @@ struct SVGDrawingParameters
|
||||
nsIntSize viewportSize;
|
||||
float animationTime;
|
||||
uint32_t flags;
|
||||
gfxFloat opacity;
|
||||
};
|
||||
|
||||
//******************************************************************************
|
||||
@ -929,7 +931,7 @@ VectorImage::Show(gfxDrawable* aDrawable, const SVGDrawingParameters& aParams)
|
||||
ThebesIntSize(aParams.size),
|
||||
aParams.region,
|
||||
SurfaceFormat::B8G8R8A8,
|
||||
aParams.filter, aParams.flags);
|
||||
aParams.filter, aParams.flags, aParams.opacity);
|
||||
|
||||
MOZ_ASSERT(mRenderingObserver, "Should have a rendering observer by now");
|
||||
mRenderingObserver->ResumeHonoringInvalidations();
|
||||
|
@ -19,12 +19,16 @@ namespace mozilla {
|
||||
class SVGImageContext
|
||||
{
|
||||
public:
|
||||
SVGImageContext() { }
|
||||
SVGImageContext()
|
||||
: mGlobalOpacity(1.0)
|
||||
{ }
|
||||
|
||||
SVGImageContext(nsIntSize aViewportSize,
|
||||
Maybe<SVGPreserveAspectRatio> aPreserveAspectRatio)
|
||||
Maybe<SVGPreserveAspectRatio> aPreserveAspectRatio,
|
||||
gfxFloat aOpacity = 1.0)
|
||||
: mViewportSize(aViewportSize)
|
||||
, mPreserveAspectRatio(aPreserveAspectRatio)
|
||||
, mGlobalOpacity(aOpacity)
|
||||
{ }
|
||||
|
||||
const nsIntSize& GetViewportSize() const {
|
||||
@ -35,9 +39,14 @@ public:
|
||||
return mPreserveAspectRatio;
|
||||
}
|
||||
|
||||
gfxFloat GetGlobalOpacity() const {
|
||||
return mGlobalOpacity;
|
||||
}
|
||||
|
||||
bool operator==(const SVGImageContext& aOther) const {
|
||||
return mViewportSize == aOther.mViewportSize &&
|
||||
mPreserveAspectRatio == aOther.mPreserveAspectRatio;
|
||||
mPreserveAspectRatio == aOther.mPreserveAspectRatio &&
|
||||
mGlobalOpacity == aOther.mGlobalOpacity;
|
||||
}
|
||||
|
||||
bool operator!=(const SVGImageContext& aOther) const {
|
||||
@ -47,7 +56,8 @@ public:
|
||||
uint32_t Hash() const {
|
||||
return HashGeneric(mViewportSize.width,
|
||||
mViewportSize.height,
|
||||
mPreserveAspectRatio.map(HashPAR).valueOr(0));
|
||||
mPreserveAspectRatio.map(HashPAR).valueOr(0),
|
||||
HashBytes(&mGlobalOpacity, sizeof(gfxFloat)));
|
||||
}
|
||||
|
||||
private:
|
||||
@ -57,6 +67,7 @@ private:
|
||||
|
||||
nsIntSize mViewportSize;
|
||||
Maybe<SVGPreserveAspectRatio> mPreserveAspectRatio;
|
||||
gfxFloat mGlobalOpacity;
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
Loading…
x
Reference in New Issue
Block a user