public void Render(ICanvas canvas, int width, int height, IPixelMapper pixelMapper) { if (pixelMapper.CellSize != _lastCellSize) { _imageCache.Clear(); _lastCellSize = pixelMapper.CellSize; } foreach (T entity in _layout) { var renderer = _renderers.FirstOrDefault(r => r.ShouldRender(entity)); if (renderer is null) { // TODO: Fill with Red to indicate error? continue; } (int x, int y, bool onScreen) = pixelMapper.CoordsToViewPortPixels(entity.Column, entity.Row); if (!onScreen) { continue; } string key = $"{entity.GetType().Name}.{entity.Identifier}"; if (_imageCache.IsDirty(key)) { using IImageCanvas imageCanvas = _imageFactory.CreateImageCanvas(pixelMapper.CellSize, pixelMapper.CellSize); float scale = pixelMapper.CellSize / 100.0f; imageCanvas.Canvas.Scale(scale, scale); renderer.Render(imageCanvas.Canvas, entity); _imageCache.Set(key, imageCanvas.Render()); } using (canvas.Scope()) { canvas.Translate(x, y); canvas.ClipRect(new Rectangle(0, 0, pixelMapper.CellSize, pixelMapper.CellSize), false, false); canvas.DrawImage(_imageCache.Get(key) !, 0, 0); } } }
public void SetSize(int width, int height) { _screenWidth = width; _screenHeight = height; _imageCache.SetDirtyAll(_screens); (int columns, int rows) = _pixelMapper.ViewPortPixelsToCoords(width, height); columns = Math.Max(columns, 1); rows = Math.Max(rows, 1); (width, height, _) = _pixelMapper.CoordsToViewPortPixels(columns + 1, rows + 1); if (_width != width || _height != height) { _width = width; _height = height; _pixelMapper.SetViewPortSize(_width, _height); // strictly speaking this only needs to clear renderers, but we already cleared screens // so its easier just to call clear _imageCache.Clear(); } }