summaryrefslogtreecommitdiffstats
path: root/gfx/2d/BorrowedContext.h
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/2d/BorrowedContext.h')
-rw-r--r--gfx/2d/BorrowedContext.h195
1 files changed, 195 insertions, 0 deletions
diff --git a/gfx/2d/BorrowedContext.h b/gfx/2d/BorrowedContext.h
new file mode 100644
index 0000000000..d39e220db0
--- /dev/null
+++ b/gfx/2d/BorrowedContext.h
@@ -0,0 +1,195 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef _MOZILLA_GFX_BORROWED_CONTEXT_H
+#define _MOZILLA_GFX_BORROWED_CONTEXT_H
+
+#include "2D.h"
+
+#ifdef MOZ_X11
+# include <X11/extensions/Xrender.h>
+# include <X11/Xlib.h>
+# include "X11UndefineNone.h"
+#endif
+
+struct _cairo;
+typedef struct _cairo cairo_t;
+
+namespace mozilla {
+
+namespace gfx {
+
+/* This is a helper class that let's you borrow a cairo_t from a
+ * DrawTargetCairo. This is used for drawing themed widgets.
+ *
+ * Callers should check the cr member after constructing the object
+ * to see if it succeeded. The DrawTarget should not be used while
+ * the context is borrowed. */
+class BorrowedCairoContext {
+ public:
+ BorrowedCairoContext() : mCairo(nullptr), mDT(nullptr) {}
+
+ explicit BorrowedCairoContext(DrawTarget* aDT) : mDT(aDT) {
+ mCairo = BorrowCairoContextFromDrawTarget(aDT);
+ }
+
+ // We can optionally Init after construction in
+ // case we don't know what the DT will be at construction
+ // time.
+ cairo_t* Init(DrawTarget* aDT) {
+ MOZ_ASSERT(!mDT, "Can't initialize twice!");
+ mDT = aDT;
+ return mCairo = BorrowCairoContextFromDrawTarget(aDT);
+ }
+
+ // The caller needs to call Finish if cr is non-null when
+ // they are done with the context. This is currently explicit
+ // instead of happening implicitly in the destructor to make
+ // what's happening in the caller more clear. It also
+ // let's you resume using the DrawTarget in the same scope.
+ void Finish() {
+ if (mCairo) {
+ ReturnCairoContextToDrawTarget(mDT, mCairo);
+ mCairo = nullptr;
+ }
+ }
+
+ ~BorrowedCairoContext() { MOZ_ASSERT(!mCairo); }
+
+ cairo_t* mCairo;
+
+ private:
+ static cairo_t* BorrowCairoContextFromDrawTarget(DrawTarget* aDT);
+ static void ReturnCairoContextToDrawTarget(DrawTarget* aDT, cairo_t* aCairo);
+ DrawTarget* mDT;
+};
+
+#ifdef MOZ_X11
+/* This is a helper class that let's you borrow an Xlib drawable from
+ * a DrawTarget. This is used for drawing themed widgets.
+ *
+ * Callers should check the Xlib drawable after constructing the object
+ * to see if it succeeded. The DrawTarget should not be used while
+ * the drawable is borrowed. */
+class BorrowedXlibDrawable {
+ public:
+ BorrowedXlibDrawable()
+ : mDT(nullptr),
+ mDisplay(nullptr),
+ mDrawable(X11None),
+ mScreen(nullptr),
+ mVisual(nullptr),
+ mXRenderFormat(nullptr) {}
+
+ explicit BorrowedXlibDrawable(DrawTarget* aDT)
+ : mDT(nullptr),
+ mDisplay(nullptr),
+ mDrawable(X11None),
+ mScreen(nullptr),
+ mVisual(nullptr),
+ mXRenderFormat(nullptr) {
+ Init(aDT);
+ }
+
+ // We can optionally Init after construction in
+ // case we don't know what the DT will be at construction
+ // time.
+ bool Init(DrawTarget* aDT);
+
+ // The caller needs to call Finish if drawable is non-zero when
+ // they are done with the context. This is currently explicit
+ // instead of happening implicitly in the destructor to make
+ // what's happening in the caller more clear. It also
+ // let's you resume using the DrawTarget in the same scope.
+ void Finish();
+
+ ~BorrowedXlibDrawable() { MOZ_ASSERT(!mDrawable); }
+
+ Display* GetDisplay() const { return mDisplay; }
+ Drawable GetDrawable() const { return mDrawable; }
+ Screen* GetScreen() const { return mScreen; }
+ Visual* GetVisual() const { return mVisual; }
+ IntSize GetSize() const { return mSize; }
+ Point GetOffset() const { return mOffset; }
+
+ XRenderPictFormat* GetXRenderFormat() const { return mXRenderFormat; }
+
+ private:
+ DrawTarget* mDT;
+ Display* mDisplay;
+ Drawable mDrawable;
+ Screen* mScreen;
+ Visual* mVisual;
+ XRenderPictFormat* mXRenderFormat;
+ IntSize mSize;
+ Point mOffset;
+};
+#endif
+
+#ifdef XP_DARWIN
+/* This is a helper class that let's you borrow a CGContextRef from a
+ * DrawTargetCG. This is used for drawing themed widgets.
+ *
+ * Callers should check the cg member after constructing the object
+ * to see if it succeeded. The DrawTarget should not be used while
+ * the context is borrowed. */
+class BorrowedCGContext {
+ public:
+ BorrowedCGContext() : cg(nullptr), mDT(nullptr) {}
+
+ explicit BorrowedCGContext(DrawTarget* aDT) : mDT(aDT) {
+ MOZ_ASSERT(aDT, "Caller should check for nullptr");
+ cg = BorrowCGContextFromDrawTarget(aDT);
+ }
+
+ // We can optionally Init after construction in
+ // case we don't know what the DT will be at construction
+ // time.
+ CGContextRef Init(DrawTarget* aDT) {
+ MOZ_ASSERT(aDT, "Caller should check for nullptr");
+ MOZ_ASSERT(!mDT, "Can't initialize twice!");
+ mDT = aDT;
+ cg = BorrowCGContextFromDrawTarget(aDT);
+ return cg;
+ }
+
+ // The caller needs to call Finish if cg is non-null when
+ // they are done with the context. This is currently explicit
+ // instead of happening implicitly in the destructor to make
+ // what's happening in the caller more clear. It also
+ // let's you resume using the DrawTarget in the same scope.
+ void Finish() {
+ if (cg) {
+ ReturnCGContextToDrawTarget(mDT, cg);
+ cg = nullptr;
+ }
+ }
+
+ ~BorrowedCGContext() { MOZ_ASSERT(!cg); }
+
+ CGContextRef cg;
+
+ private:
+# ifdef USE_SKIA
+ static CGContextRef BorrowCGContextFromDrawTarget(DrawTarget* aDT);
+ static void ReturnCGContextToDrawTarget(DrawTarget* aDT, CGContextRef cg);
+# else
+ static CGContextRef BorrowCGContextFromDrawTarget(DrawTarget* aDT) {
+ MOZ_CRASH("Not supported without Skia");
+ }
+
+ static void ReturnCGContextToDrawTarget(DrawTarget* aDT, CGContextRef cg) {
+ MOZ_CRASH("not supported without Skia");
+ }
+# endif
+ DrawTarget* mDT;
+};
+#endif
+
+} // namespace gfx
+} // namespace mozilla
+
+#endif // _MOZILLA_GFX_BORROWED_CONTEXT_H