Exemple #1
0
        private void MergeTiles(FileInfo targetFile, XkcdTile topLeftTile, XkcdTile topRightTile, XkcdTile bottomLeftTile, XkcdTile bottomRightTile)
        {
            if (topLeftTile != null ||
                topRightTile != null ||
                bottomLeftTile != null ||
                bottomRightTile != null)
            {
                Func <XkcdTile, Image> TileToImage = tile => new Image {
                    Source = XkcdTile.ToImageSource(tile)
                };

                var grid = new UniformGrid {
                    Rows = 2, Columns = 2
                };
                grid.Children.Add(TileToImage(topLeftTile));
                grid.Children.Add(TileToImage(topRightTile));
                grid.Children.Add(TileToImage(bottomLeftTile));
                grid.Children.Add(TileToImage(bottomRightTile));

                var viewBox = new Viewbox();
                viewBox.Child = grid;

                viewBox.Measure(new System.Windows.Size(XkcdTile.Width, XkcdTile.Height));
                viewBox.Arrange(new Rect(new System.Windows.Size(XkcdTile.Width, XkcdTile.Height)));

                var renderTarget = new RenderTargetBitmap(XkcdTile.Width, XkcdTile.Height, 96, 96, PixelFormats.Default);
                renderTarget.Render(viewBox);

                var frame   = BitmapFrame.Create(renderTarget);
                var encoder = new PngBitmapEncoder {
                    Frames = new[] { frame }
                };

                using (var fileStream = targetFile.Create())
                {
                    encoder.Save(fileStream);
                }
            }
        }
        private void Refresh()
        {
            if (!_refreshing)
            {
                _refreshing = true;
                var tileMap = this.TileMap;

                var width  = (int)this.ActualWidth;
                var height = (int)this.ActualWidth;

                var maxTop = tileMap.NbVertical * XkcdTile.Height - height;
                if (this.Top < 0)
                {
                    this.SetCurrentValue(XkcdMapControl.TopProperty, 0);
                }
                if (this.Top > maxTop)
                {
                    this.SetCurrentValue(XkcdMapControl.TopProperty, maxTop);
                }

                var maxLeft = tileMap.NbHorizontal * XkcdTile.Width - width;
                if (this.Left < 0)
                {
                    this.SetCurrentValue(XkcdMapControl.LeftProperty, 0);
                }
                if (this.Left > maxLeft)
                {
                    this.SetCurrentValue(XkcdMapControl.LeftProperty, maxLeft);
                }

                var top  = this.Top;
                var left = this.Left;

                var yMin = top / XkcdTile.Height;
                var yMax = (top + height) / XkcdTile.Height;
                var xMin = left / XkcdTile.Width;
                var xMax = (left + width) / XkcdTile.Width;

                var points = (from x in Enumerable.Range(xMin, xMax - xMin + 1)
                              from y in Enumerable.Range(yMin, yMax - yMin + 1)
                              select new Point(x, y)).ToArray();

                var reusedImages = (from point in points
                                    select tileMap.GetTile(point) into tile
                                    where tile != null
                                    join image in _imageCouples on tile equals image.Tile
                                    select image).ToList();

                var freeImages = new Queue <TileImageCouple>(_imageCouples.Except(reusedImages));


                foreach (var point in points)
                {
                    var tile = tileMap.GetTile(point);
                    if (tile != null)
                    {
                        TileImageCouple imageCouple = reusedImages.FirstOrDefault(tic => tic.Tile == tile);
                        if (imageCouple == null)
                        {
                            imageCouple              = freeImages.Dequeue();
                            imageCouple.Tile         = tile;
                            imageCouple.Image.Source = XkcdTile.ToImageSource(tile);
                        }

                        Canvas.SetTop(imageCouple.Image, point.Y * XkcdTile.Height - top);
                        Canvas.SetLeft(imageCouple.Image, point.X * XkcdTile.Width - left);

                        imageCouple.Image.Visibility = Visibility.Visible;

                        var curIndex = _imageCouples.IndexOf(imageCouple);
                        _imageCouples[curIndex] = _imageCouples[0];
                        _imageCouples[0]        = imageCouple;
                    }
                }

                foreach (var couple in freeImages)
                {
                    couple.Image.Visibility = Visibility.Collapsed;
                }

                _refreshing = false;
            }
        }