External/OxyPlot/OxyPlot.WindowsForms/GraphicsRenderContext.cs
author StephaneLenclud
Sun, 03 Feb 2013 18:01:50 +0100
branchMiniDisplay
changeset 433 090259cfd699
permissions -rw-r--r--
Adding SoundGraphDisplay and SensorFrontView classes.
They were respectively based on SystemTray and SensorNotifyIcon.
SoundGraphDisplay is now able to load iMONDisplay.dll providing it lives on your PATH.
Adding option to sensor context menu for adding it into FrontView.
moel@391
     1
// --------------------------------------------------------------------------------------------------------------------
moel@391
     2
// <copyright file="GraphicsRenderContext.cs" company="OxyPlot">
moel@391
     3
//   The MIT License (MIT)
moel@391
     4
//
moel@391
     5
//   Copyright (c) 2012 Oystein Bjorke
moel@391
     6
//
moel@391
     7
//   Permission is hereby granted, free of charge, to any person obtaining a
moel@391
     8
//   copy of this software and associated documentation files (the
moel@391
     9
//   "Software"), to deal in the Software without restriction, including
moel@391
    10
//   without limitation the rights to use, copy, modify, merge, publish,
moel@391
    11
//   distribute, sublicense, and/or sell copies of the Software, and to
moel@391
    12
//   permit persons to whom the Software is furnished to do so, subject to
moel@391
    13
//   the following conditions:
moel@391
    14
//
moel@391
    15
//   The above copyright notice and this permission notice shall be included
moel@391
    16
//   in all copies or substantial portions of the Software.
moel@391
    17
//
moel@391
    18
//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
moel@391
    19
//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
moel@391
    20
//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
moel@391
    21
//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
moel@391
    22
//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
moel@391
    23
//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
moel@391
    24
//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
moel@391
    25
// </copyright>
moel@391
    26
// <summary>
moel@391
    27
//   The graphics render context.
moel@391
    28
// </summary>
moel@391
    29
// --------------------------------------------------------------------------------------------------------------------
moel@391
    30
namespace OxyPlot.WindowsForms
moel@391
    31
{
moel@391
    32
    using System;
moel@391
    33
    using System.Collections.Generic;
moel@391
    34
    using System.Drawing;
moel@391
    35
    using System.Drawing.Drawing2D;
moel@391
    36
    using System.Drawing.Imaging;
moel@391
    37
    using System.IO;
moel@391
    38
    using System.Linq;
moel@391
    39
moel@391
    40
    using OxyPlot;
moel@391
    41
moel@391
    42
    /// <summary>
moel@391
    43
    /// The graphics render context.
moel@391
    44
    /// </summary>
moel@391
    45
    internal class GraphicsRenderContext : RenderContextBase
moel@391
    46
    {
moel@391
    47
        /// <summary>
moel@391
    48
        /// The font size factor.
moel@391
    49
        /// </summary>
moel@391
    50
        private const float FontsizeFactor = 0.8f;
moel@391
    51
moel@391
    52
        /// <summary>
moel@391
    53
        /// The GDI+ drawing surface.
moel@391
    54
        /// </summary>
moel@391
    55
        private Graphics g;
moel@391
    56
moel@391
    57
        /// <summary>
moel@391
    58
        /// Initializes a new instance of the <see cref="GraphicsRenderContext"/> class.
moel@391
    59
        /// </summary>
moel@391
    60
        public GraphicsRenderContext()
moel@391
    61
        {
moel@391
    62
        }
moel@391
    63
moel@391
    64
        /// <summary>
moel@391
    65
        /// Sets the graphics target.
moel@391
    66
        /// </summary>
moel@391
    67
        /// <param name="graphics">The graphics surface.</param>
moel@391
    68
        public void SetGraphicsTarget(Graphics graphics)
moel@391
    69
        {
moel@391
    70
            this.g = graphics;
moel@391
    71
        }
moel@391
    72
moel@391
    73
        /// <summary>
moel@391
    74
        /// Draws the ellipse.
moel@391
    75
        /// </summary>
moel@391
    76
        /// <param name="rect">The rect.</param>
moel@391
    77
        /// <param name="fill">The fill.</param>
moel@391
    78
        /// <param name="stroke">The stroke.</param>
moel@391
    79
        /// <param name="thickness">The thickness.</param>
moel@391
    80
        public override void DrawEllipse(OxyRect rect, OxyColor fill, OxyColor stroke, double thickness)
moel@391
    81
        {
moel@391
    82
            if (fill != null)
moel@391
    83
            {
moel@391
    84
                this.g.FillEllipse(
moel@391
    85
                    this.ToBrush(fill), (float)rect.Left, (float)rect.Top, (float)rect.Width, (float)rect.Height);
moel@391
    86
            }
moel@391
    87
moel@391
    88
            if (stroke == null || thickness <= 0)
moel@391
    89
            {
moel@391
    90
                return;
moel@391
    91
            }
moel@391
    92
moel@391
    93
            using (var pen = new Pen(this.ToColor(stroke), (float)thickness))
moel@391
    94
            {
moel@391
    95
                this.g.SmoothingMode = SmoothingMode.HighQuality;
moel@391
    96
                this.g.DrawEllipse(pen, (float)rect.Left, (float)rect.Top, (float)rect.Width, (float)rect.Height);
moel@391
    97
            }
moel@391
    98
        }
moel@391
    99
moel@391
   100
        /// <summary>
moel@391
   101
        /// Draws the line.
moel@391
   102
        /// </summary>
moel@391
   103
        /// <param name="points">The points.</param>
moel@391
   104
        /// <param name="stroke">The stroke.</param>
moel@391
   105
        /// <param name="thickness">The thickness.</param>
moel@391
   106
        /// <param name="dashArray">The dash array.</param>
moel@391
   107
        /// <param name="lineJoin">The line join.</param>
moel@391
   108
        /// <param name="aliased">if set to <c>true</c> [aliased].</param>
moel@391
   109
        public override void DrawLine(
moel@391
   110
            IList<ScreenPoint> points,
moel@391
   111
            OxyColor stroke,
moel@391
   112
            double thickness,
moel@391
   113
            double[] dashArray,
moel@391
   114
            OxyPenLineJoin lineJoin,
moel@391
   115
            bool aliased)
moel@391
   116
        {
moel@391
   117
            if (stroke == null || thickness <= 0 || points.Count < 2)
moel@391
   118
            {
moel@391
   119
                return;
moel@391
   120
            }
moel@391
   121
moel@391
   122
            this.g.SmoothingMode = aliased ? SmoothingMode.None : SmoothingMode.HighQuality;
moel@391
   123
            using (var pen = new Pen(this.ToColor(stroke), (float)thickness))
moel@391
   124
            {
moel@391
   125
moel@391
   126
                if (dashArray != null)
moel@391
   127
                {
moel@391
   128
                    pen.DashPattern = this.ToFloatArray(dashArray);
moel@391
   129
                }
moel@391
   130
moel@391
   131
                switch (lineJoin)
moel@391
   132
                {
moel@391
   133
                    case OxyPenLineJoin.Round:
moel@391
   134
                        pen.LineJoin = LineJoin.Round;
moel@391
   135
                        break;
moel@391
   136
                    case OxyPenLineJoin.Bevel:
moel@391
   137
                        pen.LineJoin = LineJoin.Bevel;
moel@391
   138
                        break;
moel@391
   139
moel@391
   140
                    // The default LineJoin is Miter
moel@391
   141
                }
moel@391
   142
moel@391
   143
                this.g.DrawLines(pen, this.ToPoints(points));
moel@391
   144
            }
moel@391
   145
        }
moel@391
   146
moel@391
   147
        /// <summary>
moel@391
   148
        /// Draws the polygon.
moel@391
   149
        /// </summary>
moel@391
   150
        /// <param name="points">The points.</param>
moel@391
   151
        /// <param name="fill">The fill.</param>
moel@391
   152
        /// <param name="stroke">The stroke.</param>
moel@391
   153
        /// <param name="thickness">The thickness.</param>
moel@391
   154
        /// <param name="dashArray">The dash array.</param>
moel@391
   155
        /// <param name="lineJoin">The line join.</param>
moel@391
   156
        /// <param name="aliased">if set to <c>true</c> [aliased].</param>
moel@391
   157
        public override void DrawPolygon(
moel@391
   158
            IList<ScreenPoint> points,
moel@391
   159
            OxyColor fill,
moel@391
   160
            OxyColor stroke,
moel@391
   161
            double thickness,
moel@391
   162
            double[] dashArray,
moel@391
   163
            OxyPenLineJoin lineJoin,
moel@391
   164
            bool aliased)
moel@391
   165
        {
moel@391
   166
            if (points.Count < 2)
moel@391
   167
            {
moel@391
   168
                return;
moel@391
   169
            }
moel@391
   170
moel@391
   171
            this.g.SmoothingMode = aliased ? SmoothingMode.None : SmoothingMode.HighQuality;
moel@391
   172
moel@391
   173
            PointF[] pts = this.ToPoints(points);
moel@391
   174
            if (fill != null)
moel@391
   175
            {
moel@391
   176
                this.g.FillPolygon(this.ToBrush(fill), pts);
moel@391
   177
            }
moel@391
   178
moel@391
   179
            if (stroke != null && thickness > 0)
moel@391
   180
            {
moel@391
   181
                using (var pen = new Pen(this.ToColor(stroke), (float)thickness))
moel@391
   182
                {
moel@391
   183
moel@391
   184
                    if (dashArray != null)
moel@391
   185
                    {
moel@391
   186
                        pen.DashPattern = this.ToFloatArray(dashArray);
moel@391
   187
                    }
moel@391
   188
moel@391
   189
                    switch (lineJoin)
moel@391
   190
                    {
moel@391
   191
                        case OxyPenLineJoin.Round:
moel@391
   192
                            pen.LineJoin = LineJoin.Round;
moel@391
   193
                            break;
moel@391
   194
                        case OxyPenLineJoin.Bevel:
moel@391
   195
                            pen.LineJoin = LineJoin.Bevel;
moel@391
   196
                            break;
moel@391
   197
moel@391
   198
                        // The default LineJoin is Miter
moel@391
   199
                    }
moel@391
   200
moel@391
   201
                    this.g.DrawPolygon(pen, pts);
moel@391
   202
                }
moel@391
   203
            }
moel@391
   204
        }
moel@391
   205
moel@391
   206
        /// <summary>
moel@391
   207
        /// The draw rectangle.
moel@391
   208
        /// </summary>
moel@391
   209
        /// <param name="rect">
moel@391
   210
        /// The rect.
moel@391
   211
        /// </param>
moel@391
   212
        /// <param name="fill">
moel@391
   213
        /// The fill.
moel@391
   214
        /// </param>
moel@391
   215
        /// <param name="stroke">
moel@391
   216
        /// The stroke.
moel@391
   217
        /// </param>
moel@391
   218
        /// <param name="thickness">
moel@391
   219
        /// The thickness.
moel@391
   220
        /// </param>
moel@391
   221
        public override void DrawRectangle(OxyRect rect, OxyColor fill, OxyColor stroke, double thickness)
moel@391
   222
        {
moel@391
   223
            if (fill != null)
moel@391
   224
            {
moel@391
   225
                this.g.FillRectangle(
moel@391
   226
                    this.ToBrush(fill), (float)rect.Left, (float)rect.Top, (float)rect.Width, (float)rect.Height);
moel@391
   227
            }
moel@391
   228
moel@391
   229
            if (stroke == null || thickness <= 0)
moel@391
   230
            {
moel@391
   231
                return;
moel@391
   232
            }
moel@391
   233
moel@391
   234
            using (var pen = new Pen(this.ToColor(stroke), (float)thickness))
moel@391
   235
            {
moel@391
   236
                this.g.DrawRectangle(pen, (float)rect.Left, (float)rect.Top, (float)rect.Width, (float)rect.Height);
moel@391
   237
            }
moel@391
   238
        }
moel@391
   239
moel@391
   240
        /// <summary>
moel@391
   241
        /// The draw text.
moel@391
   242
        /// </summary>
moel@391
   243
        /// <param name="p">
moel@391
   244
        /// The p.
moel@391
   245
        /// </param>
moel@391
   246
        /// <param name="text">
moel@391
   247
        /// The text.
moel@391
   248
        /// </param>
moel@391
   249
        /// <param name="fill">
moel@391
   250
        /// The fill.
moel@391
   251
        /// </param>
moel@391
   252
        /// <param name="fontFamily">
moel@391
   253
        /// The font family.
moel@391
   254
        /// </param>
moel@391
   255
        /// <param name="fontSize">
moel@391
   256
        /// The font size.
moel@391
   257
        /// </param>
moel@391
   258
        /// <param name="fontWeight">
moel@391
   259
        /// The font weight.
moel@391
   260
        /// </param>
moel@391
   261
        /// <param name="rotate">
moel@391
   262
        /// The rotate.
moel@391
   263
        /// </param>
moel@391
   264
        /// <param name="halign">
moel@391
   265
        /// The halign.
moel@391
   266
        /// </param>
moel@391
   267
        /// <param name="valign">
moel@391
   268
        /// The valign.
moel@391
   269
        /// </param>
moel@391
   270
        /// <param name="maxSize">
moel@391
   271
        /// The maximum size of the text.
moel@391
   272
        /// </param>
moel@391
   273
        public override void DrawText(
moel@391
   274
            ScreenPoint p,
moel@391
   275
            string text,
moel@391
   276
            OxyColor fill,
moel@391
   277
            string fontFamily,
moel@391
   278
            double fontSize,
moel@391
   279
            double fontWeight,
moel@391
   280
            double rotate,
moel@391
   281
            HorizontalAlignment halign,
moel@391
   282
            VerticalAlignment valign,
moel@391
   283
            OxySize? maxSize)
moel@391
   284
        {
moel@391
   285
            var fs = FontStyle.Regular;
moel@391
   286
            if (fontWeight >= 700)
moel@391
   287
            {
moel@391
   288
                fs = FontStyle.Bold;
moel@391
   289
            }
moel@391
   290
moel@391
   291
            using (var font = new Font(fontFamily, (float)fontSize * FontsizeFactor, fs))
moel@391
   292
            {
moel@391
   293
                using (var sf = new StringFormat { Alignment = StringAlignment.Near })
moel@391
   294
                {
moel@391
   295
                    var size = this.g.MeasureString(text, font);
moel@391
   296
                    if (maxSize != null)
moel@391
   297
                    {
moel@391
   298
                        if (size.Width > maxSize.Value.Width)
moel@391
   299
                        {
moel@391
   300
                            size.Width = (float)maxSize.Value.Width;
moel@391
   301
                        }
moel@391
   302
moel@391
   303
                        if (size.Height > maxSize.Value.Height)
moel@391
   304
                        {
moel@391
   305
                            size.Height = (float)maxSize.Value.Height;
moel@391
   306
                        }
moel@391
   307
                    }
moel@391
   308
moel@391
   309
                    float dx = 0;
moel@391
   310
                    if (halign == HorizontalAlignment.Center)
moel@391
   311
                    {
moel@391
   312
                        dx = -size.Width / 2;
moel@391
   313
                    }
moel@391
   314
moel@391
   315
                    if (halign == HorizontalAlignment.Right)
moel@391
   316
                    {
moel@391
   317
                        dx = -size.Width;
moel@391
   318
                    }
moel@391
   319
moel@391
   320
                    float dy = 0;
moel@391
   321
                    sf.LineAlignment = StringAlignment.Near;
moel@391
   322
                    if (valign == VerticalAlignment.Middle)
moel@391
   323
                    {
moel@391
   324
                        dy = -size.Height / 2;
moel@391
   325
                    }
moel@391
   326
moel@391
   327
                    if (valign == VerticalAlignment.Bottom)
moel@391
   328
                    {
moel@391
   329
                        dy = -size.Height;
moel@391
   330
                    }
moel@391
   331
moel@391
   332
                    this.g.TranslateTransform((float)p.X, (float)p.Y);
moel@391
   333
                    if (Math.Abs(rotate) > double.Epsilon)
moel@391
   334
                    {
moel@391
   335
                        this.g.RotateTransform((float)rotate);
moel@391
   336
                    }
moel@391
   337
moel@391
   338
                    this.g.TranslateTransform(dx, dy);
moel@391
   339
moel@391
   340
                    var layoutRectangle = new RectangleF(0, 0, size.Width, size.Height);
moel@391
   341
                    this.g.DrawString(text, font, this.ToBrush(fill), layoutRectangle, sf);
moel@391
   342
moel@391
   343
                    this.g.ResetTransform();
moel@391
   344
                }
moel@391
   345
            }
moel@391
   346
        }
moel@391
   347
moel@391
   348
        /// <summary>
moel@391
   349
        /// The measure text.
moel@391
   350
        /// </summary>
moel@391
   351
        /// <param name="text">The text.</param>
moel@391
   352
        /// <param name="fontFamily">The font family.</param>
moel@391
   353
        /// <param name="fontSize">The font size.</param>
moel@391
   354
        /// <param name="fontWeight">The font weight.</param>
moel@391
   355
        /// <returns>The size of the text.</returns>
moel@391
   356
        public override OxySize MeasureText(string text, string fontFamily, double fontSize, double fontWeight)
moel@391
   357
        {
moel@391
   358
            if (text == null)
moel@391
   359
            {
moel@391
   360
                return OxySize.Empty;
moel@391
   361
            }
moel@391
   362
moel@391
   363
            var fs = FontStyle.Regular;
moel@391
   364
            if (fontWeight >= 700)
moel@391
   365
            {
moel@391
   366
                fs = FontStyle.Bold;
moel@391
   367
            }
moel@391
   368
moel@391
   369
            using (var font = new Font(fontFamily, (float)fontSize * FontsizeFactor, fs))
moel@391
   370
            {
moel@391
   371
                var size = this.g.MeasureString(text, font);
moel@391
   372
                return new OxySize(size.Width, size.Height);
moel@391
   373
            }
moel@391
   374
        }
moel@391
   375
moel@391
   376
        /// <summary>
moel@391
   377
        /// Converts a fill color to a System.Drawing.Brush.
moel@391
   378
        /// </summary>
moel@391
   379
        /// <param name="fill">
moel@391
   380
        /// The fill color.
moel@391
   381
        /// </param>
moel@391
   382
        /// <returns>
moel@391
   383
        /// The brush.
moel@391
   384
        /// </returns>
moel@391
   385
        private Brush ToBrush(OxyColor fill)
moel@391
   386
        {
moel@391
   387
            if (fill != null)
moel@391
   388
            {
moel@391
   389
                return new SolidBrush(this.ToColor(fill));
moel@391
   390
            }
moel@391
   391
moel@391
   392
            return null;
moel@391
   393
        }
moel@391
   394
moel@391
   395
        /// <summary>
moel@391
   396
        /// Converts a color to a System.Drawing.Color.
moel@391
   397
        /// </summary>
moel@391
   398
        /// <param name="c">
moel@391
   399
        /// The color.
moel@391
   400
        /// </param>
moel@391
   401
        /// <returns>
moel@391
   402
        /// The System.Drawing.Color.
moel@391
   403
        /// </returns>
moel@391
   404
        private Color ToColor(OxyColor c)
moel@391
   405
        {
moel@391
   406
            return Color.FromArgb(c.A, c.R, c.G, c.B);
moel@391
   407
        }
moel@391
   408
moel@391
   409
        /// <summary>
moel@391
   410
        /// Converts a double array to a float array.
moel@391
   411
        /// </summary>
moel@391
   412
        /// <param name="a">
moel@391
   413
        /// The a.
moel@391
   414
        /// </param>
moel@391
   415
        /// <returns>
moel@391
   416
        /// The float array.
moel@391
   417
        /// </returns>
moel@391
   418
        private float[] ToFloatArray(double[] a)
moel@391
   419
        {
moel@391
   420
            if (a == null)
moel@391
   421
            {
moel@391
   422
                return null;
moel@391
   423
            }
moel@391
   424
moel@391
   425
            var r = new float[a.Length];
moel@391
   426
            for (int i = 0; i < a.Length; i++)
moel@391
   427
            {
moel@391
   428
                r[i] = (float)a[i];
moel@391
   429
            }
moel@391
   430
moel@391
   431
            return r;
moel@391
   432
        }
moel@391
   433
moel@391
   434
        /// <summary>
moel@391
   435
        /// Converts a list of point to an array of PointF.
moel@391
   436
        /// </summary>
moel@391
   437
        /// <param name="points">
moel@391
   438
        /// The points.
moel@391
   439
        /// </param>
moel@391
   440
        /// <returns>
moel@391
   441
        /// An array of points.
moel@391
   442
        /// </returns>
moel@391
   443
        private PointF[] ToPoints(IList<ScreenPoint> points)
moel@391
   444
        {
moel@391
   445
            if (points == null)
moel@391
   446
            {
moel@391
   447
                return null;
moel@391
   448
            }
moel@391
   449
moel@391
   450
            var r = new PointF[points.Count()];
moel@391
   451
            int i = 0;
moel@391
   452
            foreach (ScreenPoint p in points)
moel@391
   453
            {
moel@391
   454
                r[i++] = new PointF((float)p.X, (float)p.Y);
moel@391
   455
            }
moel@391
   456
moel@391
   457
            return r;
moel@391
   458
        }
moel@391
   459
moel@391
   460
        public override void CleanUp()
moel@391
   461
        {
moel@391
   462
            var imagesToRelease = imageCache.Keys.Where(i => !imagesInUse.Contains(i));
moel@391
   463
            foreach (var i in imagesToRelease)
moel@391
   464
            {
moel@391
   465
                var image = this.GetImage(i);
moel@391
   466
                image.Dispose();
moel@391
   467
                imageCache.Remove(i);
moel@391
   468
            }
moel@391
   469
moel@391
   470
            imagesInUse.Clear();
moel@391
   471
        }
moel@391
   472
moel@391
   473
        public override OxyImageInfo GetImageInfo(OxyImage source)
moel@391
   474
        {
moel@391
   475
            var image = this.GetImage(source);
moel@391
   476
            return image == null ? null : new OxyImageInfo { Width = (uint)image.Width, Height = (uint)image.Height, DpiX = image.HorizontalResolution, DpiY = image.VerticalResolution };
moel@391
   477
        }
moel@391
   478
moel@391
   479
        public override void DrawImage(OxyImage source, uint srcX, uint srcY, uint srcWidth, uint srcHeight, double x, double y, double w, double h, double opacity, bool interpolate)
moel@391
   480
        {
moel@391
   481
            var image = this.GetImage(source);
moel@391
   482
            if (image != null)
moel@391
   483
            {
moel@391
   484
                ImageAttributes ia = null;
moel@391
   485
                if (opacity < 1)
moel@391
   486
                {
moel@391
   487
                    var cm = new ColorMatrix
moel@391
   488
                                 {
moel@391
   489
                                     Matrix00 = 1f,
moel@391
   490
                                     Matrix11 = 1f,
moel@391
   491
                                     Matrix22 = 1f,
moel@391
   492
                                     Matrix33 = 1f,
moel@391
   493
                                     Matrix44 = (float)opacity
moel@391
   494
                                 };
moel@391
   495
moel@391
   496
                    ia = new ImageAttributes();
moel@391
   497
                    ia.SetColorMatrix(cm, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);
moel@391
   498
                }
moel@391
   499
moel@391
   500
                g.InterpolationMode = interpolate ? InterpolationMode.HighQualityBicubic : InterpolationMode.NearestNeighbor;
moel@391
   501
                int sx = (int)Math.Round(x);
moel@391
   502
                int sy = (int)Math.Round(y);
moel@391
   503
                int sw = (int)Math.Round(x + w) - sx;
moel@391
   504
                int sh = (int)Math.Round(y + h) - sy;
moel@391
   505
                g.DrawImage(image, new Rectangle(sx, sy, sw, sh), srcX, srcY, srcWidth, srcHeight, GraphicsUnit.Pixel, ia);
moel@391
   506
            }
moel@391
   507
        }
moel@391
   508
moel@391
   509
        private HashSet<OxyImage> imagesInUse = new HashSet<OxyImage>();
moel@391
   510
moel@391
   511
        private Dictionary<OxyImage, Image> imageCache = new Dictionary<OxyImage, Image>();
moel@391
   512
moel@391
   513
moel@391
   514
        private Image GetImage(OxyImage source)
moel@391
   515
        {
moel@391
   516
            if (source == null)
moel@391
   517
            {
moel@391
   518
                return null;
moel@391
   519
            }
moel@391
   520
moel@391
   521
            if (!this.imagesInUse.Contains(source))
moel@391
   522
            {
moel@391
   523
                this.imagesInUse.Add(source);
moel@391
   524
            }
moel@391
   525
moel@391
   526
            Image src;
moel@391
   527
            if (this.imageCache.TryGetValue(source, out src))
moel@391
   528
            {
moel@391
   529
                return src;
moel@391
   530
            }
moel@391
   531
moel@391
   532
            if (source != null)
moel@391
   533
            {
moel@391
   534
                Image btm;
moel@391
   535
                using (var ms = new MemoryStream(source.GetData()))
moel@391
   536
                {
moel@391
   537
                    btm = Image.FromStream(ms);
moel@391
   538
                }
moel@391
   539
moel@391
   540
                this.imageCache.Add(source, btm);
moel@391
   541
                return btm;
moel@391
   542
            }
moel@391
   543
moel@391
   544
            return null;
moel@391
   545
        }
moel@391
   546
moel@391
   547
        public override bool SetClip(OxyRect rect)
moel@391
   548
        {
moel@391
   549
            this.g.SetClip(rect.ToRect(false));
moel@391
   550
            return true;
moel@391
   551
        }
moel@391
   552
moel@391
   553
        public override void ResetClip()
moel@391
   554
        {
moel@391
   555
            this.g.ResetClip();
moel@391
   556
        }
moel@391
   557
    }
moel@391
   558
}