mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 745025 - Part 1 - Adds mozPrintCallback for canvas. r=smaug
This commit is contained in:
parent
1bc80d0294
commit
3f688bb97f
@ -1413,7 +1413,9 @@ nsCanvasRenderingContext2D::GetImageFormat() const
|
||||
NS_IMETHODIMP
|
||||
nsCanvasRenderingContext2D::GetCanvas(nsIDOMHTMLCanvasElement **canvas)
|
||||
{
|
||||
NS_IF_ADDREF(*canvas = mCanvasElement);
|
||||
if (mCanvasElement) {
|
||||
NS_IF_ADDREF(*canvas = mCanvasElement->GetOriginalCanvas());
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -1124,7 +1124,9 @@ nsCanvasRenderingContext2DAzure::GetSurfaceFormat() const
|
||||
NS_IMETHODIMP
|
||||
nsCanvasRenderingContext2DAzure::GetCanvas(nsIDOMHTMLCanvasElement **canvas)
|
||||
{
|
||||
NS_IF_ADDREF(*canvas = GetCanvas());
|
||||
if (mCanvasElement) {
|
||||
NS_IF_ADDREF(*canvas = mCanvasElement->GetOriginalCanvas());
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -18,6 +18,8 @@
|
||||
|
||||
class nsICanvasRenderingContextInternal;
|
||||
class nsIDOMFile;
|
||||
class nsHTMLCanvasPrintState;
|
||||
class nsITimerCallback;
|
||||
class nsIPropertyBag;
|
||||
|
||||
namespace mozilla {
|
||||
@ -168,9 +170,13 @@ protected:
|
||||
nsresult GetContextHelper(const nsAString& aContextId,
|
||||
bool aForceThebes,
|
||||
nsICanvasRenderingContextInternal **aContext);
|
||||
void CallPrintCallback();
|
||||
|
||||
nsString mCurrentContextId;
|
||||
nsCOMPtr<nsIDOMHTMLCanvasElement> mOriginalCanvas;
|
||||
nsCOMPtr<nsIPrintCallback> mPrintCallback;
|
||||
nsCOMPtr<nsICanvasRenderingContextInternal> mCurrentContext;
|
||||
nsCOMPtr<nsHTMLCanvasPrintState> mPrintState;
|
||||
|
||||
public:
|
||||
// Record whether this canvas should be write-only or not.
|
||||
@ -178,6 +184,16 @@ public:
|
||||
// We also transitively set it when script paints a canvas which
|
||||
// is itself write-only.
|
||||
bool mWriteOnly;
|
||||
|
||||
bool IsPrintCallbackDone();
|
||||
|
||||
void HandlePrintCallback(nsPresContext::nsPresContextType aType);
|
||||
|
||||
nsresult DispatchPrintCallback(nsITimerCallback* aCallback);
|
||||
|
||||
void ResetPrintCallback();
|
||||
|
||||
nsIDOMHTMLCanvasElement* GetOriginalCanvas();
|
||||
};
|
||||
|
||||
inline nsISupports*
|
||||
|
@ -28,6 +28,8 @@
|
||||
#include "nsDisplayList.h"
|
||||
#include "BasicLayers.h"
|
||||
#include "imgIEncoder.h"
|
||||
#include "nsITimer.h"
|
||||
#include "nsAsyncDOMEvent.h"
|
||||
|
||||
#include "nsIWritablePropertyBag2.h"
|
||||
|
||||
@ -38,6 +40,91 @@ using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
using namespace mozilla::layers;
|
||||
|
||||
class nsHTMLCanvasPrintState : public nsIDOMMozCanvasPrintState
|
||||
{
|
||||
public:
|
||||
nsHTMLCanvasPrintState(nsHTMLCanvasElement* aCanvas,
|
||||
nsICanvasRenderingContextInternal* aContext,
|
||||
nsITimerCallback* aCallback)
|
||||
: mIsDone(false), mPendingNotify(false), mCanvas(aCanvas),
|
||||
mContext(aContext), mCallback(aCallback)
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHOD GetContext(nsISupports** aContext)
|
||||
{
|
||||
NS_ADDREF(*aContext = mContext);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHOD Done()
|
||||
{
|
||||
if (!mPendingNotify && !mIsDone) {
|
||||
// The canvas needs to be invalidated for printing reftests on linux to
|
||||
// work.
|
||||
if (mCanvas) {
|
||||
mCanvas->InvalidateCanvas();
|
||||
}
|
||||
nsRefPtr<nsRunnableMethod<nsHTMLCanvasPrintState> > doneEvent =
|
||||
NS_NewRunnableMethod(this, &nsHTMLCanvasPrintState::NotifyDone);
|
||||
if (NS_SUCCEEDED(NS_DispatchToCurrentThread(doneEvent))) {
|
||||
mPendingNotify = true;
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void NotifyDone()
|
||||
{
|
||||
mIsDone = true;
|
||||
mPendingNotify = false;
|
||||
if (mCallback) {
|
||||
mCallback->Notify(nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
bool mIsDone;
|
||||
|
||||
// CC
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS(nsHTMLCanvasPrintState)
|
||||
private:
|
||||
virtual ~nsHTMLCanvasPrintState()
|
||||
{
|
||||
}
|
||||
bool mPendingNotify;
|
||||
|
||||
protected:
|
||||
nsRefPtr<nsHTMLCanvasElement> mCanvas;
|
||||
nsCOMPtr<nsICanvasRenderingContextInternal> mContext;
|
||||
nsCOMPtr<nsITimerCallback> mCallback;
|
||||
};
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTING_ADDREF(nsHTMLCanvasPrintState)
|
||||
NS_IMPL_CYCLE_COLLECTING_RELEASE(nsHTMLCanvasPrintState)
|
||||
|
||||
DOMCI_DATA(MozCanvasPrintState, nsHTMLCanvasPrintState)
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsHTMLCanvasPrintState)
|
||||
NS_INTERFACE_MAP_ENTRY(nsISupports)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIDOMMozCanvasPrintState)
|
||||
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(MozCanvasPrintState)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(nsHTMLCanvasPrintState)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsHTMLCanvasPrintState)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR_AMBIGUOUS(mCanvas, nsIDOMHTMLCanvasElement)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mContext)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mCallback)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsHTMLCanvasPrintState)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mCanvas)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mContext)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mCallback)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
nsGenericHTMLElement*
|
||||
NS_NewHTMLCanvasElement(already_AddRefed<nsINodeInfo> aNodeInfo,
|
||||
FromParser aFromParser)
|
||||
@ -46,23 +133,31 @@ NS_NewHTMLCanvasElement(already_AddRefed<nsINodeInfo> aNodeInfo,
|
||||
}
|
||||
|
||||
nsHTMLCanvasElement::nsHTMLCanvasElement(already_AddRefed<nsINodeInfo> aNodeInfo)
|
||||
: nsGenericHTMLElement(aNodeInfo), mWriteOnly(false)
|
||||
: nsGenericHTMLElement(aNodeInfo),
|
||||
mWriteOnly(false)
|
||||
{
|
||||
}
|
||||
|
||||
nsHTMLCanvasElement::~nsHTMLCanvasElement()
|
||||
{
|
||||
ResetPrintCallback();
|
||||
}
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(nsHTMLCanvasElement)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsHTMLCanvasElement,
|
||||
nsGenericHTMLElement)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mCurrentContext)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mPrintCallback)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mPrintState)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOriginalCanvas)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsHTMLCanvasElement,
|
||||
nsGenericHTMLElement)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mCurrentContext)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mPrintCallback)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mPrintState)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOriginalCanvas)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
|
||||
NS_IMPL_ADDREF_INHERITED(nsHTMLCanvasElement, nsGenericElement)
|
||||
@ -122,6 +217,74 @@ nsHTMLCanvasElement::SetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
||||
return rv;
|
||||
}
|
||||
|
||||
void
|
||||
nsHTMLCanvasElement::HandlePrintCallback(nsPresContext::nsPresContextType aType)
|
||||
{
|
||||
// Only call the print callback here if 1) we're in a print testing mode or
|
||||
// print preview mode, 2) the canvas has a print callback and 3) the callback
|
||||
// hasn't already been called. For real printing the callback is handled in
|
||||
// nsSimplePageSequenceFrame::PrePrintNextPage.
|
||||
nsCOMPtr<nsIPrintCallback> printCallback;
|
||||
if ((aType == nsPresContext::eContext_PageLayout ||
|
||||
aType == nsPresContext::eContext_PrintPreview) &&
|
||||
!mPrintState &&
|
||||
NS_SUCCEEDED(GetMozPrintCallback(getter_AddRefs(printCallback))) && printCallback) {
|
||||
DispatchPrintCallback(nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsHTMLCanvasElement::DispatchPrintCallback(nsITimerCallback* aCallback)
|
||||
{
|
||||
// For print reftests the context may not be initialized yet, so get a context
|
||||
// so mCurrentContext is set.
|
||||
if (!mCurrentContext) {
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsISupports> context;
|
||||
rv = GetContext(NS_LITERAL_STRING("2d"), JSVAL_VOID,
|
||||
getter_AddRefs(context));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
mPrintState = new nsHTMLCanvasPrintState(this, mCurrentContext, aCallback);
|
||||
|
||||
nsRefPtr<nsRunnableMethod<nsHTMLCanvasElement> > renderEvent =
|
||||
NS_NewRunnableMethod(this, &nsHTMLCanvasElement::CallPrintCallback);
|
||||
return NS_DispatchToCurrentThread(renderEvent);
|
||||
}
|
||||
|
||||
void
|
||||
nsHTMLCanvasElement::CallPrintCallback()
|
||||
{
|
||||
nsCOMPtr<nsIPrintCallback> printCallback;
|
||||
GetMozPrintCallback(getter_AddRefs(printCallback));
|
||||
printCallback->Render(mPrintState);
|
||||
}
|
||||
|
||||
void
|
||||
nsHTMLCanvasElement::ResetPrintCallback()
|
||||
{
|
||||
if (mPrintState) {
|
||||
mPrintState = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
nsHTMLCanvasElement::IsPrintCallbackDone()
|
||||
{
|
||||
if (mPrintState == nullptr) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return mPrintState->mIsDone;
|
||||
}
|
||||
|
||||
nsIDOMHTMLCanvasElement*
|
||||
nsHTMLCanvasElement::GetOriginalCanvas()
|
||||
{
|
||||
return mOriginalCanvas ? mOriginalCanvas.get() : this;
|
||||
}
|
||||
|
||||
|
||||
nsresult
|
||||
nsHTMLCanvasElement::CopyInnerTo(nsGenericElement* aDest)
|
||||
{
|
||||
@ -129,11 +292,14 @@ nsHTMLCanvasElement::CopyInnerTo(nsGenericElement* aDest)
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (aDest->OwnerDoc()->IsStaticDocument()) {
|
||||
nsHTMLCanvasElement* dest = static_cast<nsHTMLCanvasElement*>(aDest);
|
||||
nsHTMLCanvasElement* self = const_cast<nsHTMLCanvasElement*>(this);
|
||||
dest->mOriginalCanvas = self;
|
||||
|
||||
nsCOMPtr<nsISupports> cxt;
|
||||
dest->GetContext(NS_LITERAL_STRING("2d"), JSVAL_VOID, getter_AddRefs(cxt));
|
||||
nsCOMPtr<nsIDOMCanvasRenderingContext2D> context2d = do_QueryInterface(cxt);
|
||||
if (context2d) {
|
||||
context2d->DrawImage(const_cast<nsHTMLCanvasElement*>(this),
|
||||
if (context2d && !self->mPrintCallback) {
|
||||
context2d->DrawImage(self,
|
||||
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0);
|
||||
}
|
||||
}
|
||||
@ -217,6 +383,24 @@ nsHTMLCanvasElement::MozFetchAsStream(nsIInputStreamCallback *aCallback,
|
||||
return asyncCallback->OnInputStreamReady(asyncData);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLCanvasElement::SetMozPrintCallback(nsIPrintCallback *aCallback)
|
||||
{
|
||||
mPrintCallback = aCallback;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLCanvasElement::GetMozPrintCallback(nsIPrintCallback** aCallback)
|
||||
{
|
||||
if (mOriginalCanvas) {
|
||||
mOriginalCanvas->GetMozPrintCallback(aCallback);
|
||||
return NS_OK;
|
||||
}
|
||||
NS_IF_ADDREF(*aCallback = mPrintCallback);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsHTMLCanvasElement::ExtractData(const nsAString& aType,
|
||||
const nsAString& aOptions,
|
||||
|
@ -1346,6 +1346,8 @@ static nsDOMClassInfoData sClassInfoData[] = {
|
||||
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
||||
NS_DEFINE_CLASSINFO_DATA(ImageData, nsDOMGenericSH,
|
||||
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
||||
NS_DEFINE_CLASSINFO_DATA(MozCanvasPrintState, nsDOMGenericSH,
|
||||
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
||||
|
||||
NS_DEFINE_CLASSINFO_DATA(SmartCardEvent, nsDOMGenericSH,
|
||||
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
||||
@ -3926,6 +3928,10 @@ nsDOMClassInfo::Init()
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMImageData)
|
||||
DOM_CLASSINFO_MAP_END
|
||||
|
||||
DOM_CLASSINFO_MAP_BEGIN(MozCanvasPrintState, nsIDOMMozCanvasPrintState)
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMMozCanvasPrintState)
|
||||
DOM_CLASSINFO_MAP_END
|
||||
|
||||
DOM_CLASSINFO_MAP_BEGIN(XSLTProcessor, nsIXSLTProcessor)
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsIXSLTProcessor)
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsIXSLTProcessorPrivate)
|
||||
|
@ -322,6 +322,7 @@ DOMCI_CLASS(CanvasGradient)
|
||||
DOMCI_CLASS(CanvasPattern)
|
||||
DOMCI_CLASS(TextMetrics)
|
||||
DOMCI_CLASS(ImageData)
|
||||
DOMCI_CLASS(MozCanvasPrintState)
|
||||
|
||||
// SmartCard Events
|
||||
DOMCI_CLASS(SmartCardEvent)
|
||||
|
@ -24,7 +24,23 @@ interface nsIDOMFile;
|
||||
interface nsIVariant;
|
||||
interface nsIInputStreamCallback;
|
||||
|
||||
[scriptable, uuid(5929542B-C68E-48AB-84F9-D9642DA39720)]
|
||||
[scriptable, builtinclass, uuid(8d5fb8a0-7782-11e1-b0c4-0800200c9a67)]
|
||||
interface nsIDOMMozCanvasPrintState : nsISupports
|
||||
{
|
||||
// A canvas rendering context.
|
||||
readonly attribute nsISupports context;
|
||||
|
||||
// To be called when rendering to the context is done.
|
||||
void done();
|
||||
};
|
||||
|
||||
[scriptable, function, uuid(8d5fb8a0-7782-11e1-b0c4-0800200c9a66)]
|
||||
interface nsIPrintCallback : nsISupports
|
||||
{
|
||||
void render(in nsIDOMMozCanvasPrintState ctx);
|
||||
};
|
||||
|
||||
[scriptable, uuid(a7062fca-41c6-4520-b777-3bb30fd77273)]
|
||||
interface nsIDOMHTMLCanvasElement : nsIDOMHTMLElement
|
||||
{
|
||||
attribute unsigned long width;
|
||||
@ -56,5 +72,8 @@ interface nsIDOMHTMLCanvasElement : nsIDOMHTMLElement
|
||||
// stream in the desired image format.
|
||||
void mozFetchAsStream(in nsIInputStreamCallback callback,
|
||||
[optional] in DOMString type);
|
||||
|
||||
// A Mozilla-only callback that is called during the printing process.
|
||||
attribute nsIPrintCallback mozPrintCallback;
|
||||
};
|
||||
|
||||
|
@ -530,6 +530,7 @@ var interfaceNamesInGlobalScope =
|
||||
"CameraManager",
|
||||
"CSSSupportsRule",
|
||||
"MozMobileCellInfo",
|
||||
"MozCanvasPrintState",
|
||||
"TCPSocket"
|
||||
]
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user