Exemplo n.º 1
0
        public void Render(RenderOpts opts)
        {
            _graphics.Clear(BgColor);
            DrawGrid();
            DrawSiliconAndMetal(opts);

            if (opts.SelectionState != SelectionState.None)
            {
                DrawSelectionBorder(opts.Selection);
            }
        }
Exemplo n.º 2
0
        private void DrawSiliconAndMetal(RenderOpts opts)
        {
            var namedCells = new List <ILayerCell>();

            var(from, to) = opts.Selection?.ToFieldPositions() ?? default((Position, Position));

            for (var i = 0; i < _layer.Height; i++)
            {
                for (var j = 0; j < _layer.Width; j++)
                {
                    if (opts.SelectionState != SelectionState.None)
                    {
                        var isInXRange = j >= from.X && j < to.X;
                        var isInYRange = i >= from.Y && i < to.Y;

                        if (!isInXRange || !isInYRange)
                        {
                            DrawCell(opts, i, j, from, to, namedCells);
                        }
                    }
                    else
                    {
                        DrawCell(opts, i, j, from, to, namedCells);
                    }
                }
            }

            // dragging cells should be rendered over
            if (opts.SelectionState != SelectionState.None)
            {
                for (var i = from.Y; i < to.Y; i++)
                {
                    for (var j = from.X; j < to.X; j++)
                    {
                        DrawCell(opts, i, j, from, to, namedCells);
                    }
                }
            }

            foreach (var zone in _layer.Template.DeadZones)
            {
                var zoneRect = new Rectangle(
                    zone.Origin.X * (CellSize + 1),
                    zone.Origin.Y * (CellSize + 1),
                    zone.Width * (CellSize + 1) + 1,
                    zone.Height * (CellSize + 1) + 1);

                _graphics.FillRectangle(LockedRegionBrush, zoneRect);
            }

            foreach (var cell in namedCells)
            {
                var pin = cell.Pin;

                var bounds = GetCellBounds(cell.Column, cell.Row);
                bounds.Width  += CellSize * (pin.Width - 1);
                bounds.Height += CellSize * (pin.Height - 1);
                bounds.X      += 1;
                bounds.Y      += 1;
                var centerX = bounds.Left + bounds.Width / 2;
                var centerY = bounds.Top + bounds.Height / 2;
                _graphics.FillRectangle(Brushes.WhiteSmoke, bounds);
                var name    = cell.Pin?.Name ?? "XZ";
                var measure = _graphics.MeasureString(name, PinNameFont);

                if (opts.Assignments != null)
                {
                    var assignments = opts.Assignments[cell.Row, cell.Column];
                    if ((assignments.LastAssignedSiliconNode == opts.HoveredNode ||
                         assignments.LastAssignedMetalNode == opts.HoveredNode) && opts.HoveredNode != null)
                    {
                        var fillBounds = bounds;
                        fillBounds.Inflate(-1, -1);
                        FillTopologyPlace(fillBounds, assignments.LastAssignedMetalNode == opts.HoveredNode);
                    }
                }

                _graphics.DrawString(name, PinNameFont, Brushes.Black, centerX - measure.Width / 2,
                                     centerY - measure.Height / 2);
            }
        }
Exemplo n.º 3
0
        private void DrawCell(RenderOpts opts, int i, int j, Position from, Position to, List <ILayerCell> namedCells)
        {
            var cell   = _layer.Cells[i, j];
            var bounds = GetCellBounds(j, i);

            var isInXRange = j >= from.X && j < to.X;
            var isInYRange = i >= from.Y && i < to.Y;

            if (isInXRange && isInYRange)
            {
                bounds.Offset(opts.Selection.DragOffsetX, opts.Selection.DragOffsetY);
            }

            var isLeftSideDetached   = (j == to.X || j == from.X) && isInYRange;
            var isTopSideDetached    = (i == to.Y || i == from.Y) && isInXRange;
            var isRightSideDetached  = (j == to.X - 1 || j == from.X - 1) && isInYRange;
            var isBottomSideDetached = (i == to.Y - 1 || i == from.Y - 1) && isInXRange;

            if (cell.HasSilicon())
            {
                var(_, brush, gateBrush) = SelectSiliconBrush(cell);
                FillMid(cell.HasGate() ? gateBrush : brush, bounds);
                SiliconCellSide(cell, Side.Top, bounds, isTopSideDetached);
                SiliconCellSide(cell, Side.Bottom, bounds, isBottomSideDetached);
                SiliconCellSide(cell, Side.Left, bounds, isLeftSideDetached);
                SiliconCellSide(cell, Side.Right, bounds, isRightSideDetached);

                SiliconCellCorner(cell, Corner.Near, bounds, isTopSideDetached, isLeftSideDetached);
                SiliconCellCorner(cell, Corner.FarX, bounds, isTopSideDetached, isRightSideDetached);
                SiliconCellCorner(cell, Corner.FarY, bounds, isBottomSideDetached, isLeftSideDetached);
                SiliconCellCorner(cell, Corner.Far, bounds, isBottomSideDetached, isRightSideDetached);

                if (!isLeftSideDetached)
                {
                    SiliconIntercellular(cell, false, cell.Links[0]?.SiliconLink ?? SiliconLink.None, bounds);
                }
                if (!isTopSideDetached)
                {
                    SiliconIntercellular(cell, true, cell.Links[1]?.SiliconLink ?? SiliconLink.None, bounds);
                }

                if (cell.HasVia()) // in original game vias displaying under metal layer
                {
                    var viaX = bounds.X + (bounds.Width - ViaSize) / 2;
                    var viaY = bounds.Y + (bounds.Height - ViaSize) / 2;

                    _graphics.DrawLine(BorderPen, viaX + 1, viaY, viaX + ViaSize - 2, viaY);
                    _graphics.DrawLine(BorderPen, viaX + 1, viaY + ViaSize - 1, viaX + ViaSize - 2,
                                       viaY + ViaSize - 1);
                    _graphics.DrawLine(BorderPen, viaX, viaY + 1, viaX, viaY + ViaSize - 2);
                    _graphics.DrawLine(BorderPen, viaX + ViaSize - 1, viaY + 1, viaX + ViaSize - 1,
                                       viaY + ViaSize - 2);
                }
            }

            if (cell.HasMetal)
            {
                FillMid(MetalBrush, bounds);

                MetalCellSide(cell, Side.Top, bounds, isTopSideDetached);
                MetalCellSide(cell, Side.Bottom, bounds, isBottomSideDetached);
                MetalCellSide(cell, Side.Left, bounds, isLeftSideDetached);
                MetalCellSide(cell, Side.Right, bounds, isRightSideDetached);

                MetalCellCorner(cell, Corner.Near, bounds, isTopSideDetached, isLeftSideDetached);
                MetalCellCorner(cell, Corner.FarX, bounds, isTopSideDetached, isRightSideDetached);
                MetalCellCorner(cell, Corner.FarY, bounds, isBottomSideDetached, isLeftSideDetached);
                MetalCellCorner(cell, Corner.Far, bounds, isBottomSideDetached, isRightSideDetached);

                if (!isLeftSideDetached)
                {
                    MetalIntercellular(cell, false, bounds);
                }
                if (!isTopSideDetached)
                {
                    MetalIntercellular(cell, true, bounds);
                }
            }
            if (opts.Assignments != null)
            {
                var assignments = opts.Assignments[i, j];
                if ((assignments.LastAssignedSiliconNode == opts.HoveredNode ||
                     assignments.LastAssignedMetalNode == opts.HoveredNode) && opts.HoveredNode != null)
                {
                    var fillBounds = bounds;
                    fillBounds.Inflate(-1, -1);
                    FillTopologyPlace(fillBounds, assignments.LastAssignedMetalNode == opts.HoveredNode);
                }
            }

            if (cell.Pin != null)
            {
                namedCells.Add(cell);
            }
        }