1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #ifndef _MOZILLA_GFX_BORROWED_CONTEXT_H 8 #define _MOZILLA_GFX_BORROWED_CONTEXT_H 9 10 #include "2D.h" 11 12 #ifdef MOZ_X11 13 # include <X11/extensions/Xrender.h> 14 # include <X11/Xlib.h> 15 # include "X11UndefineNone.h" 16 #endif 17 18 struct _cairo; 19 typedef struct _cairo cairo_t; 20 21 namespace mozilla { 22 23 namespace gfx { 24 25 /* This is a helper class that let's you borrow a cairo_t from a 26 * DrawTargetCairo. This is used for drawing themed widgets. 27 * 28 * Callers should check the cr member after constructing the object 29 * to see if it succeeded. The DrawTarget should not be used while 30 * the context is borrowed. */ 31 class BorrowedCairoContext { 32 public: BorrowedCairoContext()33 BorrowedCairoContext() : mCairo(nullptr), mDT(nullptr) {} 34 BorrowedCairoContext(DrawTarget * aDT)35 explicit BorrowedCairoContext(DrawTarget* aDT) : mDT(aDT) { 36 mCairo = BorrowCairoContextFromDrawTarget(aDT); 37 } 38 39 // We can optionally Init after construction in 40 // case we don't know what the DT will be at construction 41 // time. Init(DrawTarget * aDT)42 cairo_t* Init(DrawTarget* aDT) { 43 MOZ_ASSERT(!mDT, "Can't initialize twice!"); 44 mDT = aDT; 45 return mCairo = BorrowCairoContextFromDrawTarget(aDT); 46 } 47 48 // The caller needs to call Finish if cr is non-null when 49 // they are done with the context. This is currently explicit 50 // instead of happening implicitly in the destructor to make 51 // what's happening in the caller more clear. It also 52 // let's you resume using the DrawTarget in the same scope. Finish()53 void Finish() { 54 if (mCairo) { 55 ReturnCairoContextToDrawTarget(mDT, mCairo); 56 mCairo = nullptr; 57 } 58 } 59 ~BorrowedCairoContext()60 ~BorrowedCairoContext() { MOZ_ASSERT(!mCairo); } 61 62 cairo_t* mCairo; 63 64 private: 65 static cairo_t* BorrowCairoContextFromDrawTarget(DrawTarget* aDT); 66 static void ReturnCairoContextToDrawTarget(DrawTarget* aDT, cairo_t* aCairo); 67 DrawTarget* mDT; 68 }; 69 70 #ifdef MOZ_X11 71 /* This is a helper class that let's you borrow an Xlib drawable from 72 * a DrawTarget. This is used for drawing themed widgets. 73 * 74 * Callers should check the Xlib drawable after constructing the object 75 * to see if it succeeded. The DrawTarget should not be used while 76 * the drawable is borrowed. */ 77 class BorrowedXlibDrawable { 78 public: BorrowedXlibDrawable()79 BorrowedXlibDrawable() 80 : mDT(nullptr), 81 mDisplay(nullptr), 82 mDrawable(X11None), 83 mScreen(nullptr), 84 mVisual(nullptr), 85 mXRenderFormat(nullptr) {} 86 BorrowedXlibDrawable(DrawTarget * aDT)87 explicit BorrowedXlibDrawable(DrawTarget* aDT) 88 : mDT(nullptr), 89 mDisplay(nullptr), 90 mDrawable(X11None), 91 mScreen(nullptr), 92 mVisual(nullptr), 93 mXRenderFormat(nullptr) { 94 Init(aDT); 95 } 96 97 // We can optionally Init after construction in 98 // case we don't know what the DT will be at construction 99 // time. 100 bool Init(DrawTarget* aDT); 101 102 // The caller needs to call Finish if drawable is non-zero when 103 // they are done with the context. This is currently explicit 104 // instead of happening implicitly in the destructor to make 105 // what's happening in the caller more clear. It also 106 // let's you resume using the DrawTarget in the same scope. 107 void Finish(); 108 ~BorrowedXlibDrawable()109 ~BorrowedXlibDrawable() { MOZ_ASSERT(!mDrawable); } 110 GetDisplay()111 Display* GetDisplay() const { return mDisplay; } GetDrawable()112 Drawable GetDrawable() const { return mDrawable; } GetScreen()113 Screen* GetScreen() const { return mScreen; } GetVisual()114 Visual* GetVisual() const { return mVisual; } GetSize()115 IntSize GetSize() const { return mSize; } GetOffset()116 Point GetOffset() const { return mOffset; } 117 GetXRenderFormat()118 XRenderPictFormat* GetXRenderFormat() const { return mXRenderFormat; } 119 120 private: 121 DrawTarget* mDT; 122 Display* mDisplay; 123 Drawable mDrawable; 124 Screen* mScreen; 125 Visual* mVisual; 126 XRenderPictFormat* mXRenderFormat; 127 IntSize mSize; 128 Point mOffset; 129 }; 130 #endif 131 132 #ifdef XP_DARWIN 133 /* This is a helper class that let's you borrow a CGContextRef from a 134 * DrawTargetCG. This is used for drawing themed widgets. 135 * 136 * Callers should check the cg member after constructing the object 137 * to see if it succeeded. The DrawTarget should not be used while 138 * the context is borrowed. */ 139 class BorrowedCGContext { 140 public: BorrowedCGContext()141 BorrowedCGContext() : cg(nullptr), mDT(nullptr) {} 142 BorrowedCGContext(DrawTarget * aDT)143 explicit BorrowedCGContext(DrawTarget* aDT) : mDT(aDT) { 144 MOZ_ASSERT(aDT, "Caller should check for nullptr"); 145 cg = BorrowCGContextFromDrawTarget(aDT); 146 } 147 148 // We can optionally Init after construction in 149 // case we don't know what the DT will be at construction 150 // time. Init(DrawTarget * aDT)151 CGContextRef Init(DrawTarget* aDT) { 152 MOZ_ASSERT(aDT, "Caller should check for nullptr"); 153 MOZ_ASSERT(!mDT, "Can't initialize twice!"); 154 mDT = aDT; 155 cg = BorrowCGContextFromDrawTarget(aDT); 156 return cg; 157 } 158 159 // The caller needs to call Finish if cg is non-null when 160 // they are done with the context. This is currently explicit 161 // instead of happening implicitly in the destructor to make 162 // what's happening in the caller more clear. It also 163 // let's you resume using the DrawTarget in the same scope. Finish()164 void Finish() { 165 if (cg) { 166 ReturnCGContextToDrawTarget(mDT, cg); 167 cg = nullptr; 168 } 169 } 170 ~BorrowedCGContext()171 ~BorrowedCGContext() { MOZ_ASSERT(!cg); } 172 173 CGContextRef cg; 174 175 private: 176 # ifdef USE_SKIA 177 static CGContextRef BorrowCGContextFromDrawTarget(DrawTarget* aDT); 178 static void ReturnCGContextToDrawTarget(DrawTarget* aDT, CGContextRef cg); 179 # else 180 static CGContextRef BorrowCGContextFromDrawTarget(DrawTarget* aDT) { 181 MOZ_CRASH("Not supported without Skia"); 182 } 183 184 static void ReturnCGContextToDrawTarget(DrawTarget* aDT, CGContextRef cg) { 185 MOZ_CRASH("not supported without Skia"); 186 } 187 # endif 188 DrawTarget* mDT; 189 }; 190 #endif 191 192 } // namespace gfx 193 } // namespace mozilla 194 195 #endif // _MOZILLA_GFX_BORROWED_CONTEXT_H 196