private Cell firstLinkingCell; // premiere cellule à lier à une deuxième #endregion Fields #region Constructors // Constructeur public Circuit(DrawingArea drawingAera, Label cellCount) { cells = new List<Cell>(); ios = new List<InOut>(); color = new Colors(); this.drawingAera = drawingAera; this.cellCount = cellCount; showLayer = new bool[] {true, true}; updateStatusBarCellCount(); draw(); }
public void draw(Context grCxt, double cellWidth, Colors color) { PointD p0, p1, p2, p3; // efface la case p0 = new PointD(this.x * cellWidth, this.y * cellWidth); p1 = new PointD((this.x + 1) * cellWidth, this.y * cellWidth); p2 = new PointD((this.x + 1) * cellWidth, (this.y + 1) * cellWidth); p3 = new PointD(this.x * cellWidth, (this.y + 1) * cellWidth); grCxt.MoveTo(p0); grCxt.LineTo(p1); grCxt.LineTo(p2); grCxt.LineTo(p3); grCxt.ClosePath(); grCxt.Color = color.find("background"); grCxt.Fill(); p0 = new PointD(this.x * cellWidth + 1, (this.y + 1) * cellWidth); p1 = new PointD(this.x * cellWidth + 1, this.y * cellWidth + 1); p2 = new PointD((this.x + 1) * cellWidth, this.y * cellWidth + 1); grCxt.MoveTo(p0); grCxt.LineTo(p1); grCxt.LineTo(p2); grCxt.Color = color.find("grid"); grCxt.Stroke(); // couche SILICON_N if (circuit.showLayer[(int)Circuit.showLayerType.S]) { if (layers[(int)LayerType.SILICON_N].isSet) { grCxt.MoveTo(new PointD(this.x * cellWidth + mgW, this.y * cellWidth + mgN)); if (layers[(int)LayerType.SILICON_N].links[(int)CellLayer.Cardinals.N] != null || layers[(int)LayerType.PNP].links[(int)CellLayer.Cardinals.N] != null) { grCxt.LineTo(new PointD(this.x * cellWidth + mgW, this.y * cellWidth)); grCxt.LineTo(new PointD((this.x + 1) * cellWidth - mgE, this.y * cellWidth)); } grCxt.LineTo(new PointD((this.x + 1) * cellWidth - mgE, this.y * cellWidth + mgN)); if (layers[(int)LayerType.SILICON_N].links[(int)CellLayer.Cardinals.E] != null || layers[(int)LayerType.PNP].links[(int)CellLayer.Cardinals.E] != null) { grCxt.LineTo(new PointD((this.x + 1) * cellWidth, this.y * cellWidth + mgN)); grCxt.LineTo(new PointD((this.x + 1) * cellWidth, (this.y + 1) * cellWidth - mgS)); } grCxt.LineTo(new PointD((this.x + 1) * cellWidth - mgE, (this.y + 1) * cellWidth - mgS)); if (layers[(int)LayerType.SILICON_N].links[(int)CellLayer.Cardinals.S] != null || layers[(int)LayerType.PNP].links[(int)CellLayer.Cardinals.S] != null) { grCxt.LineTo(new PointD((this.x + 1) * cellWidth - mgE, (this.y + 1) * cellWidth)); grCxt.LineTo(new PointD(this.x * cellWidth + mgW, (this.y + 1) * cellWidth)); } grCxt.LineTo(new PointD(this.x * cellWidth + mgW, (this.y + 1) * cellWidth - mgS)); if (layers[(int)LayerType.SILICON_N].links[(int)CellLayer.Cardinals.W] != null || layers[(int)LayerType.PNP].links[(int)CellLayer.Cardinals.W] != null) { grCxt.LineTo(new PointD(this.x * cellWidth, (this.y + 1) * cellWidth - mgS)); grCxt.LineTo(new PointD(this.x * cellWidth, this.y * cellWidth + mgN)); } grCxt.ClosePath(); grCxt.Color = color.find("snN_fill"); grCxt.Fill(); } } // couche SILICON_P if (circuit.showLayer[(int)Circuit.showLayerType.S]) { if (layers[(int)LayerType.SILICON_P].isSet) { grCxt.MoveTo(new PointD(this.x * cellWidth + mgW, this.y * cellWidth + mgN)); if (layers[(int)LayerType.SILICON_P].links[(int)CellLayer.Cardinals.N] != null || layers[(int)LayerType.NPN].links[(int)CellLayer.Cardinals.N] != null) { grCxt.LineTo(new PointD(this.x * cellWidth + mgW, this.y * cellWidth)); grCxt.LineTo(new PointD((this.x + 1) * cellWidth - mgE, this.y * cellWidth)); } grCxt.LineTo(new PointD((this.x + 1) * cellWidth - mgE, this.y * cellWidth + mgN)); if (layers[(int)LayerType.SILICON_P].links[(int)CellLayer.Cardinals.E] != null || layers[(int)LayerType.NPN].links[(int)CellLayer.Cardinals.E] != null) { grCxt.LineTo(new PointD((this.x + 1) * cellWidth, this.y * cellWidth + mgN)); grCxt.LineTo(new PointD((this.x + 1) * cellWidth, (this.y + 1) * cellWidth - mgS)); } grCxt.LineTo(new PointD((this.x + 1) * cellWidth - mgE, (this.y + 1) * cellWidth - mgS)); if (layers[(int)LayerType.SILICON_P].links[(int)CellLayer.Cardinals.S] != null || layers[(int)LayerType.NPN].links[(int)CellLayer.Cardinals.S] != null) { grCxt.LineTo(new PointD((this.x + 1) * cellWidth - mgE, (this.y + 1) * cellWidth)); grCxt.LineTo(new PointD(this.x * cellWidth + mgW, (this.y + 1) * cellWidth)); } grCxt.LineTo(new PointD(this.x * cellWidth + mgW, (this.y + 1) * cellWidth - mgS)); if (layers[(int)LayerType.SILICON_P].links[(int)CellLayer.Cardinals.W] != null || layers[(int)LayerType.NPN].links[(int)CellLayer.Cardinals.W] != null) { grCxt.LineTo(new PointD(this.x * cellWidth, (this.y + 1) * cellWidth - mgS)); grCxt.LineTo(new PointD(this.x * cellWidth, this.y * cellWidth + mgN)); } grCxt.ClosePath(); grCxt.Color = color.find("snP_fill"); grCxt.Fill(); } } // PNP / NPN if (circuit.showLayer[(int)Circuit.showLayerType.S]) { if (layers[(int)LayerType.PNP].isSet) { grCxt.MoveTo(new PointD(this.x * cellWidth + mgW, this.y * cellWidth + mgN)); if (layers[(int)LayerType.PNP].links[(int)CellLayer.Cardinals.N] != null) { grCxt.LineTo(new PointD(this.x * cellWidth + mgW, this.y * cellWidth)); grCxt.LineTo(new PointD((this.x + 1) * cellWidth - mgE, this.y * cellWidth)); } grCxt.LineTo(new PointD((this.x + 1) * cellWidth - mgE, this.y * cellWidth + mgN)); if (layers[(int)LayerType.PNP].links[(int)CellLayer.Cardinals.E] != null) { grCxt.LineTo(new PointD((this.x + 1) * cellWidth, this.y * cellWidth + mgN)); grCxt.LineTo(new PointD((this.x + 1) * cellWidth, (this.y + 1) * cellWidth - mgS)); } grCxt.LineTo(new PointD((this.x + 1) * cellWidth - mgE, (this.y + 1) * cellWidth - mgS)); if (layers[(int)LayerType.PNP].links[(int)CellLayer.Cardinals.S] != null) { grCxt.LineTo(new PointD((this.x + 1) * cellWidth - mgE, (this.y + 1) * cellWidth)); grCxt.LineTo(new PointD(this.x * cellWidth + mgW, (this.y + 1) * cellWidth)); } grCxt.LineTo(new PointD(this.x * cellWidth + mgW, (this.y + 1) * cellWidth - mgS)); if (layers[(int)LayerType.PNP].links[(int)CellLayer.Cardinals.W] != null) { grCxt.LineTo(new PointD(this.x * cellWidth, (this.y + 1) * cellWidth - mgS)); grCxt.LineTo(new PointD(this.x * cellWidth, this.y * cellWidth + mgN)); } grCxt.ClosePath(); grCxt.Color = color.find("gate_PNP"); grCxt.Fill(); } if (layers[(int)LayerType.NPN].isSet) { grCxt.MoveTo(new PointD(this.x * cellWidth + mgW, this.y * cellWidth + mgN)); if (layers[(int)LayerType.NPN].links[(int)CellLayer.Cardinals.N] != null) { grCxt.LineTo(new PointD(this.x * cellWidth + mgW, this.y * cellWidth)); grCxt.LineTo(new PointD((this.x + 1) * cellWidth - mgE, this.y * cellWidth)); } grCxt.LineTo(new PointD((this.x + 1) * cellWidth - mgE, this.y * cellWidth + mgN)); if (layers[(int)LayerType.NPN].links[(int)CellLayer.Cardinals.E] != null) { grCxt.LineTo(new PointD((this.x + 1) * cellWidth, this.y * cellWidth + mgN)); grCxt.LineTo(new PointD((this.x + 1) * cellWidth, (this.y + 1) * cellWidth - mgS)); } grCxt.LineTo(new PointD((this.x + 1) * cellWidth - mgE, (this.y + 1) * cellWidth - mgS)); if (layers[(int)LayerType.NPN].links[(int)CellLayer.Cardinals.S] != null) { grCxt.LineTo(new PointD((this.x + 1) * cellWidth - mgE, (this.y + 1) * cellWidth)); grCxt.LineTo(new PointD(this.x * cellWidth + mgW, (this.y + 1) * cellWidth)); } grCxt.LineTo(new PointD(this.x * cellWidth + mgW, (this.y + 1) * cellWidth - mgS)); if (layers[(int)LayerType.NPN].links[(int)CellLayer.Cardinals.W] != null) { grCxt.LineTo(new PointD(this.x * cellWidth, (this.y + 1) * cellWidth - mgS)); grCxt.LineTo(new PointD(this.x * cellWidth, this.y * cellWidth + mgN)); } grCxt.ClosePath(); grCxt.Color = color.find("gate_NPN"); grCxt.Fill(); } } // couche METAL if (circuit.showLayer[(int)Circuit.showLayerType.M]) { if (layers[(int)LayerType.METAL].isSet && !layers[(int)LayerType.IO].isSet) { grCxt.MoveTo(new PointD(this.x * cellWidth + mgW, this.y * cellWidth + mgN)); if (layers[(int)LayerType.METAL].links[(int)CellLayer.Cardinals.N] != null) { grCxt.LineTo(new PointD(this.x * cellWidth + mgW, this.y * cellWidth)); grCxt.LineTo(new PointD((this.x + 1) * cellWidth - mgE, this.y * cellWidth)); } grCxt.LineTo(new PointD((this.x + 1) * cellWidth - mgE, this.y * cellWidth + mgN)); if (layers[(int)LayerType.METAL].links[(int)CellLayer.Cardinals.E] != null) { grCxt.LineTo(new PointD((this.x + 1) * cellWidth, this.y * cellWidth + mgN)); grCxt.LineTo(new PointD((this.x + 1) * cellWidth, (this.y + 1) * cellWidth - mgS)); } grCxt.LineTo(new PointD((this.x + 1) * cellWidth - mgE, (this.y + 1) * cellWidth - mgS)); if (layers[(int)LayerType.METAL].links[(int)CellLayer.Cardinals.S] != null) { grCxt.LineTo(new PointD((this.x + 1) * cellWidth - mgE, (this.y + 1) * cellWidth)); grCxt.LineTo(new PointD(this.x * cellWidth + mgW, (this.y + 1) * cellWidth)); } grCxt.LineTo(new PointD(this.x * cellWidth + mgW, (this.y + 1) * cellWidth - mgS)); if (layers[(int)LayerType.METAL].links[(int)CellLayer.Cardinals.W] != null) { grCxt.LineTo(new PointD(this.x * cellWidth, (this.y + 1) * cellWidth - mgS)); grCxt.LineTo(new PointD(this.x * cellWidth, this.y * cellWidth + mgN)); } grCxt.ClosePath(); grCxt.Color = color.find("metal_fill"); grCxt.Fill(); } } // couche I/O if (layers[(int)LayerType.IO].isSet) { traceLinkedFullSquare(grCxt, cellWidth, color.find("metal_fill"), LayerType.IO); } // via if (circuit.showLayer[(int)Circuit.showLayerType.S]) { if (via) { grCxt.MoveTo(new PointD(x * cellWidth + 7d, y * cellWidth + 7d)); grCxt.LineTo(new PointD((x + 1) * cellWidth - 6d, y * cellWidth + 7d)); grCxt.LineTo(new PointD((x + 1) * cellWidth - 6d, (y + 1) * cellWidth - 6d)); grCxt.LineTo(new PointD(x * cellWidth + 7d, (y + 1) * cellWidth - 6d)); grCxt.ClosePath(); grCxt.Color = color.find("via"); grCxt.Stroke(); } } // powered bool pwr = false; foreach (CellLayer l in layers) if (l.isPowered) pwr = true; if (pwr) { grCxt.MoveTo(new PointD(x * cellWidth + mgW, y * cellWidth + mgN)); grCxt.LineTo(new PointD((x + 1) * cellWidth - mgE, y * cellWidth + mgN)); grCxt.LineTo(new PointD((x + 1) * cellWidth - mgE, (y + 1) * cellWidth - mgS)); grCxt.LineTo(new PointD(x * cellWidth + mgW, (y + 1) * cellWidth - mgS)); grCxt.ClosePath(); grCxt.Color = color.find("powered"); grCxt.Fill(); } }