DoubleBufferedGraphics.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356
  1. using System.Drawing;
  2. using System.Drawing.Drawing2D;
  3. using System.Drawing.Text;
  4. using System.Windows.Forms;
  5. namespace Microsoft.Drawing
  6. {
  7. /// <summary>
  8. /// 双缓冲区
  9. /// </summary>
  10. public class DoubleBufferedGraphics : Disposable
  11. {
  12. private const int PRE_ALLOC = 10; //预分配大小
  13. private bool m_IsCreating; //是否正在创建缓冲区
  14. private IWindow m_Owner; //拥有该缓冲区的窗口
  15. private Graphics m_OwnerGraphics; //拥有该缓冲区的窗口的绘图画面
  16. private BufferedGraphics m_BufferedGraphics; //缓冲区
  17. #region 构造函数
  18. /// <summary>
  19. /// 构造函数
  20. /// </summary>
  21. /// <param name="owner">拥有者</param>
  22. public DoubleBufferedGraphics(IWindow owner)
  23. {
  24. this.m_Owner = owner;
  25. }
  26. #endregion
  27. #region 字段属性
  28. private CompositingMode m_CompositingMode = CompositingMode.SourceOver;
  29. /// <summary>
  30. /// 获取一个值,该值指定如何将合成图像绘制到此 System.Drawing.Graphics。
  31. /// </summary>
  32. public CompositingMode CompositingMode
  33. {
  34. get
  35. {
  36. return this.m_CompositingMode;
  37. }
  38. set
  39. {
  40. if (value != this.m_CompositingMode)
  41. {
  42. this.m_CompositingMode = value;
  43. if (this.m_BufferedGraphics != null)
  44. this.m_BufferedGraphics.Graphics.CompositingMode = value;
  45. }
  46. }
  47. }
  48. private CompositingQuality m_CompositingQuality = CompositingQuality.Default;
  49. /// <summary>
  50. /// 获取或设置绘制到此 System.Drawing.Graphics 的合成图像的呈现质量。
  51. /// </summary>
  52. public CompositingQuality CompositingQuality
  53. {
  54. get
  55. {
  56. return this.m_CompositingQuality;
  57. }
  58. set
  59. {
  60. if (value != this.m_CompositingQuality)
  61. {
  62. this.m_CompositingQuality = value;
  63. if (this.m_BufferedGraphics != null)
  64. this.m_BufferedGraphics.Graphics.CompositingQuality = value;
  65. }
  66. }
  67. }
  68. private InterpolationMode m_InterpolationMode = InterpolationMode.Bilinear;
  69. /// <summary>
  70. /// 获取或设置与此 System.Drawing.Graphics 关联的插补模式。
  71. /// </summary>
  72. public InterpolationMode InterpolationMode
  73. {
  74. get
  75. {
  76. return this.m_InterpolationMode;
  77. }
  78. set
  79. {
  80. if (value != this.m_InterpolationMode)
  81. {
  82. this.m_InterpolationMode = value;
  83. if (this.m_BufferedGraphics != null)
  84. this.m_BufferedGraphics.Graphics.InterpolationMode = value;
  85. }
  86. }
  87. }
  88. private PixelOffsetMode m_PixelOffsetMode = PixelOffsetMode.Default;
  89. /// <summary>
  90. /// 获取或设置一个值,该值指定在呈现此 System.Drawing.Graphics 的过程中像素如何偏移。
  91. /// </summary>
  92. public PixelOffsetMode PixelOffsetMode
  93. {
  94. get
  95. {
  96. return this.m_PixelOffsetMode;
  97. }
  98. set
  99. {
  100. if (value != this.m_PixelOffsetMode)
  101. {
  102. this.m_PixelOffsetMode = value;
  103. if (this.m_BufferedGraphics != null)
  104. this.m_BufferedGraphics.Graphics.PixelOffsetMode = value;
  105. }
  106. }
  107. }
  108. private SmoothingMode m_SmoothingMode = SmoothingMode.None;
  109. /// <summary>
  110. /// 获取或设置此 System.Drawing.Graphics 的呈现质量。
  111. /// </summary>
  112. public SmoothingMode SmoothingMode
  113. {
  114. get
  115. {
  116. return this.m_SmoothingMode;
  117. }
  118. set
  119. {
  120. if (value != this.m_SmoothingMode)
  121. {
  122. this.m_SmoothingMode = value;
  123. if (this.m_BufferedGraphics != null)
  124. this.m_BufferedGraphics.Graphics.SmoothingMode = value;
  125. }
  126. }
  127. }
  128. private int m_TextContrast = 4;
  129. /// <summary>
  130. /// 获取或设置呈现文本的灰度校正值。
  131. /// </summary>
  132. public int TextContrast
  133. {
  134. get
  135. {
  136. return this.m_TextContrast;
  137. }
  138. set
  139. {
  140. if (value != this.m_TextContrast)
  141. {
  142. this.m_TextContrast = value;
  143. if (this.m_BufferedGraphics != null)
  144. this.m_BufferedGraphics.Graphics.TextContrast = value;
  145. }
  146. }
  147. }
  148. private TextRenderingHint m_TextRenderingHint = TextRenderingHint.ClearTypeGridFit;
  149. /// <summary>
  150. /// 获取或设置与此 System.Drawing.Graphics 关联的文本的呈现模式。
  151. /// </summary>
  152. public TextRenderingHint TextRenderingHint
  153. {
  154. get
  155. {
  156. return this.m_TextRenderingHint;
  157. }
  158. set
  159. {
  160. if (value != this.m_TextRenderingHint)
  161. {
  162. this.m_TextRenderingHint = value;
  163. if (this.m_BufferedGraphics != null)
  164. this.m_BufferedGraphics.Graphics.TextRenderingHint = value;
  165. }
  166. }
  167. }
  168. /// <summary>
  169. /// 缓冲区绘图对象
  170. /// </summary>
  171. public Graphics Graphics
  172. {
  173. get
  174. {
  175. return this.m_BufferedGraphics.Graphics;
  176. }
  177. }
  178. private Size m_Size = Size.Empty;
  179. /// <summary>
  180. /// 获取缓冲区的虚拟画布大小。
  181. /// </summary>
  182. public Size Size
  183. {
  184. get
  185. {
  186. return this.m_Size;
  187. }
  188. }
  189. #endregion
  190. #region 私有方法
  191. /// <summary>
  192. /// 初始化绘图画面
  193. /// </summary>
  194. /// <param name="g">绘图画面</param>
  195. private void InitGraphics(Graphics g)
  196. {
  197. g.CompositingMode = this.m_CompositingMode;
  198. g.CompositingQuality = this.m_CompositingQuality;
  199. g.InterpolationMode = this.m_InterpolationMode;
  200. g.PixelOffsetMode = this.m_PixelOffsetMode;
  201. g.SmoothingMode = this.m_SmoothingMode;
  202. g.TextContrast = this.m_TextContrast;
  203. g.TextRenderingHint = this.m_TextRenderingHint;
  204. }
  205. #endregion
  206. #region 公共方法
  207. /// <summary>
  208. /// 开始渲染
  209. /// </summary>
  210. /// <returns>成功返回true,否则返回false</returns>
  211. public bool Prepare()
  212. {
  213. //检查资源
  214. this.CheckDisposed();
  215. //检查资源
  216. this.m_Owner.CheckDisposed();
  217. //判断句柄
  218. if (!this.m_Owner.IsHandleCreated)
  219. return false;
  220. //判断可见
  221. if (!this.m_Owner.Visible)
  222. return false;
  223. //判断大小
  224. Size wndSize = this.m_Owner.Size;
  225. if (wndSize.Width <= 0 || (wndSize.Height <= 0))
  226. return false;
  227. //已创建
  228. Size bufferSize = this.m_Size;
  229. if (this.m_BufferedGraphics != null
  230. && bufferSize.Width >= wndSize.Width && bufferSize.Width <= wndSize.Width + PRE_ALLOC
  231. && bufferSize.Height >= wndSize.Height && bufferSize.Height <= wndSize.Height + PRE_ALLOC)
  232. return true;
  233. //预分配
  234. if (bufferSize.Width < wndSize.Width)
  235. wndSize.Width += PRE_ALLOC;
  236. if (bufferSize.Height < wndSize.Height)
  237. wndSize.Height += PRE_ALLOC;
  238. //设置状态
  239. if (this.m_IsCreating)
  240. return false;
  241. this.m_IsCreating = true;
  242. //缓冲上下文
  243. BufferedGraphicsContext bufferedGraphicsContext = BufferedGraphicsManager.Current;
  244. bufferedGraphicsContext.MaximumBuffer = wndSize;
  245. //执行创建
  246. if (this.m_OwnerGraphics == null)
  247. this.m_OwnerGraphics = this.m_Owner.CreateGraphics();
  248. if (this.m_BufferedGraphics != null)
  249. this.m_BufferedGraphics.Dispose();
  250. this.m_BufferedGraphics = bufferedGraphicsContext.Allocate(this.m_OwnerGraphics, new Rectangle(0, 0, wndSize.Width, wndSize.Height));
  251. //初始化绘图对象
  252. this.InitGraphics(this.m_BufferedGraphics.Graphics);
  253. this.m_Size = wndSize;
  254. //不创建
  255. this.m_IsCreating = false;
  256. return true;
  257. }
  258. /// <summary>
  259. /// 在目标设备上混合渲染
  260. /// </summary>
  261. /// <param name="g">目标设备渲染数据</param>
  262. public void BlendRender(Graphics g)
  263. {
  264. BufferedGraphicsEx.BlendRender(this.m_BufferedGraphics, g);
  265. }
  266. /// <summary>
  267. /// 在目标设备上混合渲染
  268. /// </summary>
  269. /// <param name="e">目标设备渲染数据</param>
  270. public void BlendRender(PaintEventArgs e)
  271. {
  272. BufferedGraphicsEx.BlendRender(this.m_BufferedGraphics, e.Graphics, e.ClipRectangle);
  273. }
  274. /// <summary>
  275. /// 在目标设备上复制渲染
  276. /// </summary>
  277. /// <param name="g">目标设备渲染数据</param>
  278. public void Render(Graphics g)
  279. {
  280. this.m_BufferedGraphics.Render(g);
  281. }
  282. /// <summary>
  283. /// 在目标设备上复制渲染
  284. /// </summary>
  285. /// <param name="e">目标设备渲染数据</param>
  286. public void Render(PaintEventArgs e)
  287. {
  288. BufferedGraphicsEx.Render(this.m_BufferedGraphics, e.Graphics, e.ClipRectangle);
  289. }
  290. #endregion
  291. #region 释放资源
  292. /// <summary>
  293. /// 释放资源
  294. /// </summary>
  295. /// <param name="disposing">释放托管资源为true,否则为false</param>
  296. protected override void Dispose(bool disposing)
  297. {
  298. if (this.m_BufferedGraphics != null)
  299. {
  300. this.m_BufferedGraphics.Dispose();
  301. this.m_BufferedGraphics = null;
  302. }
  303. if (this.m_OwnerGraphics != null)
  304. {
  305. this.m_OwnerGraphics.Dispose();
  306. this.m_OwnerGraphics = null;
  307. }
  308. this.m_Owner = null;//取消引用
  309. }
  310. #endregion
  311. }
  312. }