public static void Render(
            this DrawingContext cx,
            DrawingRenderInfo drawing)
        {
            var pop_count = 0;

            if (drawing.Transform != null)
            {
                cx.PushTransform(drawing.Transform);
                pop_count++;
            }
            if (drawing.Opacity != null)
            {
                cx.PushOpacity(drawing.Opacity.Value);
                pop_count++;
            }
            if (drawing.Clip != null)
            {
                cx.PushClip(drawing.Clip);
                pop_count++;
            }

            cx.DrawDrawing(drawing.Drawing);

            while (pop_count-- > 0)
                cx.Pop();
        }
        public WpfDrawingContextDrawCommand(Action<IPixelCanvas, DrawingContext, CancellationToken> drawAction)
        {
            this.DrawAction = drawAction;
            return;

            Processing = Task.Run(() =>
            {
                var sw = Stopwatch.StartNew();

                var dv = new DrawingVisual();
                using (var cx = dv.RenderOpen())
                {
                    Draw(null, cx, CancellationToken.None);
                }

                var dr = dv.Drawing;
                dr.Freeze();

                var di = new DrawingRenderInfo();

                di.Drawing = dr;

                sw.Stop();
                Debug.WriteLine("drawing single " + sw.Elapsed.TotalMilliseconds);

                return di;
            });
        }
        public static void Render(
            this DrawingContext cx,
            double drawingWidth,
            double drawingHeight,
            DrawingRenderInfo drawing)
        {
            // expand drawings to desired size using transparent rectangle
            var canvas = new RectangleGeometry(new Rect(0, 0, drawingWidth, drawingHeight));
            canvas.Freeze();
            cx.DrawGeometry(Brushes.Transparent, null, canvas);

            cx.Render(drawing);
        }
        public static void Render(
            this DrawingContext cx,
            int x,
            int y,
            int width,
            int height,
            Action<DrawingContext> prepareDrawingContext,
            DrawingRenderInfo drawing)
        {
            if (prepareDrawingContext != null)
                prepareDrawingContext(cx);

            cx.Render(width, height, drawing);
        }
        IEnumerable<DrawingRenderInfo> produceSquares(int count, int square_size, int canvas_size)
        {
            Random rd = new Random();

            for(int i = 0; i < count; i++)
            {
                var di = new DrawingRenderInfo();
                di.Transform = new TranslateTransform(rd.Next(0, canvas_size - square_size), rd.Next(0, canvas_size - square_size));
                di.Transform.Freeze();

                var geom = new RectangleGeometry(new Rect(0, 0, square_size, square_size));
                geom.Freeze();

                di.Drawing = new GeometryDrawing(Brushes.Red, null, geom);
                di.Drawing.Freeze();

                yield return di;
            }
        }
        public static void DrawDrawing(
            this IPixelCanvas pc,
            int x,
            int y,
            int width,
            int height,
            BlendMode blendMode,
            Action<DrawingContext> prepareDrawingContext,
            DrawingRenderInfo drawing)
        {
            var dv = new DrawingVisual();

            using (var cx = dv.RenderOpen())
            {
                if (prepareDrawingContext != null)
                    prepareDrawingContext(cx);

                cx.Render(width, height, drawing);
            }

            pc.DrawVisual(0, 0, dv, blendMode);
        }