зеркало из https://github.com/mozilla/gecko-dev.git
Bug 740200 - BorrowedContext support for cairo; r=mattwoodrow
This commit is contained in:
Родитель
d6eaee854e
Коммит
16051488eb
57
gfx/2d/2D.h
57
gfx/2d/2D.h
|
@ -27,6 +27,9 @@
|
|||
#include <string>
|
||||
#endif
|
||||
|
||||
struct _cairo;
|
||||
typedef struct _cairo cairo_t;
|
||||
|
||||
struct _cairo_surface;
|
||||
typedef _cairo_surface cairo_surface_t;
|
||||
|
||||
|
@ -1017,6 +1020,60 @@ private:
|
|||
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
|
||||
/* This is a helper class that let's you borrow a CGContextRef from a
|
||||
* DrawTargetCG. This is used for drawing themed widgets.
|
||||
|
|
|
@ -1096,5 +1096,38 @@ DrawTargetCairo::SetTransform(const Matrix& aTransform)
|
|||
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
|
||||
{
|
||||
public:
|
||||
friend BorrowedCairoContext;
|
||||
|
||||
DrawTargetCairo();
|
||||
virtual ~DrawTargetCairo();
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче