mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-03 20:49:27 +00:00
Bug 740200 - BorrowedContext support for cairo; r=mattwoodrow
This commit is contained in:
parent
d6eaee854e
commit
16051488eb
57
gfx/2d/2D.h
57
gfx/2d/2D.h
@ -27,6 +27,9 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
struct _cairo;
|
||||||
|
typedef struct _cairo cairo_t;
|
||||||
|
|
||||||
struct _cairo_surface;
|
struct _cairo_surface;
|
||||||
typedef _cairo_surface cairo_surface_t;
|
typedef _cairo_surface cairo_surface_t;
|
||||||
|
|
||||||
@ -1017,6 +1020,60 @@ private:
|
|||||||
static DrawEventRecorder *mRecorder;
|
static DrawEventRecorder *mRecorder;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* 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)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
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 XP_MACOSX
|
#ifdef XP_MACOSX
|
||||||
/* This is a helper class that let's you borrow a CGContextRef from a
|
/* This is a helper class that let's you borrow a CGContextRef from a
|
||||||
* DrawTargetCG. This is used for drawing themed widgets.
|
* DrawTargetCG. This is used for drawing themed widgets.
|
||||||
|
@ -1096,5 +1096,38 @@ DrawTargetCairo::SetTransform(const Matrix& aTransform)
|
|||||||
cairo_set_matrix(mContext, &mat);
|
cairo_set_matrix(mContext, &mat);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cairo_t*
|
||||||
|
BorrowedCairoContext::BorrowCairoContextFromDrawTarget(DrawTarget* aDT)
|
||||||
|
{
|
||||||
|
if (aDT->GetType() != BACKEND_CAIRO || aDT->IsDualDrawTarget()) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
DrawTargetCairo* cairoDT = static_cast<DrawTargetCairo*>(aDT);
|
||||||
|
|
||||||
|
cairoDT->WillChange();
|
||||||
|
|
||||||
|
// save the state to make it easier for callers to avoid mucking with things
|
||||||
|
cairo_save(cairoDT->mContext);
|
||||||
|
|
||||||
|
// Neuter the DrawTarget while the context is being borrowed
|
||||||
|
cairo_t* cairo = cairoDT->mContext;
|
||||||
|
cairoDT->mContext = nullptr;
|
||||||
|
|
||||||
|
return cairo;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
BorrowedCairoContext::ReturnCairoContextToDrawTarget(DrawTarget* aDT,
|
||||||
|
cairo_t* aCairo)
|
||||||
|
{
|
||||||
|
if (aDT->GetType() != BACKEND_CAIRO || aDT->IsDualDrawTarget()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
DrawTargetCairo* cairoDT = static_cast<DrawTargetCairo*>(aDT);
|
||||||
|
|
||||||
|
cairo_restore(aCairo);
|
||||||
|
cairoDT->mContext = aCairo;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -51,6 +51,8 @@ class GradientStopsCairo : public GradientStops
|
|||||||
class DrawTargetCairo : public DrawTarget
|
class DrawTargetCairo : public DrawTarget
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
friend BorrowedCairoContext;
|
||||||
|
|
||||||
DrawTargetCairo();
|
DrawTargetCairo();
|
||||||
virtual ~DrawTargetCairo();
|
virtual ~DrawTargetCairo();
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user