зеркало из https://github.com/mozilla/pjs.git
b=430906; add moz-opaque attribute to <canvas>; r+sr=roc
This commit is contained in:
Родитель
355e9c0144
Коммит
0db050fa2f
|
@ -514,6 +514,7 @@ GK_ATOM(mouseout, "mouseout")
|
||||||
GK_ATOM(mouseover, "mouseover")
|
GK_ATOM(mouseover, "mouseover")
|
||||||
GK_ATOM(mousethrough, "mousethrough")
|
GK_ATOM(mousethrough, "mousethrough")
|
||||||
GK_ATOM(mouseup, "mouseup")
|
GK_ATOM(mouseup, "mouseup")
|
||||||
|
GK_ATOM(moz_opaque, "moz-opaque")
|
||||||
GK_ATOM(msthemecompatible, "msthemecompatible")
|
GK_ATOM(msthemecompatible, "msthemecompatible")
|
||||||
GK_ATOM(multicol, "multicol")
|
GK_ATOM(multicol, "multicol")
|
||||||
GK_ATOM(multiple, "multiple")
|
GK_ATOM(multiple, "multiple")
|
||||||
|
|
|
@ -77,6 +77,12 @@ public:
|
||||||
// If this canvas context can be represented with a simple Thebes surface,
|
// If this canvas context can be represented with a simple Thebes surface,
|
||||||
// return the surface. Otherwise returns an error.
|
// return the surface. Otherwise returns an error.
|
||||||
NS_IMETHOD GetThebesSurface(gfxASurface **surface) = 0;
|
NS_IMETHOD GetThebesSurface(gfxASurface **surface) = 0;
|
||||||
|
|
||||||
|
// If this context is opaque, the backing store of the canvas should
|
||||||
|
// be created as opaque; all compositing operators should assume the
|
||||||
|
// dst alpha is always 1.0. If this is never called, the context
|
||||||
|
// defaults to false (not opaque).
|
||||||
|
NS_IMETHOD SetIsOpaque(PRBool isOpaque) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
NS_DEFINE_STATIC_IID_ACCESSOR(nsICanvasRenderingContextInternal,
|
NS_DEFINE_STATIC_IID_ACCESSOR(nsICanvasRenderingContextInternal,
|
||||||
|
|
|
@ -296,6 +296,7 @@ public:
|
||||||
const PRUnichar* aEncoderOptions,
|
const PRUnichar* aEncoderOptions,
|
||||||
nsIInputStream **aStream);
|
nsIInputStream **aStream);
|
||||||
NS_IMETHOD GetThebesSurface(gfxASurface **surface);
|
NS_IMETHOD GetThebesSurface(gfxASurface **surface);
|
||||||
|
NS_IMETHOD SetIsOpaque(PRBool isOpaque);
|
||||||
|
|
||||||
// nsISupports interface
|
// nsISupports interface
|
||||||
NS_DECL_ISUPPORTS
|
NS_DECL_ISUPPORTS
|
||||||
|
@ -334,7 +335,8 @@ protected:
|
||||||
|
|
||||||
// Member vars
|
// Member vars
|
||||||
PRInt32 mWidth, mHeight;
|
PRInt32 mWidth, mHeight;
|
||||||
PRBool mValid;
|
PRPackedBool mValid;
|
||||||
|
PRPackedBool mOpaque;
|
||||||
|
|
||||||
// the canvas element informs us when it's going away,
|
// the canvas element informs us when it's going away,
|
||||||
// so these are not nsCOMPtrs
|
// so these are not nsCOMPtrs
|
||||||
|
@ -470,7 +472,7 @@ NS_NewCanvasRenderingContext2D(nsIDOMCanvasRenderingContext2D** aResult)
|
||||||
}
|
}
|
||||||
|
|
||||||
nsCanvasRenderingContext2D::nsCanvasRenderingContext2D()
|
nsCanvasRenderingContext2D::nsCanvasRenderingContext2D()
|
||||||
: mValid(PR_FALSE), mCanvasElement(nsnull),
|
: mValid(PR_FALSE), mOpaque(PR_FALSE), mCanvasElement(nsnull),
|
||||||
mSaveCount(0), mCairo(nsnull), mSurface(nsnull), mStyleStack(20)
|
mSaveCount(0), mCairo(nsnull), mSurface(nsnull), mStyleStack(20)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -685,7 +687,12 @@ nsCanvasRenderingContext2D::SetDimensions(PRInt32 width, PRInt32 height)
|
||||||
|
|
||||||
// Check that the dimensions are sane
|
// Check that the dimensions are sane
|
||||||
if (gfxASurface::CheckSurfaceSize(gfxIntSize(width, height), 0xffff)) {
|
if (gfxASurface::CheckSurfaceSize(gfxIntSize(width, height), 0xffff)) {
|
||||||
mThebesSurface = gfxPlatform::GetPlatform()->CreateOffscreenSurface(gfxIntSize(width, height), gfxASurface::ImageFormatARGB32);
|
gfxASurface::gfxImageFormat format = gfxASurface::ImageFormatARGB32;
|
||||||
|
if (mOpaque)
|
||||||
|
format = gfxASurface::ImageFormatRGB24;
|
||||||
|
|
||||||
|
mThebesSurface = gfxPlatform::GetPlatform()->CreateOffscreenSurface
|
||||||
|
(gfxIntSize(width, height), format);
|
||||||
|
|
||||||
if (mThebesSurface->CairoStatus() == 0) {
|
if (mThebesSurface->CairoStatus() == 0) {
|
||||||
mThebesContext = new gfxContext(mThebesSurface);
|
mThebesContext = new gfxContext(mThebesSurface);
|
||||||
|
@ -733,6 +740,24 @@ nsCanvasRenderingContext2D::SetDimensions(PRInt32 width, PRInt32 height)
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsCanvasRenderingContext2D::SetIsOpaque(PRBool isOpaque)
|
||||||
|
{
|
||||||
|
if (isOpaque == mOpaque)
|
||||||
|
return NS_OK;
|
||||||
|
|
||||||
|
mOpaque = isOpaque;
|
||||||
|
|
||||||
|
if (mValid) {
|
||||||
|
/* If we've already been created, let SetDimensions take care of
|
||||||
|
* recreating our surface
|
||||||
|
*/
|
||||||
|
return SetDimensions(mWidth, mHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsCanvasRenderingContext2D::Render(gfxContext *ctx)
|
nsCanvasRenderingContext2D::Render(gfxContext *ctx)
|
||||||
{
|
{
|
||||||
|
@ -748,12 +773,19 @@ nsCanvasRenderingContext2D::Render(gfxContext *ctx)
|
||||||
|
|
||||||
nsRefPtr<gfxPattern> pat = new gfxPattern(mThebesSurface);
|
nsRefPtr<gfxPattern> pat = new gfxPattern(mThebesSurface);
|
||||||
|
|
||||||
|
gfxContext::GraphicsOperator op = ctx->CurrentOperator();
|
||||||
|
if (mOpaque)
|
||||||
|
ctx->SetOperator(gfxContext::OPERATOR_SOURCE);
|
||||||
|
|
||||||
// XXX I don't want to use PixelSnapped here, but layout doesn't guarantee
|
// XXX I don't want to use PixelSnapped here, but layout doesn't guarantee
|
||||||
// pixel alignment for this stuff!
|
// pixel alignment for this stuff!
|
||||||
ctx->NewPath();
|
ctx->NewPath();
|
||||||
ctx->PixelSnappedRectangleAndSetPattern(gfxRect(0, 0, mWidth, mHeight), pat);
|
ctx->PixelSnappedRectangleAndSetPattern(gfxRect(0, 0, mWidth, mHeight), pat);
|
||||||
ctx->Fill();
|
ctx->Fill();
|
||||||
|
|
||||||
|
if (mOpaque)
|
||||||
|
ctx->SetOperator(op);
|
||||||
|
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -118,6 +118,8 @@ public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
nsIntSize GetWidthHeight();
|
nsIntSize GetWidthHeight();
|
||||||
|
PRBool GetIsOpaque();
|
||||||
|
|
||||||
nsresult UpdateContext();
|
nsresult UpdateContext();
|
||||||
nsresult ToDataURLImpl(const nsAString& aMimeType,
|
nsresult ToDataURLImpl(const nsAString& aMimeType,
|
||||||
const nsAString& aEncoderOptions,
|
const nsAString& aEncoderOptions,
|
||||||
|
@ -191,8 +193,15 @@ nsHTMLCanvasElement::GetWidthHeight()
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PRBool
|
||||||
|
nsHTMLCanvasElement::GetIsOpaque()
|
||||||
|
{
|
||||||
|
return HasAttr(kNameSpaceID_None, nsGkAtoms::moz_opaque);
|
||||||
|
}
|
||||||
|
|
||||||
NS_IMPL_INT_ATTR_DEFAULT_VALUE(nsHTMLCanvasElement, Width, width, DEFAULT_CANVAS_WIDTH)
|
NS_IMPL_INT_ATTR_DEFAULT_VALUE(nsHTMLCanvasElement, Width, width, DEFAULT_CANVAS_WIDTH)
|
||||||
NS_IMPL_INT_ATTR_DEFAULT_VALUE(nsHTMLCanvasElement, Height, height, DEFAULT_CANVAS_HEIGHT)
|
NS_IMPL_INT_ATTR_DEFAULT_VALUE(nsHTMLCanvasElement, Height, height, DEFAULT_CANVAS_HEIGHT)
|
||||||
|
NS_IMPL_BOOL_ATTR(nsHTMLCanvasElement, MozOpaque, moz_opaque)
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsHTMLCanvasElement::SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
nsHTMLCanvasElement::SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
||||||
|
@ -202,7 +211,7 @@ nsHTMLCanvasElement::SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
||||||
nsresult rv = nsGenericHTMLElement::SetAttr(aNameSpaceID, aName, aPrefix, aValue,
|
nsresult rv = nsGenericHTMLElement::SetAttr(aNameSpaceID, aName, aPrefix, aValue,
|
||||||
aNotify);
|
aNotify);
|
||||||
if (NS_SUCCEEDED(rv) && mCurrentContext &&
|
if (NS_SUCCEEDED(rv) && mCurrentContext &&
|
||||||
(aName == nsGkAtoms::width || aName == nsGkAtoms::height))
|
(aName == nsGkAtoms::width || aName == nsGkAtoms::height || aName == nsGkAtoms::moz_opaque))
|
||||||
{
|
{
|
||||||
rv = UpdateContext();
|
rv = UpdateContext();
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
@ -221,6 +230,9 @@ nsHTMLCanvasElement::GetAttributeChangeHint(const nsIAtom* aAttribute,
|
||||||
aAttribute == nsGkAtoms::height)
|
aAttribute == nsGkAtoms::height)
|
||||||
{
|
{
|
||||||
NS_UpdateHint(retval, NS_STYLE_HINT_REFLOW);
|
NS_UpdateHint(retval, NS_STYLE_HINT_REFLOW);
|
||||||
|
} else if (aAttribute == nsGkAtoms::moz_opaque)
|
||||||
|
{
|
||||||
|
NS_UpdateHint(retval, NS_STYLE_HINT_VISUAL);
|
||||||
}
|
}
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
@ -488,6 +500,7 @@ nsHTMLCanvasElement::UpdateContext()
|
||||||
nsresult rv = NS_OK;
|
nsresult rv = NS_OK;
|
||||||
if (mCurrentContext) {
|
if (mCurrentContext) {
|
||||||
nsIntSize sz = GetWidthHeight();
|
nsIntSize sz = GetWidthHeight();
|
||||||
|
rv = mCurrentContext->SetIsOpaque(GetIsOpaque());
|
||||||
rv = mCurrentContext->SetDimensions(sz.width, sz.height);
|
rv = mCurrentContext->SetDimensions(sz.width, sz.height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -52,6 +52,7 @@ interface nsIDOMHTMLCanvasElement : nsIDOMHTMLElement
|
||||||
{
|
{
|
||||||
attribute long width;
|
attribute long width;
|
||||||
attribute long height;
|
attribute long height;
|
||||||
|
attribute boolean mozOpaque;
|
||||||
|
|
||||||
nsISupports getContext(in DOMString contextId);
|
nsISupports getContext(in DOMString contextId);
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче