123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223 |
- using System;
- using System.Drawing;
- namespace PaintDotNet
- {
- /// <summary>
- /// Encapsulates the arguments passed to a Render function.
- /// This way we can do on-demand and once-only creation of Bitmap and Graphics
- /// objects from a given Surface object.
- /// </summary>
- /// <remarks>
- /// Use of the Bitmap and Graphics objects is not thread safe because of how GDI+ works.
- /// You must wrap use of these objects with a critical section, like so:
- /// object lockObject = new object();
- /// lock (lockObject)
- /// {
- /// Graphics g = ra.Graphics;
- /// g.DrawRectangle(...);
- /// // etc.
- /// }
- /// </remarks>
- public sealed class RenderArgs
- : IDisposable
- {
- private Surface surface;
- private Bitmap bitmap;
- private Graphics graphics;
- private bool disposed = false;
- /// <summary>
- /// Gets the Surface that has been associated with this instance of RenderArgs.
- /// </summary>
- public Surface Surface
- {
- get
- {
- if (this.disposed)
- {
- throw new ObjectDisposedException("RenderArgs");
- }
- return this.surface;
- }
- }
- /// <summary>
- /// Gets a Bitmap reference that aliases the Surface.
- /// </summary>
- public Bitmap Bitmap
- {
- get
- {
- if (this.disposed)
- {
- throw new ObjectDisposedException("RenderArgs");
- }
- if (this.bitmap == null)
- {
- this.bitmap = surface.CreateAliasedBitmap();
- }
- return this.bitmap;
- }
- }
- /// <summary>
- /// Retrieves a Graphics instance that can be used to draw on to the Surface.
- /// </summary>
- /// <remarks>
- /// Use of this object is not thread-safe. You must wrap retrieval and consumption of this
- /// property with a critical section.
- /// </remarks>
- public Graphics Graphics
- {
- get
- {
- if (this.disposed)
- {
- throw new ObjectDisposedException("RenderArgs");
- }
- if (this.graphics == null)
- {
- this.graphics = Graphics.FromImage(Bitmap);
- }
- return this.graphics;
- }
- }
- /// <summary>
- /// Gets the size of the associated Surface object.
- /// </summary>
- /// <remarks>
- /// This is a convenience method equivalent to using RenderArgs.Surface.Bounds.
- /// </remarks>
- public Rectangle Bounds
- {
- get
- {
- if (this.disposed)
- {
- throw new ObjectDisposedException("RenderArgs");
- }
- return this.Surface.Bounds;
- }
- }
- /// <summary>
- /// Gets the size of the associated Surface object.
- /// </summary>
- /// <remarks>
- /// This is a convenient method equivalent to using RenderArgs.Surface.Size.
- /// </remarks>
- public Size Size
- {
- get
- {
- if (this.disposed)
- {
- throw new ObjectDisposedException("RenderArgs");
- }
- return this.Surface.Size;
- }
- }
- /// <summary>
- /// Gets the width of the associated Surface object.
- /// </summary>
- /// <remarks>
- /// This is a convenience method equivalent to using RenderArgs.Surface.Width.
- /// </remarks>
- public int Width
- {
- get
- {
- if (this.disposed)
- {
- throw new ObjectDisposedException("RenderArgs");
- }
- return this.surface.Width;
- }
- }
- /// <summary>
- /// Gets the height of the associated Surface object.
- /// </summary>
- /// <remarks>
- /// This is a convenience method equivalent to using RenderArgs.Surface.Height.
- /// </remarks>
- public int Height
- {
- get
- {
- if (this.disposed)
- {
- throw new ObjectDisposedException("RenderArgs");
- }
- return this.surface.Height;
- }
- }
- /// <summary>
- /// Creates an instance of the RenderArgs class.
- /// </summary>
- /// <param name="surface">
- /// The Surface to associate with this instance. This instance of RenderArgs does not
- /// take ownership of this Surface.
- /// </param>
- public RenderArgs(Surface surface)
- {
- this.surface = surface;
- this.bitmap = null;
- this.graphics = null;
- }
- ~RenderArgs()
- {
- Dispose(false);
- }
- /// <summary>
- /// Disposes of the contained Bitmap and Graphics instances, if necessary.
- /// </summary>
- /// <remarks>
- /// Note that since this class does not take ownership of the Surface, it
- /// is not disposed.
- /// </remarks>
- public void Dispose()
- {
- Dispose(true);
- GC.SuppressFinalize(this);
- }
- private void Dispose(bool disposing)
- {
- if (!this.disposed)
- {
- this.disposed = true;
- if (disposing)
- {
- if (this.graphics != null)
- {
- this.graphics.Dispose();
- this.graphics = null;
- }
- if (this.bitmap != null)
- {
- this.bitmap.Dispose();
- this.bitmap = null;
- }
- }
- }
- }
- }
- }
|