Exemple #1
0
        private void RenderTextFramePrimitive(Graphics g, TextFrameRecord textFrame)
        {
            var penWidth = ScaleLineWidth(textFrame.LineWidth);
            var rect     = ScreenFromWorld(textFrame.CalculateBounds());

            if (textFrame.IsSolid)
            {
                using (var brush = new SolidBrush(textFrame.AreaColor))
                {
                    DrawingUtils.FillRectangle(g, brush, rect);
                }
            }

            if (textFrame.ShowBorder)
            {
                using (var pen = CreatePen(textFrame.Color, penWidth, lineJoin: LineJoin.Miter))
                {
                    DrawingUtils.DrawRectangle(g, pen, rect);
                }
                // reduce text area according to the penWidth
                rect.Inflate(-penWidth, -penWidth);
            }

            using (var brush = new SolidBrush(textFrame.TextColor))
                using (var font = CreateFont(textFrame.FontId))
                {
                    DrawingUtils.DrawString(g, textFrame.Text, font, brush, rect, StringAlignment.Near, StringAlignment.Near, textFrame.ClipToRect, textFrame.WordWrap);
                }
        }
        protected override void DoRender(Graphics graphics, bool fastRendering = false)
        {
            if (graphics == null)
            {
                throw new ArgumentNullException(nameof(graphics));
            }

            var primitives        = Component.GetPrimitivesOfType <PcbPrimitive>();
            var orderedPrimitives = primitives
                                    .Where(p => IsPrimitiveVisible(graphics, p))
                                    .OrderByDescending(p => p.Layer.DrawPriority)
                                    .ThenByDescending(p => p.Layer);

            Debug.WriteLine($"Rendering {orderedPrimitives.Count()} / {primitives.Count()}");

            foreach (var primitive in orderedPrimitives)
            {
                // using Graphics.BeginContainer() instead of Graphics.Save() because
                // the former saves the previous transform as the default, and we
                // can then call Graphics.ResetTransform() to go back to the transform
                // that was set when the container was created.
                // Save() just resets the transform to identity
                var graphicsContainer = graphics.BeginContainer();
                // Drawback is that we need to set SmothingMode, etc. for each container
                DrawingUtils.SetupGraphics(graphics, fastRendering);

                switch (primitive)
                {
                case PcbArc arc:
                    RenderArcPrimitive(graphics, arc);
                    break;

                case PcbPad pad:
                    RenderPadPrimitive(graphics, pad);
                    break;

                case PcbTrack track:
                    RenderTrackPrimitive(graphics, track);
                    break;

                case PcbString @string:
                    RenderStringPrimitive(graphics, @string);
                    break;

                case PcbRectangle rectangle:
                    RenderRectanglePrimitive(graphics, rectangle);
                    break;

                case PcbPolygon polygon:
                    RenderPolygonPrimitive(graphics, polygon);
                    break;
                }
                graphics.EndContainer(graphicsContainer);
            }
        }
Exemple #3
0
        private void RenderPadPrimitive(Graphics g, PcbPad pad)
        {
            var holeCenter = ScreenFromWorld(pad.Location.X, pad.Location.Y);

            g.TranslateTransform(holeCenter.X, holeCenter.Y);
            g.RotateTransform(-(float)pad.Rotation);

            DrawPad(g, pad, PcbPadPart.BottomSolder);
            DrawPad(g, pad, PcbPadPart.TopSolder);
            DrawPad(g, pad, PcbPadPart.BottomLayer);
            DrawPad(g, pad, PcbPadPart.TopLayer);

            if (pad.HasHole)
            {
                g.RotateTransform(-(float)pad.HoleRotation);
                using (var brush = new SolidBrush(Layer.GetLayerColor("PadHoleLayer")))
                {
                    var rect = ScaleRect(pad.CalculatePartRect(PcbPadPart.Hole, false));
                    switch (pad.HoleShape)
                    {
                    case PcbPadHoleShape.Round:
                        g.FillEllipse(brush, rect);
                        break;

                    case PcbPadHoleShape.Square:
                        DrawingUtils.FillRectangle(g, brush, rect);
                        break;

                    case PcbPadHoleShape.Slot:
                        DrawingUtils.FillRoundedRect(g, brush, rect, 100);
                        break;

                    default:
                        return;
                    }
                }
            }

            g.ResetTransform();

            const float MIN_FONT_DESCRIPTOR = 7;
            var         fontSize            = Math.Min(29f, ScaleCoord(pad.HasHole ? pad.HoleSize : pad.SizeTop.Y) * 0.5f);

            if (fontSize > MIN_FONT_DESCRIPTOR)
            {
                var fontColor = pad.HasHole ? Color.FromArgb(255, 227, 143) : Color.FromArgb(255, 181, 181);
                using (var brush = new SolidBrush(fontColor)) // TODO: add constant
                    using (var font = new Font("Arial", fontSize))
                    {
                        DrawingUtils.DrawString(g, pad.Designator, font, brush, holeCenter.X, holeCenter.Y,
                                                StringAlignmentKind.Tight, StringAlignment.Center, StringAlignment.Center);
                    }
            }
        }
Exemple #4
0
        private void RenderPinPrimitive(Graphics g, PinRecord pin)
        {
            var location = ScreenFromWorld(pin.Location.X, pin.Location.Y);

            g.TranslateTransform(location.X, location.Y);

            var direction = 1.0f;
            var displayNameHorizontalAlignment = StringAlignment.Far;
            var designatorHorizontalAlignment  = StringAlignment.Near;
            var penWidth = ScaleLineWidth(LineWidth.Small);

            using (var pen = CreatePen(pin.Color, penWidth, LineCap.Flat))
            {
                if (pin.PinConglomerate.HasFlag(PinConglomerateFlags.Rotated))
                {
                    g.RotateTransform(-90);
                }

                if (pin.PinConglomerate.HasFlag(PinConglomerateFlags.Flipped))
                {
                    direction = -1.0f;
                    displayNameHorizontalAlignment = StringAlignment.Near;
                    designatorHorizontalAlignment  = StringAlignment.Far;
                }

                var length = ScaleCoord(pin.PinLength) * direction;
                g.DrawLine(pen, -1.0f, 0.0f, length, 0.0f);
            }

            using (var brush = new SolidBrush(pin.Color))
                using (var font = CreateFont("Times New Roman", 10f, FontStyle.Regular))
                {
                    if (pin.PinConglomerate.HasFlag(PinConglomerateFlags.DisplayNameVisible))
                    {
                        var x           = ScalePixelLength(-5.0f) * direction;
                        var displayName = pin.Name.Replace(@"\", "");
                        DrawingUtils.DrawString(g, displayName, font, brush, x, ScalePixelLength(0.5),
                                                StringAlignmentKind.Default, displayNameHorizontalAlignment, StringAlignment.Center);
                        using (var pen = CreatePen(pin.Color, ScaleLineWidth(LineWidth.Small)))
                        {
                            DrawOverline(g, pin.Name, font, pen, x, ScalePixelLength(0.5),
                                         StringAlignmentKind.Default, displayNameHorizontalAlignment, StringAlignment.Center);
                        }
                    }

                    if (pin.PinConglomerate.HasFlag(PinConglomerateFlags.DesignatorVisible))
                    {
                        DrawingUtils.DrawString(g, pin.Designator, font, brush,
                                                ScalePixelLength(8.0f) * direction, 0,
                                                StringAlignmentKind.Extent, designatorHorizontalAlignment, StringAlignment.Far);
                    }
                }
        }
        private void RenderRoundedRectPrimitive(Graphics g, RoundedRectangleRecord roundedRect)
        {
            var penWidth = ScaleLineWidth(roundedRect.LineWidth);

            using (var brush = new SolidBrush(roundedRect.AreaColor))
                using (var pen = CreatePen(roundedRect.Color, penWidth))
                {
                    var rect    = ScreenFromWorld(roundedRect.CalculateBounds());
                    var radiusX = ScaleCoord(roundedRect.CornerXRadius);
                    var radiusY = ScaleCoord(roundedRect.CornerYRadius);
                    DrawingUtils.FillRoundedRect(g, brush, rect, radiusX, radiusY);
                    DrawingUtils.DrawRoundedRect(g, pen, rect, radiusX, radiusY);
                }
        }
Exemple #6
0
        private void RenderTextPrimitive(Graphics g, PcbText text)
        {
            var   location  = ScreenFromWorld(text.Corner1.X, text.Corner1.Y);
            var   color     = LayerMetadata.GetColor(text.Layer);
            var   height    = ScaleCoord(text.Height);
            var   fontStyle = (text.FontItalic ? FontStyle.Italic : FontStyle.Regular) | (text.FontBold ? FontStyle.Bold : FontStyle.Regular);
            float fontWidth;
            float fontSize;

            if (text.TextKind == PcbTextKind.Stroke)
            {
                fontWidth = ScaleCoord(text.Width);
                fontSize  = DrawingUtils.CalculateFontSizeForBaseline(g, StrokeFontFamily, fontStyle, height + fontWidth);
            }
            else
            {
                fontWidth = 0;
                fontSize  = DrawingUtils.CalculateFontSizeForHeight(g, StrokeFontFamily, fontStyle, height);
            }

            g.TranslateTransform(location.X, location.Y);
            g.RotateTransform(-(float)text.Rotation);

            using (var brush = new SolidBrush(color))
                using (var fontFamily = new FontFamily(text.FontName))
                    using (var font = new Font(text.TextKind == PcbTextKind.Stroke ? StrokeFontFamily : fontFamily, fontSize, fontStyle))
                    {
                        var size = g.MeasureString(text.Text, font);
                        if (size.Height < 5)
                        {
                            using (var pen = new Pen(brush))
                            {
                                var rect = ScaleRect(text.CalculateRect(false));
                                g.DrawRectangle(pen, rect.Left, rect.Top, rect.Width, rect.Height);
                            }
                        }
                        else
                        {
                            if (text.Mirrored)
                            {
                                g.ScaleTransform(-1.0f, 1.0f);
                            }
                            DrawingUtils.DrawString(g, text.Text, font, brush, 0, fontWidth * 0.5f,
                                                    StringAlignmentKind.Tight, StringAlignment.Near, StringAlignment.Far);
                        }
                    }

            g.ResetTransform();
        }
        private void RenderImagePrimitive(Graphics g, ImageRecord image)
        {
            var rect = ScreenFromWorld(image.CalculateBounds());

            if (_embeddedImages.TryGetValue(image.Filename, out var img))
            {
                g.DrawImage(img, rect);
            }

            if (image.IsSolid)
            {
                var penWidth = ScaleLineWidth(image.LineWidth);
                using (var pen = CreatePen(image.Color, penWidth, lineJoin: LineJoin.Miter))
                {
                    DrawingUtils.DrawRectangle(g, pen, rect);
                }
            }
        }
        private void RenderRectanglePrimitive(Graphics g, RectangleRecord rectangle)
        {
            var rect = ScreenFromWorld(rectangle.CalculateBounds());

            if (rectangle.IsSolid)
            {
                using (var brush = new SolidBrush(rectangle.AreaColor))
                {
                    DrawingUtils.FillRectangle(g, brush, rect);
                }
            }

            var penWidth = ScaleLineWidth(rectangle.LineWidth);

            using (var pen = CreatePen(rectangle.Color, penWidth, lineJoin: LineJoin.Miter))
            {
                DrawingUtils.DrawRectangle(g, pen, rect);
            }
        }
Exemple #9
0
        /// <summary>
        /// Draws a bar over the text of a pin to symbolize negative logic.
        /// </summary>
        private void DrawOverline(Graphics g, string text, Font font, Pen pen, float x, float y,
                                  StringAlignmentKind alignmentKind, StringAlignment horizontalAlignment, StringAlignment verticalAlignment)
        {
            var overlineRanges = OverlineHelper.Parse(text);

            if (overlineRanges.Length == 0)
            {
                return;
            }

            var plainText = text.Replace(@"\", "");
            var offsetX   = ScalePixelLength(0.5f);
            var offsetY   = 0.0f;

            var rangeBounds = DrawingUtils.CalculateTextExtent(g, plainText, x, y, font,
                                                               alignmentKind, horizontalAlignment, verticalAlignment, overlineRanges);

            foreach (var bound in rangeBounds)
            {
                var inflatedBound = bound.Inflated(-offsetX, -offsetY);
                g.DrawLine(pen, inflatedBound.X, inflatedBound.Y, inflatedBound.Right, inflatedBound.Y);
            }
        }
Exemple #10
0
        private void RenderTextStringPrimitive(Graphics g, TextStringRecord textString)
        {
            if (textString.IsHidden || textString.Record != 4)
            {
                return;
            }

            var location = ScreenFromWorld(textString.Location.X, textString.Location.Y);

            using (var brush = new SolidBrush(textString.Color))
                using (var font = CreateFont(textString.FontId))
                {
                    StringAlignment horizontalAlignment;
                    if (textString.Justification == TextJustification.BottomLeft ||
                        textString.Justification == TextJustification.MiddleLeft ||
                        textString.Justification == TextJustification.TopLeft)
                    {
                        horizontalAlignment = StringAlignment.Near;
                    }
                    else if (textString.Justification == TextJustification.BottomCenter ||
                             textString.Justification == TextJustification.MiddleCenter ||
                             textString.Justification == TextJustification.TopCenter)
                    {
                        horizontalAlignment = StringAlignment.Center;
                    }
                    else
                    {
                        horizontalAlignment = StringAlignment.Far;
                    }

                    StringAlignment verticalAlignment;
                    if (textString.Justification == TextJustification.BottomLeft ||
                        textString.Justification == TextJustification.BottomCenter ||
                        textString.Justification == TextJustification.BottomRight)
                    {
                        verticalAlignment = StringAlignment.Far;
                    }
                    else if (textString.Justification == TextJustification.MiddleLeft ||
                             textString.Justification == TextJustification.MiddleCenter ||
                             textString.Justification == TextJustification.MiddleRight)
                    {
                        verticalAlignment = StringAlignment.Center;
                    }
                    else
                    {
                        verticalAlignment = StringAlignment.Near;
                    }

                    g.TranslateTransform(location.X, location.Y);
                    if (textString.Orientations.HasFlag(TextOrientations.Rotated))
                    {
                        g.RotateTransform(-90);
                    }
                    if (textString.Orientations.HasFlag(TextOrientations.Flipped))
                    {
                        horizontalAlignment = StringAlignment.Far - (int)horizontalAlignment;
                        verticalAlignment   = StringAlignment.Far - (int)verticalAlignment;
                    }

                    DrawingUtils.DrawString(g, textString.Text, font, brush,
                                            0, 0, horizontalAlignment, verticalAlignment, false);
                }
        }
Exemple #11
0
        /// <summary>
        /// Implements rendering of the SchLib.
        /// </summary>
        /// <param name="graphics"></param>
        /// <param name="fastRendering"></param>
        protected override void DoRender(Graphics graphics, bool fastRendering = false)
        {
            if (graphics == null)
            {
                throw new ArgumentNullException(nameof(graphics));
            }

            var primitives        = Component.GetPrimitivesOfType <SchPrimitive>();
            var orderedPrimitives = primitives
                                    .Where(p => IsPrimitiveVisible(graphics, p));

            Debug.WriteLine($"Rendering {orderedPrimitives.Count()} / {primitives.Count()}");

            foreach (var primitive in orderedPrimitives)
            {
                // using Graphics.BeginContainer() instead of Graphics.Save() because
                // the former saves the previous transform as the default, and we
                // can then call Graphics.ResetTransform() to go back to the transform
                // that was set when the container was created.
                // Save() just resets the transform to identity
                var graphicsContainer = graphics.BeginContainer();
                // Drawback is that we need to set SmothingMode, etc. for each container
                DrawingUtils.SetupGraphics(graphics, fastRendering);

                switch (primitive)
                {
                case PinRecord pin:
                    RenderPinPrimitive(graphics, pin);
                    break;

                case SymbolRecord symbol:
                    RenderSymbolPrimitive(graphics, symbol);
                    break;

                case TextStringRecord textString:
                    // this can handle Record34 and Record41 through inheritance
                    RenderTextStringPrimitive(graphics, textString);
                    break;

                case BezierRecord bezier:
                    RenderBezierPrimitive(graphics, bezier);
                    break;

                case PolylineRecord polyline:
                    RenderPolylinePrimitive(graphics, polyline);
                    break;

                case PolygonRecord polygon:
                    RenderPolygonPrimitive(graphics, polygon);
                    break;

                case EllipseRecord ellipse:
                    RenderEllipsePrimitive(graphics, ellipse);
                    break;

                case PieChartRecord pieChart:
                    RenderPieChartPrimitive(graphics, pieChart);
                    break;

                case RoundedRectangleRecord roundedRect:
                    RenderRoundedRectPrimitive(graphics, roundedRect);
                    break;

                case ArcRecord arc:
                    RenderArcPrimitive(graphics, arc);
                    break;

                case LineRecord line:
                    RenderLinePrimitive(graphics, line);
                    break;

                case RectangleRecord rectangle:
                    RenderRectanglePrimitive(graphics, rectangle);
                    break;

                case TextFrameRecord textFrame:
                    RenderTextFramePrimitive(graphics, textFrame);
                    break;

                case ImageRecord image:
                    RenderImagePrimitive(graphics, image);
                    break;
                }
                graphics.EndContainer(graphicsContainer);
            }
        }
Exemple #12
0
        private void DrawPad(Graphics g, PcbPad pad, PcbPadPart padPart)
        {
            PcbPadShape shape;
            int         cornerRadiusPercent;
            Color       color;

            // setup parameters according to the current padPart
            switch (padPart)
            {
            case PcbPadPart.TopLayer:
                shape = pad.ShapeTop;
                cornerRadiusPercent = pad.CornerRadiusTop;
                color = LayerMetadata.GetColor(pad.Layer);
                break;

            case PcbPadPart.BottomLayer:
                shape = pad.ShapeBottom;
                cornerRadiusPercent = pad.CornerRadiusBot;
                color = LayerMetadata.GetColor(pad.Layer);
                break;

            case PcbPadPart.TopSolder:
                shape = pad.ShapeTop;
                cornerRadiusPercent = pad.CornerRadiusTop;
                color = LayerMetadata.GetColor("TopSolder");
                break;

            case PcbPadPart.BottomSolder:
                shape = pad.ShapeBottom;
                cornerRadiusPercent = pad.CornerRadiusBot;
                color = LayerMetadata.GetColor("BottomSolder");
                break;

            default:
                return;
            }

            var rect = ScaleRect(pad.CalculatePartRect(padPart, false));

            using (var brush = new SolidBrush(color))
            {
                switch (shape)
                {
                case PcbPadShape.Round:
                    DrawingUtils.FillRoundedRect(g, brush, rect, 100);
                    break;

                case PcbPadShape.Rectangular:
                    DrawingUtils.FillRectangle(g, brush, rect);
                    break;

                case PcbPadShape.Octogonal:
                    DrawingUtils.FillOctagon(g, brush, rect);
                    break;

                case PcbPadShape.RoundedRectangle:
                    cornerRadiusPercent = cornerRadiusPercent > 0 ? cornerRadiusPercent : 100;
                    DrawingUtils.FillRoundedRect(g, brush, rect, cornerRadiusPercent);
                    break;

                default:
                    return;
                }
            }
        }