public new static sym_pin Parse(List <Token> tokens) { sym_pin result = new sym_pin(); result.Name = tokens[1].Value; result.PinNumber = tokens[2].Value; result.Pos.X = tokens[3].IntValue; result.Pos.Y = tokens[4].IntValue; result.Length = tokens[5].IntValue; result.Orientation = tokens[6].Value; result.SizeNum = (float)tokens[7].GetValueAsDouble(); result.SizeName = (float)tokens[8].GetValueAsDouble(); result.Unit = tokens[9].IntValue; result.DeMorganAlternate = tokens[10].IntValue; result.Type = tokens[11].Value; if (tokens.Count >= 13) { result.Shape = tokens[12].Value; } else { result.Shape = " "; } result.Visible = true; if (result.Shape.StartsWith("N")) { result.Visible = false; } return(result); }
RectangleF GetPinRect(sym_pin pin, float offset) { float size = pin.Name.Length * pin.SizeName; if (pin.Name == "~") { size = 0; } if (size != 0) { size += offset; } size += pin.Length; // // o---| name // switch (pin.Orientation) { case "D": return(new RectangleF(pin.Pos.X - pin.SizeName / 2f, pin.Pos.Y - size, pin.SizeName, size)); case "U": return(new RectangleF(pin.Pos.X - pin.SizeName / 2f, pin.Pos.Y, pin.SizeName, size)); case "R": return(new RectangleF(pin.Pos.X, pin.Pos.Y - pin.SizeName / 2f, size, pin.SizeName)); case "L": return(new RectangleF(pin.Pos.X - size, pin.Pos.Y - pin.SizeName / 2f, size, pin.SizeName)); } return(RectangleF.Empty); }
public sym_pin FindPin(int unit, string name) { if (Drawings != null) { foreach (sym_drawing_base sym in Drawings) { if (sym is sym_pin) { sym_pin pin = sym as sym_pin; if ((pin.Unit == unit) && (pin.Name == name)) { return(pin); } } } } return(null); }
public static sym_pin Clone(sym_pin src) { sym_pin result = new sym_pin(src.Unit, src.Name, src.PinNumber, src.Pos, src.Length, src.Orientation, src.SizeNum, src.SizeName, src.Type, src.Shape, src.Visible); return(result); }
// drawing functions public void Render(Canvas canvas) { canvas.Ydir = -1; // +ve Y is up the page canvas.Initialise(); // Pen pen = new Pen(canvas.color_symbol_drawing, 2); Brush brush = new SolidBrush(canvas.color_symbol_drawing); Brush brush_text = new SolidBrush(canvas.color_symbol_text); // pen.Width = 2; pen.EndCap = System.Drawing.Drawing2D.LineCap.Round; pen.StartCap = System.Drawing.Drawing2D.LineCap.Round; pen.Alignment = System.Drawing.Drawing2D.PenAlignment.Center; // DrawText(canvas, fValue.Text, brush_text); DrawText(canvas, fReference.Text, brush_text); SolidBrush fill_brush = new SolidBrush(canvas.color_symbol_drawing); // draw background fills foreach (sym_drawing_base node in this.Drawings) { if (node.Fill == FillTypes.PenColor) { fill_brush.Color = canvas.color_symbol_drawing; } else { fill_brush.Color = canvas.color_symbol_background; } if (node is sym_rectangle) { sym_rectangle gr_rect = node as sym_rectangle; Point sp1 = canvas.ToScreen(gr_rect.P1); Point sp2 = canvas.ToScreen(gr_rect.P2); if (gr_rect.Fill != FillTypes.None) { canvas.g.FillRectangle(fill_brush, new Rectangle(Math.Min(sp1.X, sp2.X), Math.Min(sp1.Y, sp2.Y), Math.Abs(sp2.X - sp1.X), Math.Abs(sp2.Y - sp1.Y))); } } else if (node is sym_polygon) { sym_polygon gr_poly = node as sym_polygon; if (node.Fill != FillTypes.None) { Point[] points = new Point[gr_poly.NumVertex]; for (int i = 0; i < gr_poly.NumVertex; i++) { points[i] = canvas.ToScreen(gr_poly.Vertex[i]); } canvas.g.FillPolygon(fill_brush, points); } } else if (node is sym_arc) { } else if (node is sym_circle) { } } Console.WriteLine("sym {0}", Name); // draw foreground items foreach (sym_drawing_base node in this.Drawings) { if (node.PenSize == 0) { pen.Width = canvas.ToScreen(5f); } else { pen.Width = canvas.ToScreen(node.PenSize); } if (node.Fill == FillTypes.PenColor) { fill_brush.Color = canvas.color_symbol_drawing; } else { fill_brush.Color = canvas.color_symbol_background; } if (node is sym_rectangle) { sym_rectangle gr_rect = node as sym_rectangle; Point sp1 = canvas.ToScreen(gr_rect.P1); Point sp2 = canvas.ToScreen(gr_rect.P2); if ((sp2.X - sp1.X == 0) || (sp2.Y - sp1.Y == 0)) { canvas.g.DrawLine(pen, sp1, sp2); } else { canvas.g.DrawRectangle(pen, new Rectangle(Math.Min(sp1.X, sp2.X), Math.Min(sp1.Y, sp2.Y), Math.Abs(sp2.X - sp1.X), Math.Abs(sp2.Y - sp1.Y))); } } else if (node is sym_arc) { sym_arc arc = node as sym_arc; Point sp1 = canvas.ToScreen(arc.Position); int radius = canvas.ToScreen(arc.Radius); #if Method1 float start, end; start = NormalizeAnglePos(arc.ArcStart); end = NormalizeAnglePos(arc.ArcEnd); float angle = end - start; float a_start = CalcAngle(arc.Position, arc.Start); float a_end = CalcAngle(arc.Position, arc.End); Console.WriteLine("arc {0:f1} {1:f1} {2:f1}", arc.ArcStart, arc.ArcEnd, arc.ArcEnd - arc.ArcStart); Console.WriteLine("arc norm {0:f1} {1:f1} {2:f1}", start, end, angle); Console.WriteLine("arc calc {0:f1} {1:f1} ", a_start, a_end); if (Math.Abs(angle) < 180) { if (angle != 0) { g.DrawArc(pen, new Rectangle(sp1.X - radius, sp1.Y - radius, radius * 2, radius * 2), -a_end, angle); } } else { if (angle > 180) { angle -= 180; } g.DrawArc(pen, new Rectangle(sp1.X - radius, sp1.Y - radius, radius * 2, radius * 2), -a_start, angle); } #endif // #if Method2 float start, end; start = NormalizeAnglePos(arc.ArcStart); end = NormalizeAnglePos(arc.ArcEnd); bool swap = MapAngles(ref start, ref end); PointF pos1 = arc.Start; PointF pos2 = arc.End; if (swap) { pos1 = arc.End; pos2 = arc.Start; } //float angle = NormalizeAnglePos(end - start); float angle = end - start; //start = CalcAngle(arc.Position, pos1); Console.WriteLine("arc {0:f1} {1:f1} {2:f1}", arc.ArcStart, arc.ArcEnd, arc.ArcEnd - arc.ArcStart); Console.WriteLine("arc norm {0:f1} {1:f1} {2:f1} {3}", start, end, angle, swap); //Console.WriteLine("arc calc {0:f1} {1:f1} ", a_start, a_end); if (angle != 0) { g.DrawArc(pen, new Rectangle(sp1.X - radius, sp1.Y - radius, radius * 2, radius * 2), -end, angle); } #endif //#if Method3 float a_start = CalcAngle(arc.Position, arc.Start); float a_end = CalcAngle(arc.Position, arc.End); float start, end; start = NormalizeAnglePos(a_start); end = NormalizeAnglePos(a_end); float angle = end - start; if (angle < 0) { angle += 360; } // float test_angle = NormalizeAnglePos(arc.ArcEnd) - NormalizeAnglePos(arc.ArcStart); test_angle = NormalizeAnglePos(test_angle); if (angle != 0) { if ((test_angle < 180)) { canvas.g.DrawArc(pen, new Rectangle(sp1.X - radius, sp1.Y - radius, radius * 2, radius * 2), -end, angle); } else { canvas.g.DrawArc(pen, new Rectangle(sp1.X - radius, sp1.Y - radius, radius * 2, radius * 2), -start, 360.0f - angle); } } //#endif // if (false) { Pen tpen = new Pen(Color.Green); tpen.Width = 3; canvas.g.DrawLine(tpen, sp1, canvas.ToScreen(arc.Start)); tpen.Color = Color.Blue; canvas.g.DrawLine(tpen, sp1, canvas.ToScreen(arc.End)); } } else if (node is sym_circle) { sym_circle circle = node as sym_circle; Point sp1 = canvas.ToScreen(circle.Position); int radius = canvas.ToScreen(circle.Radius); canvas.g.DrawEllipse(pen, new Rectangle(sp1.X - radius, sp1.Y - radius, radius * 2, radius * 2)); } else if (node is sym_bezier) { } else if (node is sym_polygon) { sym_polygon gr_poly = node as sym_polygon; if (node.Fill == FillTypes.PenColor) { Point[] points = new Point[gr_poly.NumVertex]; for (int i = 0; i < gr_poly.NumVertex; i++) { points[i] = canvas.ToScreen(gr_poly.Vertex[i]); } canvas.g.FillPolygon(fill_brush, points); } for (int i = 0; i < gr_poly.NumVertex - 1; i++) { Point sp1 = canvas.ToScreen(gr_poly.Vertex[i]); Point sp2 = canvas.ToScreen(gr_poly.Vertex[i + 1]); canvas.g.DrawLine(pen, sp1, sp2); } if ((node.Fill != FillTypes.None) && (gr_poly.NumVertex > 2)) { Point sp1 = canvas.ToScreen(gr_poly.Vertex[0]); Point sp2 = canvas.ToScreen(gr_poly.Vertex[gr_poly.NumVertex - 1]); canvas.g.DrawLine(pen, sp1, sp2); } } else if (node is sym_pin) { sym_pin pin = node as sym_pin; if (pin.Visible) { Point sp1 = canvas.ToScreen(pin.Pos); int radius = canvas.ToScreen(10f); PointF offset = new PointF(0, 0); switch (pin.Orientation) { case "L": offset.X = -pin.Length; break; case "R": offset.X = pin.Length; break; case "U": offset.Y = pin.Length; break; case "D": offset.Y = -pin.Length; break; } Point sp2 = canvas.ToScreen(new PointF(pin.Pos.X + offset.X, pin.Pos.Y + offset.Y)); if (pin.PenSize == 0) { pen.Width = canvas.ToScreen(5f); } else { pen.Width = canvas.ToScreen(pin.PenSize); } canvas.g.DrawLine(pen, sp1, sp2); pen.Width = 2; canvas.g.DrawEllipse(pen, new Rectangle(sp1.X - radius, sp1.Y - radius, radius * 2, radius * 2)); // int FontHeight = canvas.ToScreen(pin.SizeName); Font font = new Font("Arial", FontHeight, FontStyle.Regular, GraphicsUnit.Pixel); TextBase text = new TextBase(); // horiz if ((pin.Orientation == "L") || (pin.Orientation == "R")) { if ((this.ShowPinName) && (pin.Name != "~")) { // inside? if (this.Offset != 0) { if (pin.Orientation == "R") { text.Pos = new Position(pin.Pos.X + offset.X + this.Offset, pin.Pos.Y); text.HorizAlignment = SymbolField.HorizAlign_Left; text.VertAlignment = SymbolField.VertAlign_Center; } else { text.Pos = new Position(pin.Pos.X + offset.X - this.Offset, pin.Pos.Y); text.HorizAlignment = SymbolField.HorizAlign_Right; text.VertAlignment = SymbolField.VertAlign_Center; } } else { if (pin.Orientation == "R") { text.Pos = new Position(pin.Pos.X + pin.Length / 2, pin.Pos.Y); text.HorizAlignment = SymbolField.HorizAlign_Center; text.VertAlignment = SymbolField.VertAlign_Bottom; } else { text.Pos = new Position(pin.Pos.X - pin.Length / 2, pin.Pos.Y); text.HorizAlignment = SymbolField.HorizAlign_Center; text.VertAlignment = SymbolField.VertAlign_Bottom; } } text.FontSize = pin.SizeName; text.Value = pin.Name; DrawText(canvas, text, brush_text); } if (this.ShowPinNumber) { if (pin.Orientation == "L") { text.Pos = new Position(pin.Pos.X - pin.Length / 2, pin.Pos.Y); } else { text.Pos = new Position(pin.Pos.X + pin.Length / 2, pin.Pos.Y); } text.HorizAlignment = SymbolField.HorizAlign_Center; if (this.Offset == 0) { text.VertAlignment = SymbolField.VertAlign_Top; } else { text.VertAlignment = SymbolField.VertAlign_Bottom; } text.FontSize = pin.SizeName; text.Value = pin.PinNumber; DrawText(canvas, text, brush); } } else // vertical { if ((this.ShowPinName) && (pin.Name != "~")) { if (pin.Orientation == "U") { text.Pos = new Position(pin.Pos.X, pin.Pos.Y + offset.Y + this.Offset); text.HorizAlignment = SymbolField.HorizAlign_Left; } else { text.Pos = new Position(pin.Pos.X, pin.Pos.Y + offset.Y - this.Offset); text.HorizAlignment = SymbolField.HorizAlign_Right; } text.VertAlignment = SymbolField.VertAlign_Center; text.FontSize = pin.SizeName; text.Value = pin.Name; text.Pos.Rotation = 90; DrawText(canvas, text, brush_text); } if (this.ShowPinNumber) { if (pin.Orientation == "D") { text.Pos = new Position(pin.Pos.X, pin.Pos.Y - pin.Length / 2); } else { text.Pos = new Position(pin.Pos.X, pin.Pos.Y + pin.Length / 2); } text.HorizAlignment = SymbolField.HorizAlign_Center; text.VertAlignment = SymbolField.VertAlign_Bottom; text.FontSize = pin.SizeName; text.Value = pin.PinNumber; text.Pos.Rotation = 90; DrawText(canvas, text, brush); } } } } else if (node is sym_text) { sym_text text = node as sym_text; DrawText(canvas, text.Text, brush); } } //return bm; }
public void CheckSymbol(bool Update = false) { // find max lengths const int m_up = 0; const int m_down = 1; const int m_left = 2; const int m_right = 3; float pin_len = 0; float[] max = new float[4]; Extent outer_extent = new Extent(); Extent inner_extent = new Extent(); Extent text_extent = new Extent(); Extent new_outer_extent = new Extent(); Extent lower_pins = new Extent(); //PointF min_pos = new PointF(0,0); //PointF max_pos = new PointF(0, 0); List <RectangleF> bounds = new List <RectangleF>(); bool[] overlaps = new bool[4] { false, false, false, false }; List <sym_pin> pins = new List <sym_pin>(); // check only visible items? foreach (sym_drawing_base drawing in Drawings) { if (drawing is sym_pin) { sym_pin pin = drawing as sym_pin; pins.Add(pin); float size = pin.Name.Length * pin.SizeName; size += pin.Length; pin_len = pin.Length; //size = 50.0f * ((int)(size / 50.0f) + 1); // U D L R int index = 0; switch (pin.Orientation) { case "D": index = m_up; break; case "U": index = m_down; break; case "R": index = m_left; break; case "L": index = m_right; break; } bounds.Add(GetPinRect(pin)); UpdateExtent(ref outer_extent, pin.Pos); //size = RoundToGrid(size); if (size > max[index]) { max[index] = size; } } } // check for overlaps bool overlap = false; for (int i = 0; i < bounds.Count; i++) { for (int j = 0; j < i; j++) { if (i != j) { RectangleF r = RectangleF.Intersect(bounds[i], bounds[j]); if (!r.IsEmpty) { overlap = true; Console.WriteLine(" pin {0}:{1} overlaps {2}:{3}", pins[i].PinNumber, pins[i].Name, pins[j].PinNumber, pins[j].Name); if ((pins[i].Orientation == "U") || (pins[j].Orientation == "U")) { overlaps[m_down] = true; } else if ((pins[i].Orientation == "D") || (pins[j].Orientation == "D")) { overlaps[m_up] = false; } else { overlaps[m_left] = true; } } } } } if (overlap) { Console.WriteLine("Symbol {0} has overlapping text", Name); } if (overlap && Update) { Console.WriteLine("Formatting {0}", Name); for (int i = 0; i < 4; i++) { max[i] = RoundToGrid(max[i]); } new_outer_extent = new Extent(); float width = max[m_left] + max[m_right]; width = RoundToGrid(width, gridsize * 2); max[m_left] = width / 2; max[m_right] = width / 2; // Pass 1: set max sizes of horizontal pins foreach (sym_drawing_base drawing in Drawings) { if (drawing is sym_pin) { sym_pin pin = drawing as sym_pin; switch (pin.Orientation) { case "R": { if (pin.Pos.X > -max[m_left]) { pin.Pos.X = -max[m_left]; } UpdateExtent(ref text_extent, new PointF(pin.Pos.X + pin_len, pin.Pos.Y - pin.SizeName / 2f)); UpdateExtent(ref text_extent, new PointF(pin.Pos.X + pin_len + RoundToGrid(pin.Name.Length * pin.SizeName), pin.Pos.Y + pin.SizeName / 2f)); } break; case "L": { if (pin.Pos.X < max[m_right]) { pin.Pos.X = max[m_right]; } UpdateExtent(ref text_extent, new PointF(pin.Pos.X - pin_len, pin.Pos.Y - pin.SizeName / 2f)); UpdateExtent(ref text_extent, new PointF(pin.Pos.X - pin_len - RoundToGrid(pin.Name.Length * pin.SizeName), pin.Pos.Y + pin.SizeName / 2f)); } break; } UpdateExtent(ref new_outer_extent, pin.Pos); } } // Pass 2: set vertical pins foreach (sym_drawing_base drawing in Drawings) { if (drawing is sym_pin) { sym_pin pin = drawing as sym_pin; switch (pin.Orientation) { case "U": // bottom pins { float p = RoundToGrid(text_extent.Min.Y) - max[m_down]; if (pin.Pos.Y > p) { pin.Pos.Y = p; } RectangleF r = GetPinRect(pin); UpdateExtent(ref lower_pins, r.Location); UpdateExtent(ref lower_pins, new PointF(r.Right, r.Bottom)); } break; case "D": // top pins { float p = RoundToGrid(text_extent.Max.Y) + max[m_up]; if (pin.Pos.Y < p) { pin.Pos.Y = p; } } break; } UpdateExtent(ref new_outer_extent, pin.Pos); } } // Pass 3: update the bounding rectangle foreach (sym_drawing_base drawing in Drawings) { if (drawing is sym_rectangle) { sym_rectangle rect = drawing as sym_rectangle; if ((rect.P1.X - pin_len == outer_extent.Min.X) && (rect.P2.Y - pin_len == outer_extent.Min.Y)) { rect.P1.X = new_outer_extent.Min.X + pin_len; rect.P1.Y = new_outer_extent.Max.Y - pin_len; // rect.P2.X = new_outer_extent.Max.X - pin_len; rect.P2.Y = new_outer_extent.Min.Y + pin_len; } } } // reposition texts // designator at top left fReference.Text.Pos.At.X = new_outer_extent.Min.X + pin_len; fReference.Text.Pos.At.Y = new_outer_extent.Max.Y - pin_len + gridsize; // symbol name /value at lower left fValue.Text.Pos.At.X = new_outer_extent.Max.X - pin_len - RoundToGrid(fValue.Text.Value.Length * fValue.Text.FontSize); if (fValue.Text.Pos.At.X < RoundToGrid(lower_pins.Max.X)) { fValue.Text.Pos.At.X = RoundToGrid(lower_pins.Max.X) + gridsize; } fValue.Text.Pos.At.Y = new_outer_extent.Min.Y + pin_len - gridsize * 2f; } // }
RectangleF GetPinRect(sym_pin pin) { return(GetPinRect(pin, Offset)); }