Beispiel #1
0
        public new static sym_rectangle Parse(List <Token> tokens)
        {
            sym_rectangle result = new sym_rectangle();

            result.P1.X = tokens[1].IntValue;
            result.P1.Y = tokens[2].IntValue;
            result.P2.X = tokens[3].IntValue;
            result.P2.Y = tokens[4].IntValue;

            result.Unit = tokens[5].IntValue;
            result.DeMorganAlternate = tokens[6].IntValue;
            result.PenSize           = (float)tokens[7].GetValueAsDouble();
            result.Fill = sym_drawing_base.GetFillType(tokens[8].Value);

            return(result);
        }
Beispiel #2
0
        // 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;
        }
Beispiel #3
0
        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;
            }

            //
        }