Пример #1
0
        private static void LockToGrid(CanvasPixelPosition canvasOffset, [NotNull] TileCanvas target, ref double x, ref double y)
        {
            if (canvasOffset == null)
            {
                return;
            }

            var scale = 1.0 / target.CurrentZoom();
            var grid  = TileCanvas.GridSize * scale;

            var bias = (3 * grid) / 5.0;

            x  = Math.Round((x + bias) / grid) * grid;
            x -= (canvasOffset.X * scale) % grid;

            y  = Math.Round((y + bias) / grid) * grid;
            y -= (canvasOffset.Y * scale) % grid;
        }
Пример #2
0
        private void DryWaitingStroke([NotNull] TileCanvas tileCanvas)
        {
            // Try to get a waiting stroke (peek, so we can draw the waiting stroke)
            DPoint[][] waitingStrokes;
            lock (_dryLock)
            {
                waitingStrokes = _dryingInk.ToArray();
                _dryingInk.Clear();
                if (waitingStrokes != null)
                {
                    _renderingInk.UnionWith(waitingStrokes);
                }
            }

            tileCanvas.Invalidate(); // show progress if the render is slow.
            _renderTarget.Invalidate();

            if (waitingStrokes == null)
            {
                return;
            }
            foreach (var strokeToRender in waitingStrokes)
            {
                if (strokeToRender.Length < 1)
                {
                    continue;
                }

                // Figure out what part of the screen is covered
                var clipRegion  = MeasureDrawing(strokeToRender, tileCanvas.CurrentZoom());
                var pixelWidth  = (int)clipRegion.Width;
                var pixelHeight = (int)clipRegion.Height;

                // draw to an image
                byte[] bytes;
                using (var offscreen = new CanvasRenderTarget(CanvasDevice.GetSharedDevice(), pixelWidth, pixelHeight, 96,
                                                              DirectXPixelFormat.B8G8R8A8UIntNormalized, CanvasAlphaMode.Premultiplied))
                {
                    using (var ds = offscreen.CreateDrawingSession())
                    {
                        ds?.Clear(Colors.Transparent);
                        DrawToSession(ds, strokeToRender, clipRegion, tileCanvas.CurrentZoom());
                    }

                    bytes = offscreen.GetPixelBytes();
                }

                // render into tile cache
                var uncropped = new RawImageInterleaved_UInt8
                {
                    Data   = bytes,
                    Width  = pixelWidth,
                    Height = pixelHeight
                };

                var visualWidth  = (int)Math.Ceiling(pixelWidth / tileCanvas.CurrentZoom());
                var visualHeight = (int)Math.Ceiling(pixelHeight / tileCanvas.CurrentZoom());
                var visualTop    = (int)Math.Floor(clipRegion.Y + 0.5);
                var visualLeft   = (int)Math.Floor(clipRegion.X + 0.5);
                var visualRight  = visualLeft + visualWidth;
                var visualBottom = visualTop + visualHeight;

                ThreadPool.QueueUserWorkItem(canv =>
                {
                    var ok = tileCanvas.ImportBytesScaled(uncropped, visualLeft, visualTop, visualRight, visualBottom);
                    if (!ok)
                    {
                        Logging.WriteLogMessage("Tile byte import failed when drawing strokes");
                    }
                    lock (_dryLock)
                    {
                        _renderingInk.Remove(strokeToRender);
                    }
                    tileCanvas.Invalidate(); // show finished strokes
                    _renderTarget.Invalidate();
                });
            }
        }