├── FUNDING.yml
├── .gitattributes
├── AltiumSharp
├── font.ttf
├── assets.schlib
├── BasicTypes
│ ├── Misc.cs
│ ├── CoordPoint.cs
│ ├── CoordPoint3D.cs
│ ├── Coord.cs
│ ├── CoordRect.cs
│ ├── Utils.cs
│ └── Layer.cs
├── Records
│ ├── Sch
│ │ ├── SchNetLabel.cs
│ │ ├── SchWire.cs
│ │ ├── SchMapDefinerList.cs
│ │ ├── SchSheetHeader.cs
│ │ ├── SchImplementationParameters.cs
│ │ ├── SchBezier.cs
│ │ ├── SchImplementationList.cs
│ │ ├── SchDesignator.cs
│ │ ├── SchTemplate.cs
│ │ ├── SchBasicPolyline.cs
│ │ ├── SchPie.cs
│ │ ├── SchJunction.cs
│ │ ├── SchImage.cs
│ │ ├── SchPolyline.cs
│ │ ├── SchSymbol.cs
│ │ ├── SchEllipse.cs
│ │ ├── SchEllipticalArc.cs
│ │ ├── SchRoundedRectangle.cs
│ │ ├── SchMapDefiner.cs
│ │ ├── SchPowerObject.cs
│ │ ├── SchLine.cs
│ │ ├── SchCircle.cs
│ │ ├── SchLabel.cs
│ │ ├── SchImplementation.cs
│ │ ├── SchArc.cs
│ │ ├── SchRectangle.cs
│ │ ├── SchLibHeader.cs
│ │ ├── SchTextFrame.cs
│ │ ├── SchPolygon.cs
│ │ ├── SchParameter.cs
│ │ ├── SchPrimitive.cs
│ │ ├── SchGraphicalObject.cs
│ │ ├── SchDocumentHeader.cs
│ │ └── SchPin.cs
│ ├── Pcb
│ │ ├── PcbFill.cs
│ │ ├── PcbRegion.cs
│ │ ├── PcbArc.cs
│ │ ├── PcbRectangularPrimitive.cs
│ │ ├── PcbTrack.cs
│ │ ├── PcbText.cs
│ │ ├── PcbComponent.cs
│ │ ├── PcbPrimitive.cs
│ │ ├── PcbVia.cs
│ │ └── PcbComponentBody.cs
│ └── Primitive.cs
├── IComponent.cs
├── IContainer.cs
├── GlobalSuppressions.cs
├── Drawing
│ ├── Extensions.cs
│ └── OverlineHelper.cs
├── SchDoc.cs
├── SchData.cs
├── PcbLib.cs
├── SchLib.cs
├── PcbData.cs
├── SchDocReader.cs
├── OriginalCircuit.AltiumSharp.csproj
├── SchDocWriter.cs
├── Extensions.cs
├── SchLibWriter.cs
└── SchWriter.cs
├── LibraryViewer
├── assets.schlib
├── App.config
├── Properties
│ ├── Settings.settings
│ ├── Settings.Designer.cs
│ ├── AssemblyInfo.cs
│ ├── Resources.Designer.cs
│ └── Resources.resx
├── Program.cs
├── LibraryViewer.csproj
├── PropertyViewer.cs
├── PropertyViewer.Designer.cs
├── PropertyViewer.resx
└── Main.resx
├── AltiumSharp.sln
├── README.md
└── .gitignore
/FUNDING.yml:
--------------------------------------------------------------------------------
1 | github: issus
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
--------------------------------------------------------------------------------
/AltiumSharp/font.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/issus/AltiumSharp/HEAD/AltiumSharp/font.ttf
--------------------------------------------------------------------------------
/AltiumSharp/assets.schlib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/issus/AltiumSharp/HEAD/AltiumSharp/assets.schlib
--------------------------------------------------------------------------------
/LibraryViewer/assets.schlib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/issus/AltiumSharp/HEAD/LibraryViewer/assets.schlib
--------------------------------------------------------------------------------
/AltiumSharp/BasicTypes/Misc.cs:
--------------------------------------------------------------------------------
1 | namespace OriginalCircuit.AltiumSharp.BasicTypes
2 | {
3 | public enum LineWidth
4 | {
5 | Smallest, Small, Medium, Large
6 | };
7 | }
8 |
--------------------------------------------------------------------------------
/AltiumSharp/Records/Sch/SchNetLabel.cs:
--------------------------------------------------------------------------------
1 | namespace OriginalCircuit.AltiumSharp.Records
2 | {
3 | public class SchNetLabel : SchLabel
4 | {
5 | public override int Record => 25;
6 | }
7 | }
--------------------------------------------------------------------------------
/AltiumSharp/Records/Sch/SchWire.cs:
--------------------------------------------------------------------------------
1 | namespace OriginalCircuit.AltiumSharp.Records
2 | {
3 | public class SchWire : SchBasicPolyline
4 | {
5 | public override int Record => 27;
6 | }
7 | }
--------------------------------------------------------------------------------
/AltiumSharp/Records/Sch/SchMapDefinerList.cs:
--------------------------------------------------------------------------------
1 | namespace OriginalCircuit.AltiumSharp.Records
2 | {
3 | public class SchMapDefinerList : SchPrimitive
4 | {
5 | public override int Record => 46;
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/AltiumSharp/Records/Sch/SchSheetHeader.cs:
--------------------------------------------------------------------------------
1 | namespace OriginalCircuit.AltiumSharp.Records
2 | {
3 | public class SchSheetHeader : SchDocumentHeader
4 | {
5 | public override int Record => 31;
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/LibraryViewer/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/AltiumSharp/IComponent.cs:
--------------------------------------------------------------------------------
1 | namespace OriginalCircuit.AltiumSharp
2 | {
3 | public interface IComponent : IContainer
4 | {
5 | string Name { get; }
6 |
7 | string Description { get; }
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/AltiumSharp/Records/Sch/SchImplementationParameters.cs:
--------------------------------------------------------------------------------
1 | namespace OriginalCircuit.AltiumSharp.Records
2 | {
3 | public class SchImplementationParameters : SchPrimitive
4 | {
5 | public override int Record => 48;
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/LibraryViewer/Properties/Settings.settings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/AltiumSharp/IContainer.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using OriginalCircuit.AltiumSharp.BasicTypes;
3 |
4 | namespace OriginalCircuit.AltiumSharp
5 | {
6 | public interface IContainer
7 | {
8 | IEnumerable GetPrimitivesOfType(bool flatten = true) where T : Primitive;
9 |
10 | CoordRect CalculateBounds();
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/AltiumSharp/Records/Sch/SchBezier.cs:
--------------------------------------------------------------------------------
1 | using System.Drawing;
2 |
3 | namespace OriginalCircuit.AltiumSharp.Records
4 | {
5 | public class SchBezier : SchBasicPolyline
6 | {
7 | public override int Record => 5;
8 |
9 | public SchBezier() : base()
10 | {
11 | Color = ColorTranslator.FromWin32(255);
12 | }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/AltiumSharp/Records/Pcb/PcbFill.cs:
--------------------------------------------------------------------------------
1 | namespace OriginalCircuit.AltiumSharp.Records
2 | {
3 | public class PcbFill : PcbRectangularPrimitive
4 | {
5 | public override PcbPrimitiveDisplayInfo GetDisplayInfo() =>
6 | new PcbPrimitiveDisplayInfo("", Width, Height);
7 |
8 | public override PcbPrimitiveObjectId ObjectId => PcbPrimitiveObjectId.Fill;
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/AltiumSharp/Records/Sch/SchImplementationList.cs:
--------------------------------------------------------------------------------
1 | namespace OriginalCircuit.AltiumSharp.Records
2 | {
3 | public class SchImplementationList : SchPrimitive
4 | {
5 | public override int Record => 44;
6 | public override bool IsVisible => false;
7 |
8 | public SchImplementationList()
9 | {
10 | OwnerPartId = 0;
11 | }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/AltiumSharp/Records/Sch/SchDesignator.cs:
--------------------------------------------------------------------------------
1 | namespace OriginalCircuit.AltiumSharp.Records
2 | {
3 | public class SchDesignator : SchParameter
4 | {
5 | public override int Record => 34;
6 | public override bool IsVisible =>
7 | base.IsVisible && OwnerIndex > 0;
8 |
9 | public SchDesignator() : base()
10 | {
11 | ReadOnlyState = 1;
12 | }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/AltiumSharp/GlobalSuppressions.cs:
--------------------------------------------------------------------------------
1 |
2 | // This file is used by Code Analysis to maintain SuppressMessage
3 | // attributes that are applied to this project.
4 | // Project-level suppressions either have no target or are given
5 | // a specific target and scoped to a namespace, type, member, etc.
6 |
7 | [assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Globalization", "CA1303:Do not pass literals as localized parameters", Justification = "")]
8 |
9 |
--------------------------------------------------------------------------------
/AltiumSharp/Drawing/Extensions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Drawing;
4 | using System.Text;
5 |
6 | namespace OriginalCircuit.AltiumSharp.Drawing
7 | {
8 | internal static class RectangleFExtensions
9 | {
10 | public static RectangleF Inflated(this RectangleF rect, float x, float y)
11 | {
12 | var result = rect;
13 | result.Inflate(x, y);
14 | return result;
15 | }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/AltiumSharp/SchDoc.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Linq;
3 | using OriginalCircuit.AltiumSharp.BasicTypes;
4 | using OriginalCircuit.AltiumSharp.Records;
5 |
6 | namespace OriginalCircuit.AltiumSharp
7 | {
8 | public class SchDoc : SchData
9 | {
10 | public override SchSheetHeader Header => Items.OfType().SingleOrDefault();
11 |
12 | public SchDoc() : base()
13 | {
14 |
15 | }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/AltiumSharp/Records/Primitive.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Diagnostics;
3 | using OriginalCircuit.AltiumSharp.BasicTypes;
4 |
5 | namespace OriginalCircuit.AltiumSharp
6 | {
7 | public abstract class Primitive
8 | {
9 | public IEnumerable RawData { get; internal set; }
10 |
11 | public Primitive Owner { get; internal set; }
12 |
13 | [Conditional("DEBUG")]
14 | internal void SetRawData(in byte[] rawData) => RawData = rawData;
15 |
16 | public abstract CoordRect CalculateBounds();
17 |
18 | public virtual bool IsVisible => Owner?.IsVisible ?? true;
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/LibraryViewer/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading.Tasks;
5 | using System.Windows.Forms;
6 |
7 | namespace LibraryViewer
8 | {
9 | static class Program
10 | {
11 | ///
12 | /// The main entry point for the application.
13 | ///
14 | [STAThread]
15 | static void Main()
16 | {
17 | Application.EnableVisualStyles();
18 | Application.SetHighDpiMode(HighDpiMode.SystemAware);
19 | Application.SetCompatibleTextRenderingDefault(false);
20 | Application.Run(new Main());
21 | }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/AltiumSharp/Records/Pcb/PcbRegion.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Linq;
3 | using OriginalCircuit.AltiumSharp.BasicTypes;
4 |
5 | namespace OriginalCircuit.AltiumSharp.Records
6 | {
7 | public class PcbRegion : PcbPrimitive
8 | {
9 | public override PcbPrimitiveObjectId ObjectId => PcbPrimitiveObjectId.Region;
10 | public ParameterCollection Parameters { get; internal set; } = new ParameterCollection();
11 | public List Outline { get; } = new List();
12 |
13 | public override CoordRect CalculateBounds()
14 | {
15 | return new CoordRect(
16 | new CoordPoint(Outline.Min(p => p.X), Outline.Min(p => p.Y)),
17 | new CoordPoint(Outline.Max(p => p.X), Outline.Max(p => p.Y)));
18 | }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/AltiumSharp/Records/Pcb/PcbArc.cs:
--------------------------------------------------------------------------------
1 | using OriginalCircuit.AltiumSharp.BasicTypes;
2 |
3 | namespace OriginalCircuit.AltiumSharp.Records
4 | {
5 | public class PcbArc : PcbPrimitive
6 | {
7 | public override PcbPrimitiveObjectId ObjectId => PcbPrimitiveObjectId.Arc;
8 | public CoordPoint Location { get; set; }
9 | public Coord Radius { get; set; }
10 | public double StartAngle { get; set; }
11 | public double EndAngle { get; set; }
12 | public Coord Width { get; set; }
13 |
14 | public PcbArc() : base()
15 | {
16 | Radius = Utils.DxpFracToCoord(10, 0);
17 | StartAngle = 0;
18 | EndAngle = 360;
19 | }
20 |
21 | public override CoordRect CalculateBounds()
22 | {
23 | return new CoordRect(Location.X - Radius, Location.Y - Radius, Radius * 2, Radius * 2);
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/AltiumSharp/Records/Sch/SchTemplate.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using OriginalCircuit.AltiumSharp.BasicTypes;
3 |
4 | namespace OriginalCircuit.AltiumSharp.Records
5 | {
6 | public class SchTemplate : SchGraphicalObject
7 | {
8 | public override int Record => 39;
9 | public string FileName { get; set; }
10 |
11 | public override void ImportFromParameters(ParameterCollection p)
12 | {
13 | if (p == null) throw new ArgumentNullException(nameof(p));
14 |
15 | base.ImportFromParameters(p);
16 | FileName = p["FILENAME"].AsStringOrDefault();
17 | }
18 |
19 | public override void ExportToParameters(ParameterCollection p)
20 | {
21 | if (p == null) throw new ArgumentNullException(nameof(p));
22 |
23 | base.ExportToParameters(p);
24 |
25 | p.Add("FILENAME", FileName);
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/AltiumSharp/SchData.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using OriginalCircuit.AltiumSharp.Records;
3 |
4 | namespace OriginalCircuit.AltiumSharp
5 | {
6 | public abstract class SchData
7 | {
8 | ///
9 | /// Name of the file.
10 | ///
11 | internal string FileName { get; set; }
12 | }
13 |
14 | public abstract class SchData : SchData
15 | where THeader : SchDocumentHeader
16 | where TItem : SchPrimitive
17 | {
18 | ///
19 | /// Header information for the schematic file.
20 | ///
21 | public abstract THeader Header { get; }
22 |
23 | ///
24 | /// List of items present the file.
25 | ///
26 | public List Items { get; } = new List();
27 |
28 | protected SchData()
29 | {
30 |
31 | }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/AltiumSharp/Records/Pcb/PcbRectangularPrimitive.cs:
--------------------------------------------------------------------------------
1 | using OriginalCircuit.AltiumSharp.BasicTypes;
2 |
3 | namespace OriginalCircuit.AltiumSharp.Records
4 | {
5 | public abstract class PcbRectangularPrimitive : PcbPrimitive
6 | {
7 | public CoordPoint Corner1 { get; set; }
8 | public CoordPoint Corner2 { get; set; }
9 | public double Rotation { get; set; }
10 |
11 | public Coord Width
12 | {
13 | get => Corner2.X - Corner1.X;
14 | set => Corner2 = new CoordPoint(Corner1.X + value, Corner2.Y);
15 | }
16 |
17 | public Coord Height {
18 | get => Corner2.Y - Corner1.Y;
19 | set => Corner2 = new CoordPoint(Corner1.X, Corner1.Y + value);
20 | }
21 |
22 | public override CoordRect CalculateBounds()
23 | {
24 | return CoordRect.FromRotatedRect(new CoordRect(Corner1, Corner2), Corner1, Rotation);
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/AltiumSharp/Records/Sch/SchBasicPolyline.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using OriginalCircuit.AltiumSharp.BasicTypes;
3 |
4 | namespace OriginalCircuit.AltiumSharp.Records
5 | {
6 | public enum LineStyle
7 | {
8 | Solid, Dashed, Dotted
9 | }
10 |
11 | public abstract class SchBasicPolyline : SchPolygon
12 | {
13 | public LineStyle LineStyle { get; internal set; }
14 |
15 | public override void ImportFromParameters(ParameterCollection p)
16 | {
17 | if (p == null) throw new ArgumentNullException(nameof(p));
18 |
19 | base.ImportFromParameters(p);
20 | LineStyle = p["LINESTYLE"].AsEnumOrDefault();
21 | }
22 |
23 | public override void ExportToParameters(ParameterCollection p)
24 | {
25 | if (p == null) throw new ArgumentNullException(nameof(p));
26 |
27 | base.ExportToParameters(p);
28 | p.SetBookmark();
29 | p.Add("LINESTYLE", LineStyle);
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/LibraryViewer/LibraryViewer.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | net6.0-windows
4 | WinExe
5 | false
6 | true
7 | true
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 | all
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/AltiumSharp/PcbLib.cs:
--------------------------------------------------------------------------------
1 | using System.Collections;
2 | using System.Collections.Generic;
3 | using OriginalCircuit.AltiumSharp.Records;
4 |
5 | namespace OriginalCircuit.AltiumSharp
6 | {
7 | public class PcbLib : PcbData, IEnumerable
8 | {
9 | ///
10 | /// UniqueId from the binary FileHeader entry
11 | ///
12 | public string UniqueId { get; internal set; }
13 |
14 | public PcbLib() : base()
15 | {
16 |
17 | }
18 |
19 | public void Add(PcbComponent component)
20 | {
21 | if (component == null) return;
22 |
23 | if (string.IsNullOrEmpty(component.Pattern))
24 | {
25 | component.Pattern = $"Component_{Items.Count + 1}";
26 | }
27 |
28 | Items.Add(component);
29 | }
30 |
31 | IEnumerator IEnumerable.GetEnumerator() => Items.GetEnumerator();
32 | IEnumerator IEnumerable.GetEnumerator() => Items.GetEnumerator();
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/AltiumSharp/SchLib.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections;
3 | using System.Collections.Generic;
4 | using OriginalCircuit.AltiumSharp.Records;
5 |
6 | namespace OriginalCircuit.AltiumSharp
7 | {
8 | public class SchLib : SchData, IEnumerable
9 | {
10 | public override SchLibHeader Header { get; }
11 |
12 | public SchLib() : base()
13 | {
14 | Header = new SchLibHeader(Items);
15 | }
16 |
17 | public void Add(SchComponent component)
18 | {
19 | if (component == null)
20 | throw new ArgumentNullException(nameof(component));
21 |
22 | if (string.IsNullOrEmpty(component.LibReference))
23 | {
24 | component.LibReference = $"Component_{Items.Count+1}";
25 | }
26 |
27 | Items.Add(component);
28 | }
29 |
30 | IEnumerator IEnumerable.GetEnumerator() => Items.GetEnumerator();
31 | IEnumerator IEnumerable.GetEnumerator() => Items.GetEnumerator();
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/AltiumSharp/Records/Sch/SchPie.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Drawing;
3 | using OriginalCircuit.AltiumSharp.BasicTypes;
4 |
5 | namespace OriginalCircuit.AltiumSharp.Records
6 | {
7 | public class SchPie : SchArc
8 | {
9 | public override int Record => 9;
10 | public bool IsSolid { get; set; }
11 |
12 | public SchPie() : base()
13 | {
14 | Color = ColorTranslator.FromWin32(16711680);
15 | AreaColor = ColorTranslator.FromWin32(12632256);
16 | IsSolid = true;
17 | }
18 |
19 | public override void ImportFromParameters(ParameterCollection p)
20 | {
21 | if (p == null) throw new ArgumentNullException(nameof(p));
22 |
23 | base.ImportFromParameters(p);
24 | IsSolid = p["ISSOLID"].AsBool();
25 | }
26 |
27 | public override void ExportToParameters(ParameterCollection p)
28 | {
29 | if (p == null) throw new ArgumentNullException(nameof(p));
30 |
31 | base.ExportToParameters(p);
32 | p.Add("ISSOLID", IsSolid);
33 | }
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/LibraryViewer/Properties/Settings.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.42000
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace LibraryViewer.Properties
12 | {
13 |
14 |
15 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
16 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
17 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
18 | {
19 |
20 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
21 |
22 | public static Settings Default
23 | {
24 | get
25 | {
26 | return defaultInstance;
27 | }
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/AltiumSharp/PcbData.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Drawing;
3 | using OriginalCircuit.AltiumSharp.Records;
4 |
5 | namespace OriginalCircuit.AltiumSharp
6 | {
7 | public abstract class PcbData
8 | {
9 | ///
10 | /// Name of the file.
11 | ///
12 | internal string FileName { get; private set; }
13 |
14 | ///
15 | /// Mapping of image file names to the actual image data for
16 | /// embedded images.
17 | ///
18 | public Dictionary EmbeddedImages { get; } = new Dictionary();
19 | }
20 |
21 | public abstract class PcbData : PcbData
22 | where THeader : new()
23 | where TItem : IContainer, new()
24 | {
25 | ///
26 | /// Header information for the schematic file.
27 | ///
28 | public THeader Header { get; } = new THeader();
29 |
30 | ///
31 | /// List of items present the file.
32 | ///
33 | public List Items { get; } = new List();
34 |
35 | protected PcbData()
36 | {
37 |
38 | }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/AltiumSharp/Records/Sch/SchJunction.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using OriginalCircuit.AltiumSharp.BasicTypes;
3 |
4 | namespace OriginalCircuit.AltiumSharp.Records
5 | {
6 | internal class SchJunction : SchGraphicalObject
7 | {
8 | public override int Record => 29;
9 | public LineWidth Size { get; set; }
10 | public bool IsManualJunction { get; set; }
11 |
12 | public override CoordRect CalculateBounds() =>
13 | new CoordRect(Location.X - Utils.DxpToCoord(2), Location.Y - Utils.DxpToCoord(2), Utils.DxpToCoord(4), Utils.DxpToCoord(4));
14 |
15 | public override void ImportFromParameters(ParameterCollection p)
16 | {
17 | if (p == null) throw new ArgumentNullException(nameof(p));
18 |
19 | base.ImportFromParameters(p);
20 | Size = p["SIZE"].AsEnumOrDefault();
21 | IsManualJunction = p["LOCKED"].AsBool();
22 | }
23 |
24 | public override void ExportToParameters(ParameterCollection p)
25 | {
26 | if (p == null) throw new ArgumentNullException(nameof(p));
27 |
28 | base.ExportToParameters(p);
29 | p.Add("SIZE", Size);
30 | p.Add("LOCKED", IsManualJunction);
31 | }
32 | }
33 | }
--------------------------------------------------------------------------------
/AltiumSharp/SchDocReader.cs:
--------------------------------------------------------------------------------
1 | namespace OriginalCircuit.AltiumSharp
2 | {
3 | ///
4 | /// Schematic document reader.
5 | ///
6 | public sealed class SchDocReader : SchReader
7 | {
8 | public SchDocReader() : base()
9 | {
10 | }
11 |
12 | protected override void DoRead()
13 | {
14 | ReadFileHeader();
15 |
16 | var embeddedImages = ReadStorageEmbeddedImages();
17 | SetEmbeddedImages(Data.Items, embeddedImages);
18 | }
19 |
20 | ///
21 | /// Reads the "FileHeader" section which contains the primitives that
22 | /// exist in the current document.
23 | ///
24 | private void ReadFileHeader()
25 | {
26 | BeginContext("FileHeader");
27 |
28 | using (var reader = Cf.GetStream("FileHeader").GetBinaryReader())
29 | {
30 | var parameters = ReadBlock(reader, size => ReadParameters(reader, size));
31 | var weight = parameters["WEIGHT"].AsIntOrDefault();
32 |
33 | var primitives = ReadPrimitives(reader, null, null, null, null);
34 | Data.Items.AddRange(primitives);
35 |
36 | AssignOwners(primitives);
37 | }
38 |
39 | EndContext();
40 | }
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/AltiumSharp/Records/Sch/SchImage.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Drawing;
3 | using OriginalCircuit.AltiumSharp.BasicTypes;
4 |
5 | namespace OriginalCircuit.AltiumSharp.Records
6 | {
7 | public class SchImage : SchRectangle
8 | {
9 | public override int Record => 30;
10 | public bool KeepAspect { get; set; }
11 | public bool EmbedImage { get; set; }
12 | public string Filename { get; set; }
13 | public Image Image { get; set; }
14 |
15 | public SchImage() : base()
16 | {
17 | KeepAspect = true;
18 | EmbedImage = true;
19 | }
20 |
21 | public override void ImportFromParameters(ParameterCollection p)
22 | {
23 | if (p == null) throw new ArgumentNullException(nameof(p));
24 |
25 | base.ImportFromParameters(p);
26 | KeepAspect = p["KEEPASPECT"].AsBool();
27 | EmbedImage = p["EMBEDIMAGE"].AsBool();
28 | Filename = p["FILENAME"].AsStringOrDefault();
29 | }
30 |
31 | public override void ExportToParameters(ParameterCollection p)
32 | {
33 | if (p == null) throw new ArgumentNullException(nameof(p));
34 |
35 | base.ExportToParameters(p);
36 | p.Add("KEEPASPECT", KeepAspect);
37 | p.Add("EMBEDIMAGE", EmbedImage);
38 | p.Add("FILENAME", Filename);
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/AltiumSharp/Records/Sch/SchPolyline.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using OriginalCircuit.AltiumSharp.BasicTypes;
3 |
4 | namespace OriginalCircuit.AltiumSharp.Records
5 | {
6 | public enum LineShape
7 | {
8 | None, Arrow, SolidArrow, Tail, SolidTail, Circle, Square
9 | }
10 |
11 | public class SchPolyline : SchBasicPolyline
12 | {
13 | public override int Record => 6;
14 | public LineShape StartLineShape { get; set; }
15 | public LineShape EndLineShape { get; set; }
16 | public int LineShapeSize { get; set; }
17 |
18 | public override void ImportFromParameters(ParameterCollection p)
19 | {
20 | if (p == null) throw new ArgumentNullException(nameof(p));
21 |
22 | base.ImportFromParameters(p);
23 | StartLineShape = p["STARTLINESHAPE"].AsEnumOrDefault();
24 | EndLineShape = p["ENDLINESHAPE"].AsEnumOrDefault();
25 | LineShapeSize = p["LINESHAPESIZE"].AsIntOrDefault();
26 | }
27 |
28 | public override void ExportToParameters(ParameterCollection p)
29 | {
30 | if (p == null) throw new ArgumentNullException(nameof(p));
31 |
32 | base.ExportToParameters(p);
33 | p.Add("STARTLINESHAPE", StartLineShape);
34 | p.Add("ENDLINESHAPE", EndLineShape);
35 | p.Add("LINESHAPESIZE", LineShapeSize);
36 | p.MoveKeys("COLOR");
37 | }
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/AltiumSharp/Records/Sch/SchSymbol.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using OriginalCircuit.AltiumSharp.BasicTypes;
3 |
4 | namespace OriginalCircuit.AltiumSharp.Records
5 | {
6 | public class SchSymbol : SchGraphicalObject
7 | {
8 | public override int Record => 3;
9 | public int Symbol { get; set; }
10 | public bool IsMirrored { get; set; }
11 | public LineWidth LineWidth { get; set; }
12 | public int ScaleFactor { get; set; }
13 |
14 | public override void ImportFromParameters(ParameterCollection p)
15 | {
16 | if (p == null) throw new ArgumentNullException(nameof(p));
17 |
18 | base.ImportFromParameters(p);
19 | Symbol = p["SYMBOL"].AsIntOrDefault();
20 | IsMirrored = p["ISMIRRORED"].AsBool();
21 | LineWidth = p["LINEWIDTH"].AsEnumOrDefault();
22 | ScaleFactor = p["SCALEFACTOR"].AsIntOrDefault();
23 | }
24 |
25 | public override void ExportToParameters(ParameterCollection p)
26 | {
27 | if (p == null) throw new ArgumentNullException(nameof(p));
28 |
29 | base.ExportToParameters(p);
30 | p.SetBookmark();
31 | p.Add("SYMBOL", Symbol);
32 | p.Add("ISMIRRORED", IsMirrored);
33 | p.Add("LINEWIDTH", LineWidth);
34 | p.MoveKeys("LOCATION.X");
35 | p.Add("SCALEFACTOR", ScaleFactor);
36 | p.MoveKeys("COLOR");
37 | }
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/AltiumSharp/Records/Sch/SchEllipse.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using OriginalCircuit.AltiumSharp.BasicTypes;
3 |
4 | namespace OriginalCircuit.AltiumSharp.Records
5 | {
6 | public class SchEllipse : SchCircle
7 | {
8 | public override int Record => 8;
9 | public Coord SecondaryRadius { get; set; }
10 |
11 | public SchEllipse() : base()
12 | {
13 | Radius = 20;
14 | SecondaryRadius = 10;
15 | }
16 |
17 | public override CoordRect CalculateBounds() =>
18 | new CoordRect(Location.X - Radius, Location.Y - SecondaryRadius, Radius * 2, SecondaryRadius * 2);
19 |
20 | public override void ImportFromParameters(ParameterCollection p)
21 | {
22 | if (p == null) throw new ArgumentNullException(nameof(p));
23 |
24 | base.ImportFromParameters(p);
25 | SecondaryRadius = Utils.DxpFracToCoord(p["SECONDARYRADIUS"].AsIntOrDefault(), p["SECONDARYRADIUS_FRAC"].AsIntOrDefault());
26 | }
27 |
28 | public override void ExportToParameters(ParameterCollection p)
29 | {
30 | if (p == null) throw new ArgumentNullException(nameof(p));
31 |
32 | base.ExportToParameters(p);
33 | p.SetBookmark();
34 | {
35 | var (n, f) = Utils.CoordToDxpFrac(SecondaryRadius);
36 | p.Add("SECONDARYRADIUS", n);
37 | p.Add("SECONDARYRADIUS_FRAC", f);
38 | }
39 | p.MoveKeys("COLOR");
40 | }
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/AltiumSharp/Records/Sch/SchEllipticalArc.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using OriginalCircuit.AltiumSharp.BasicTypes;
3 |
4 | namespace OriginalCircuit.AltiumSharp.Records
5 | {
6 | public class SchEllipticalArc : SchArc
7 | {
8 | public override int Record => 11;
9 | public Coord SecondaryRadius { get; set; }
10 |
11 | public SchEllipticalArc() : base()
12 | {
13 | Radius = Utils.DxpFracToCoord(10, 0);
14 | }
15 |
16 | public override CoordRect CalculateBounds() =>
17 | new CoordRect(Location.X - Radius, Location.Y - SecondaryRadius, Radius * 2, SecondaryRadius * 2);
18 |
19 | public override void ImportFromParameters(ParameterCollection p)
20 | {
21 | if (p == null) throw new ArgumentNullException(nameof(p));
22 |
23 | base.ImportFromParameters(p);
24 | SecondaryRadius = Utils.DxpFracToCoord(p["SECONDARYRADIUS"].AsIntOrDefault(), p["SECONDARYRADIUS_FRAC"].AsIntOrDefault());
25 | }
26 |
27 | public override void ExportToParameters(ParameterCollection p)
28 | {
29 | if (p == null) throw new ArgumentNullException(nameof(p));
30 |
31 | base.ExportToParameters(p);
32 | p.SetBookmark();
33 | {
34 | var (n, f) = Utils.CoordToDxpFrac(SecondaryRadius);
35 | p.Add("SECONDARYRADIUS", n);
36 | p.Add("SECONDARYRADIUS_FRAC", f);
37 | }
38 | p.MoveKeys("LINEWIDTH");
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/LibraryViewer/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("LibraryViewer")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("LibraryViewer")]
13 | [assembly: AssemblyCopyright("Copyright © 2019")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("42247288-afc2-4590-80ca-702468b40ce4")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 |
--------------------------------------------------------------------------------
/AltiumSharp/BasicTypes/CoordPoint.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace OriginalCircuit.AltiumSharp.BasicTypes
4 | {
5 | public readonly struct CoordPoint : IEquatable
6 | {
7 | public static readonly CoordPoint Zero = new CoordPoint();
8 |
9 | public Coord X { get; }
10 | public Coord Y { get; }
11 | public CoordPoint(Coord x, Coord y) => (X, Y) = (x, y);
12 | public void Deconstruct(out Coord x, out Coord y) => (x, y) = (X, Y);
13 |
14 | public static CoordPoint FromMils(double milsX, double milsY) =>
15 | new CoordPoint(Coord.FromMils(milsX), Coord.FromMils(milsY));
16 | public static CoordPoint FromMMs(double mmsX, double mmsY) =>
17 | new CoordPoint(Coord.FromMMs(mmsX), Coord.FromMMs(mmsY));
18 |
19 | public override string ToString() => $"X:{X} Y:{Y}";
20 | public string ToString(Unit unit) => $"X:{X.ToString(unit)} Y:{Y.ToString(unit)}";
21 | public string ToString(Unit unit, Coord grid) => $"X:{X.ToString(unit, grid)} Y:{Y.ToString(unit, grid)}";
22 |
23 | #region 'boilerplate'
24 | public override bool Equals(object obj) => obj is CoordPoint other && Equals(other);
25 | public bool Equals(CoordPoint other) => X == other.X && Y == other.Y;
26 | public override int GetHashCode() => X.GetHashCode() ^ Y.GetHashCode();
27 | public static bool operator ==(CoordPoint left, CoordPoint right) => left.Equals(right);
28 | public static bool operator !=(CoordPoint left, CoordPoint right) => !(left == right);
29 | #endregion
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/AltiumSharp/Records/Sch/SchRoundedRectangle.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using OriginalCircuit.AltiumSharp.BasicTypes;
3 |
4 | namespace OriginalCircuit.AltiumSharp.Records
5 | {
6 | public class SchRoundedRectangle : SchRectangle
7 | {
8 | public override int Record => 10;
9 | public Coord CornerXRadius { get; set; }
10 | public Coord CornerYRadius { get; set; }
11 |
12 | public override void ImportFromParameters(ParameterCollection p)
13 | {
14 | if (p == null) throw new ArgumentNullException(nameof(p));
15 |
16 | base.ImportFromParameters(p);
17 | CornerXRadius = Utils.DxpFracToCoord(p["CORNERXRADIUS"].AsIntOrDefault(), p["CORNERXRADIUS_FRAC"].AsIntOrDefault());
18 | CornerYRadius = Utils.DxpFracToCoord(p["CORNERYRADIUS"].AsIntOrDefault(), p["CORNERYRADIUS_FRAC"].AsIntOrDefault());
19 | }
20 |
21 | public override void ExportToParameters(ParameterCollection p)
22 | {
23 | if (p == null) throw new ArgumentNullException(nameof(p));
24 |
25 | base.ExportToParameters(p);
26 | p.SetBookmark();
27 | {
28 | var (n, f) = Utils.CoordToDxpFrac(CornerXRadius);
29 | p.Add("CORNERXRADIUS", n);
30 | p.Add("CORNERXRADIUS_FRAC", f);
31 | }
32 | {
33 | var (n, f) = Utils.CoordToDxpFrac(CornerYRadius);
34 | p.Add("CORNERYRADIUS", n);
35 | p.Add("CORNERYRADIUS_FRAC", f);
36 | }
37 | p.MoveKeys("LINEWIDTH");
38 | }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/AltiumSharp/Records/Sch/SchMapDefiner.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using OriginalCircuit.AltiumSharp.BasicTypes;
5 |
6 | namespace OriginalCircuit.AltiumSharp.Records
7 | {
8 | public class SchMapDefiner : SchPrimitive
9 | {
10 | public override int Record => 47;
11 | public string DesignatorInterface { get; set; }
12 | public List DesignatorImplementation { get; private set; }
13 | public bool IsTrivial { get; set; }
14 |
15 | public override void ImportFromParameters(ParameterCollection p)
16 | {
17 | if (p == null) throw new ArgumentNullException(nameof(p));
18 |
19 | base.ImportFromParameters(p);
20 | DesignatorInterface = p["DESINTF"].AsStringOrDefault();
21 | DesignatorImplementation = Enumerable.Range(0, p["DESIMPCOUNT"].AsIntOrDefault())
22 | .Select(i =>
23 | p[$"DESIMP{i}"].AsStringOrDefault())
24 | .ToList();
25 | IsTrivial = p["ISTRIVIAL"].AsBool();
26 | }
27 |
28 | public override void ExportToParameters(ParameterCollection p)
29 | {
30 | if (p == null) throw new ArgumentNullException(nameof(p));
31 |
32 | base.ExportToParameters(p);
33 | p.Add("DESINTF", DesignatorInterface);
34 | p.Add("DESIMPCOUNT", DesignatorImplementation.Count);
35 | for (var i = 0; i < DesignatorImplementation.Count; ++i)
36 | {
37 | p.Add($"DESIMP{i}", DesignatorImplementation[i]);
38 | }
39 | p.Add("ISTRIVIAL", IsTrivial);
40 | }
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/AltiumSharp.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 17
4 | VisualStudioVersion = 17.4.33103.184
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OriginalCircuit.AltiumSharp", "AltiumSharp\OriginalCircuit.AltiumSharp.csproj", "{56CE96A8-5463-44DA-89C6-7F30C37BC946}"
7 | EndProject
8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LibraryViewer", "LibraryViewer\LibraryViewer.csproj", "{42247288-AFC2-4590-80CA-702468B40CE4}"
9 | EndProject
10 | Global
11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
12 | Debug|Any CPU = Debug|Any CPU
13 | Release|Any CPU = Release|Any CPU
14 | EndGlobalSection
15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
16 | {56CE96A8-5463-44DA-89C6-7F30C37BC946}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
17 | {56CE96A8-5463-44DA-89C6-7F30C37BC946}.Debug|Any CPU.Build.0 = Debug|Any CPU
18 | {56CE96A8-5463-44DA-89C6-7F30C37BC946}.Release|Any CPU.ActiveCfg = Release|Any CPU
19 | {56CE96A8-5463-44DA-89C6-7F30C37BC946}.Release|Any CPU.Build.0 = Release|Any CPU
20 | {42247288-AFC2-4590-80CA-702468B40CE4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
21 | {42247288-AFC2-4590-80CA-702468B40CE4}.Debug|Any CPU.Build.0 = Debug|Any CPU
22 | {42247288-AFC2-4590-80CA-702468B40CE4}.Release|Any CPU.ActiveCfg = Release|Any CPU
23 | {42247288-AFC2-4590-80CA-702468B40CE4}.Release|Any CPU.Build.0 = Release|Any CPU
24 | EndGlobalSection
25 | GlobalSection(SolutionProperties) = preSolution
26 | HideSolutionNode = FALSE
27 | EndGlobalSection
28 | GlobalSection(ExtensibilityGlobals) = postSolution
29 | SolutionGuid = {3050039D-3F3C-4F17-9649-E6CA9AEB0E2B}
30 | EndGlobalSection
31 | EndGlobal
32 |
--------------------------------------------------------------------------------
/AltiumSharp/BasicTypes/CoordPoint3D.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace OriginalCircuit.AltiumSharp.BasicTypes
4 | {
5 | public readonly struct CoordPoint3D : IEquatable
6 | {
7 | public static readonly CoordPoint3D Zero = new CoordPoint3D();
8 |
9 | public Coord X { get; }
10 | public Coord Y { get; }
11 | public Coord Z { get; }
12 | public CoordPoint3D(Coord x, Coord y, Coord z) => (X, Y, Z) = (x, y, z);
13 | public void Deconstruct(out Coord x, out Coord y, out Coord z) => (x, y, z) = (X, Y, Z);
14 |
15 | public static CoordPoint3D FromMils(double milsX, double milsY, double milsZ) =>
16 | new CoordPoint3D(Coord.FromMils(milsX), Coord.FromMils(milsY), Coord.FromMils(milsZ));
17 | public static CoordPoint3D FromMMs(double mmsX, double mmsY, double mmsZ) =>
18 | new CoordPoint3D(Coord.FromMMs(mmsX), Coord.FromMMs(mmsY), Coord.FromMMs(mmsZ));
19 |
20 | public override string ToString() => $"X:{X} Y:{Y} Z:{Z}";
21 | public string ToString(Unit unit) => $"X:{X.ToString(unit)} Y:{Y.ToString(unit)} Z:{Z.ToString(unit)}";
22 | public string ToString(Unit unit, Coord grid) => $"X:{X.ToString(unit, grid)} Y:{Y.ToString(unit, grid)} Z:{Z.ToString(unit, grid)}";
23 |
24 | #region 'boilerplate'
25 | public override bool Equals(object obj) => obj is CoordPoint3D other && Equals(other);
26 | public bool Equals(CoordPoint3D other) => X == other.X && Y == other.Y && Z == other.Z;
27 | public override int GetHashCode() => X.GetHashCode() ^ Y.GetHashCode() ^ Z.GetHashCode();
28 | public static bool operator ==(CoordPoint3D left, CoordPoint3D right) => left.Equals(right);
29 | public static bool operator !=(CoordPoint3D left, CoordPoint3D right) => !(left == right);
30 | #endregion
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/AltiumSharp/Records/Sch/SchPowerObject.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using OriginalCircuit.AltiumSharp.BasicTypes;
3 |
4 | namespace OriginalCircuit.AltiumSharp.Records
5 | {
6 | public enum PowerPortStyle
7 | {
8 | Circle,
9 | Arrow,
10 | Bar,
11 | Wave,
12 | PowerGround,
13 | SignalGround,
14 | Earth,
15 | GostArrow,
16 | GostPowerGround,
17 | GostEarth,
18 | GostBar
19 | }
20 |
21 | public class SchPowerObject : SchLabel
22 | {
23 | public override int Record => 17;
24 | public PowerPortStyle Style { get; set; }
25 | public bool ShowNetName { get; set; }
26 | public bool IsCrossSheetConnector { get; set; }
27 |
28 | public override CoordRect CalculateBounds() =>
29 | new CoordRect(Location.X - Utils.DxpToCoord(2), Location.Y - Utils.DxpToCoord(2), Utils.DxpToCoord(4), Utils.DxpToCoord(4));
30 |
31 | public override void ImportFromParameters(ParameterCollection p)
32 | {
33 | if (p == null) throw new ArgumentNullException(nameof(p));
34 |
35 | base.ImportFromParameters(p);
36 | Style = p["STYLE"].AsEnumOrDefault();
37 | ShowNetName = p["SHOWNETNAME"].AsBool();
38 | IsCrossSheetConnector = p["ISCROSSSHEETCONNECTOR"].AsBool();
39 | }
40 |
41 | public override void ExportToParameters(ParameterCollection p)
42 | {
43 | if (p == null) throw new ArgumentNullException(nameof(p));
44 |
45 | base.ExportToParameters(p);
46 | p.SetBookmark();
47 | p.Add("STYLE", Style);
48 | p.Add("SHOWNETNAME", ShowNetName, false);
49 | p.MoveKeys("LOCATION.X");
50 | p.MoveKeys("TEXT");
51 | p.Add("ISCROSSSHEETCONNECTOR", IsCrossSheetConnector);
52 | }
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/AltiumSharp/Records/Sch/SchLine.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using OriginalCircuit.AltiumSharp.BasicTypes;
3 |
4 | namespace OriginalCircuit.AltiumSharp.Records
5 | {
6 | public class SchLine : SchGraphicalObject
7 | {
8 | public override int Record => 13;
9 | public CoordPoint Corner { get; set; }
10 | public LineWidth LineWidth { get; set; }
11 | public LineStyle LineStyle { get; set; }
12 |
13 | public override CoordRect CalculateBounds() =>
14 | new CoordRect(Location, Corner);
15 |
16 | public SchLine() : base()
17 | {
18 | LineWidth = LineWidth.Small;
19 | }
20 |
21 | public override void ImportFromParameters(ParameterCollection p)
22 | {
23 | if (p == null) throw new ArgumentNullException(nameof(p));
24 |
25 | base.ImportFromParameters(p);
26 | Corner = new CoordPoint(
27 | Utils.DxpFracToCoord(p["CORNER.X"].AsIntOrDefault(), p["CORNER.X_FRAC"].AsIntOrDefault()),
28 | Utils.DxpFracToCoord(p["CORNER.Y"].AsIntOrDefault(), p["CORNER.Y_FRAC"].AsIntOrDefault()));
29 | LineWidth = p["LINEWIDTH"].AsEnumOrDefault();
30 | LineStyle = p["LINESTYLE"].AsEnumOrDefault();
31 | }
32 |
33 | public override void ExportToParameters(ParameterCollection p)
34 | {
35 | if (p == null) throw new ArgumentNullException(nameof(p));
36 |
37 | base.ExportToParameters(p);
38 | {
39 | var (n, f) = Utils.CoordToDxpFrac(Corner.X);
40 | p.Add("CORNER.X", n);
41 | p.Add("CORNER.X_FRAC", f);
42 | }
43 | {
44 | var (n, f) = Utils.CoordToDxpFrac(Corner.Y);
45 | p.Add("CORNER.Y", n);
46 | p.Add("CORNER.Y_FRAC", f);
47 | }
48 | p.Add("LINEWIDTH", LineWidth);
49 | p.MoveKey("COLOR");
50 | p.Add("LINESTYLE", LineStyle);
51 | }
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/AltiumSharp/OriginalCircuit.AltiumSharp.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net6.0
5 | True
6 | AltiumSharp
7 | OriginalCircuit
8 | OriginalCircuit Limited
9 | Library for reading and writing Altium Designer files.
10 | Copyright 2020-2023 Original Circuit Limited. Released under MIT License
11 | https://github.com/issus/AltiumSharp
12 | README.md
13 | https://github.com/issus/AltiumSharp
14 | altium;schlib;pcblib;altium designer;eda;ecad
15 | MIT
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 | PreserveNewest
25 |
26 |
27 |
28 |
29 |
30 | True
31 | \
32 |
33 |
34 |
35 |
36 |
37 | all
38 | runtime; build; native; contentfiles; analyzers; buildtransitive
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 | PreserveNewest
48 |
49 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/AltiumSharp/Records/Pcb/PcbTrack.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using OriginalCircuit.AltiumSharp.BasicTypes;
5 |
6 | namespace OriginalCircuit.AltiumSharp.Records
7 | {
8 | public class PcbTrack : PcbPrimitive
9 | {
10 | public override PcbPrimitiveDisplayInfo GetDisplayInfo() =>
11 | new PcbPrimitiveDisplayInfo("", Width, null);
12 |
13 | public override PcbPrimitiveObjectId ObjectId => PcbPrimitiveObjectId.Track;
14 | public CoordPoint Start { get; set; }
15 | public CoordPoint End { get; set; }
16 | public Coord Width { get; set; }
17 |
18 | public PcbTrack() : base()
19 | {
20 | Width = Coord.FromMils(10);
21 | }
22 |
23 | public override CoordRect CalculateBounds()
24 | {
25 | return new CoordRect(Start, End);
26 | }
27 | }
28 |
29 | ///
30 | /// Helper class used for creating a multi-vertex track in one go.
31 | /// This can be used for creating a complex track with multiple point without
32 | /// having to manually create multiple track lines that have matching start and
33 | /// end property values.
34 | /// When this is added to a component multiple PcbTrack primitives are created
35 | /// in its place instead.
36 | ///
37 | public class PcbMetaTrack : PcbUnknown
38 | {
39 | public IList Vertices { get; }
40 | public Coord Width { get; set; }
41 |
42 | public PcbMetaTrack() : base(PcbPrimitiveObjectId.None)
43 | {
44 | Vertices = new List();
45 | Width = Coord.FromMils(10);
46 | }
47 |
48 | public PcbMetaTrack(params CoordPoint[] vertices) : this()
49 | {
50 | Vertices = vertices;
51 | }
52 |
53 | public override CoordRect CalculateBounds() => CoordRect.Empty;
54 |
55 | public IEnumerable> Lines =>
56 | Vertices.Zip(Vertices.Skip(1), Tuple.Create);
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/AltiumSharp/Records/Sch/SchCircle.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Drawing;
3 | using OriginalCircuit.AltiumSharp.BasicTypes;
4 |
5 | namespace OriginalCircuit.AltiumSharp.Records
6 | {
7 | public class SchCircle : SchGraphicalObject
8 | {
9 | public Coord Radius { get; internal set; }
10 | public LineWidth LineWidth { get; internal set; }
11 | public bool IsSolid { get; internal set; }
12 | public bool Transparent { get; internal set; }
13 |
14 | public SchCircle() : base()
15 | {
16 | Radius = 10;
17 | Color = ColorTranslator.FromWin32(16711680);
18 | AreaColor = ColorTranslator.FromWin32(12632256);
19 | IsSolid = true;
20 | }
21 |
22 | public override CoordRect CalculateBounds() =>
23 | new CoordRect(Location.X - Radius, Location.Y - Radius, Radius * 2, Radius * 2);
24 |
25 | public override void ImportFromParameters(ParameterCollection p)
26 | {
27 | if (p == null) throw new ArgumentNullException(nameof(p));
28 |
29 | base.ImportFromParameters(p);
30 | Radius = Utils.DxpFracToCoord(p["RADIUS"].AsIntOrDefault(), p["RADIUS_FRAC"].AsIntOrDefault());
31 | LineWidth = p["LINEWIDTH"].AsEnumOrDefault();
32 | IsSolid = p["ISSOLID"].AsBool();
33 | Transparent = p["TRANSPARENT"].AsBool();
34 | }
35 |
36 | public override void ExportToParameters(ParameterCollection p)
37 | {
38 | if (p == null) throw new ArgumentNullException(nameof(p));
39 |
40 | base.ExportToParameters(p);
41 | p.SetBookmark();
42 | {
43 | var (n, f) = Utils.CoordToDxpFrac(Radius);
44 | if (n != 0 || f != 0) p.Add("RADIUS", n);
45 | if (f != 0) p.Add("RADIUS" + "_FRAC", f);
46 | }
47 | p.Add("LINEWIDTH", LineWidth);
48 | p.MoveKeys("COLOR");
49 | p.Add("ISSOLID", IsSolid);
50 | p.Add("TRANSPARENT", Transparent);
51 | }
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/LibraryViewer/PropertyViewer.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.ComponentModel;
4 | using System.Data;
5 | using System.Drawing;
6 | using System.Linq;
7 | using System.Text;
8 | using System.Threading.Tasks;
9 | using System.Windows.Forms;
10 | using OriginalCircuit.AltiumSharp;
11 |
12 | namespace LibraryViewer
13 | {
14 | public partial class PropertyViewer : Form
15 | {
16 | private object[] _objects;
17 |
18 | internal event EventHandler Changed;
19 |
20 | public PropertyViewer()
21 | {
22 | InitializeComponent();
23 | }
24 |
25 | private void PropertyViewer_Load(object sender, EventArgs e)
26 | {
27 | CenterToParent();
28 | }
29 |
30 | internal void SetSelectedObjects(object[] objects)
31 | {
32 | _objects = objects;
33 | comboBoxObjects.BeginUpdate();
34 | comboBoxObjects.Items.Clear();
35 | if (_objects?.Length > 0)
36 | {
37 | if (_objects.Length != 1)
38 | {
39 | comboBoxObjects.Items.Add("");
40 | }
41 | comboBoxObjects.Items.AddRange(_objects);
42 | comboBoxObjects.SelectedIndex = 0;
43 | }
44 | else
45 | {
46 | comboBoxObjects.SelectedIndex = -1;
47 | }
48 | comboBoxObjects.EndUpdate();
49 | }
50 |
51 | private void ComboBoxObjects_SelectedIndexChanged(object sender, EventArgs e)
52 | {
53 | if (_objects.Length != 1 && comboBoxObjects.SelectedIndex < 1)
54 | {
55 | propertyGrid.SelectedObjects = _objects;
56 | }
57 | else
58 | {
59 | propertyGrid.SelectedObject = comboBoxObjects.SelectedItem;
60 | }
61 | }
62 |
63 | private void propertyGrid_PropertyValueChanged(object s, PropertyValueChangedEventArgs e)
64 | {
65 | Changed?.Invoke(this, EventArgs.Empty);
66 | }
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/AltiumSharp/Records/Sch/SchLabel.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Drawing;
3 | using OriginalCircuit.AltiumSharp.BasicTypes;
4 |
5 | namespace OriginalCircuit.AltiumSharp.Records
6 | {
7 | public class SchLabel : SchGraphicalObject
8 | {
9 | public override int Record => 4;
10 | public TextOrientations Orientation { get; set; }
11 | public TextJustification Justification { get; set; }
12 | public int FontId { get; set; }
13 | public string Text { get; set; }
14 | public bool IsMirrored { get; set; }
15 | public bool IsHidden { get; set; }
16 |
17 | internal virtual string DisplayText => Text ?? "";
18 | public override bool IsVisible => base.IsVisible && !IsHidden;
19 |
20 | public SchLabel() : base()
21 | {
22 | Color = ColorTranslator.FromWin32(8388608);
23 | FontId = 1;
24 | Text = "Text";
25 | }
26 |
27 | public override void ImportFromParameters(ParameterCollection p)
28 | {
29 | if (p == null) throw new ArgumentNullException(nameof(p));
30 |
31 | base.ImportFromParameters(p);
32 | Orientation = p["ORIENTATION"].AsEnumOrDefault();
33 | Justification = (TextJustification)p["JUSTIFICATION"].AsIntOrDefault();
34 | FontId = p["FONTID"].AsIntOrDefault();
35 | Text = p["TEXT"].AsStringOrDefault();
36 | IsMirrored = p["ISMIRRORED"].AsBool();
37 | IsHidden = p["ISHIDDEN"].AsBool();
38 | }
39 |
40 | public override void ExportToParameters(ParameterCollection p)
41 | {
42 | if (p == null) throw new ArgumentNullException(nameof(p));
43 |
44 | base.ExportToParameters(p);
45 | p.SetBookmark();
46 | p.Add("ORIENTATION", Orientation);
47 | p.Add("JUSTIFICATION", (int)Justification);
48 | p.MoveKeys("COLOR");
49 | p.Add("FONTID", FontId);
50 | p.Add("ISHIDDEN", IsHidden);
51 | p.Add("TEXT", Text);
52 | p.Add("ISMIRRORED", IsMirrored);
53 | }
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/AltiumSharp/Records/Sch/SchImplementation.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Globalization;
4 | using System.Linq;
5 | using OriginalCircuit.AltiumSharp.BasicTypes;
6 |
7 | namespace OriginalCircuit.AltiumSharp.Records
8 | {
9 | ///
10 | /// Model of a component.
11 | ///
12 | public class SchImplementation : SchPrimitive
13 | {
14 | public override int Record => 45;
15 | public string Description { get; set; }
16 | public string ModelName { get; set; }
17 | public string ModelType { get; set; }
18 | public List DataFile { get; internal set; }
19 | public bool IsCurrent { get; set; }
20 |
21 | public override void ImportFromParameters(ParameterCollection p)
22 | {
23 | if (p == null) throw new ArgumentNullException(nameof(p));
24 |
25 | base.ImportFromParameters(p);
26 | Description = p["DESCRIPTION"].AsStringOrDefault();
27 | ModelName = p["MODELNAME"].AsStringOrDefault();
28 | ModelType = p["MODELTYPE"].AsStringOrDefault();
29 | DataFile = Enumerable.Range(1, p["DATAFILECOUNT"].AsIntOrDefault())
30 | .Select(i =>
31 | p[string.Format(CultureInfo.InvariantCulture, "MODELDATAFILEKIND{0}", i)].AsStringOrDefault())
32 | .ToList();
33 | IsCurrent = p["ISCURRENT"].AsBool();
34 | }
35 |
36 | public override void ExportToParameters(ParameterCollection p)
37 | {
38 | if (p == null) throw new ArgumentNullException(nameof(p));
39 |
40 | base.ExportToParameters(p);
41 | p.Add("DESCRIPTION", Description);
42 | p.Add("MODELNAME", ModelName);
43 | p.Add("MODELTYPE", ModelType);
44 | p.Add("DATAFILECOUNT", DataFile.Count);
45 | for (var i = 0; i < DataFile.Count; i++)
46 | {
47 | p.Add(string.Format(CultureInfo.InvariantCulture, "MODELDATAFILEKIND{0}", i), DataFile[i]);
48 | }
49 | p.Add("ISCURRENT", IsCurrent);
50 | }
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/AltiumSharp/SchDocWriter.cs:
--------------------------------------------------------------------------------
1 | using System.IO;
2 | using OriginalCircuit.AltiumSharp.BasicTypes;
3 |
4 | namespace OriginalCircuit.AltiumSharp
5 | {
6 | ///
7 | /// Schematic document writer.
8 | ///
9 | public sealed class SchDocWriter : SchWriter
10 | {
11 | public SchDocWriter() : base()
12 | {
13 |
14 | }
15 |
16 | protected override void DoWrite(string fileName)
17 | {
18 | WriteFileHeader();
19 | WriteAdditional();
20 |
21 | var embeddedImages = GetEmbeddedImages(Data.Items);
22 | WriteStorageEmbeddedImages(embeddedImages);
23 | }
24 |
25 | ///
26 | /// Writes the "FileHeader" section which contains the primitives that
27 | /// exist in the current document.
28 | ///
29 | private void WriteFileHeader()
30 | {
31 | Cf.RootStorage.GetOrAddStream("FileHeader").Write(writer =>
32 | {
33 | var parameters = new ParameterCollection
34 | {
35 | { "HEADER", "Protel for Windows - Schematic Capture Binary File Version 5.0" },
36 | { "WEIGHT", Data.Items.Count }
37 | };
38 | WriteBlock(writer, w => WriteParameters(w, parameters));
39 |
40 | WritePrimitives(writer);
41 | });
42 | }
43 |
44 | private void WritePrimitives(BinaryWriter writer)
45 | {
46 | var index = 0;
47 | var pinIndex = 0;
48 | WritePrimitive(writer, Data.Header, false, 0, ref index, ref pinIndex,
49 | null, null, null, null);
50 | }
51 |
52 | private void WriteAdditional()
53 | {
54 | Cf.RootStorage.GetOrAddStream("Additional").Write(writer =>
55 | {
56 | var parameters = new ParameterCollection
57 | {
58 | { "HEADER", "Protel for Windows - Schematic Capture Binary File Version 5.0" }
59 | };
60 | WriteBlock(writer, w => WriteParameters(w, parameters));
61 | });
62 | }
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/AltiumSharp/Records/Sch/SchArc.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Drawing;
3 | using OriginalCircuit.AltiumSharp.BasicTypes;
4 |
5 | namespace OriginalCircuit.AltiumSharp.Records
6 | {
7 | public class SchArc : SchGraphicalObject
8 | {
9 | public override int Record => 12;
10 | public Coord Radius { get; set; }
11 | public LineWidth LineWidth { get; set; }
12 | public double StartAngle { get; set; }
13 | public double EndAngle { get; set; }
14 |
15 | public override CoordRect CalculateBounds() =>
16 | new CoordRect(Location.X - Radius, Location.Y - Radius, Radius * 2, Radius * 2);
17 |
18 | public SchArc() : base()
19 | {
20 | LineWidth = LineWidth.Small;
21 | Radius = Utils.DxpFracToCoord(10, 0);
22 | EndAngle = 360.0;
23 | Color = ColorTranslator.FromWin32(16711680);
24 | }
25 |
26 | public override void ImportFromParameters(ParameterCollection p)
27 | {
28 | if (p == null) throw new ArgumentNullException(nameof(p));
29 |
30 | base.ImportFromParameters(p);
31 | Location = new CoordPoint(
32 | Utils.DxpFracToCoord(p["LOCATION.X"].AsIntOrDefault(), p["LOCATION.X_FRAC"].AsIntOrDefault()),
33 | Utils.DxpFracToCoord(p["LOCATION.Y"].AsIntOrDefault(), p["LOCATION.Y_FRAC"].AsIntOrDefault()));
34 | Radius = Utils.DxpFracToCoord(p["RADIUS"].AsIntOrDefault(), p["RADIUS_FRAC"].AsIntOrDefault());
35 | LineWidth = p["LINEWIDTH"].AsEnumOrDefault();
36 | StartAngle = p["STARTANGLE"].AsDoubleOrDefault();
37 | EndAngle = p["ENDANGLE"].AsDoubleOrDefault();
38 | }
39 |
40 | public override void ExportToParameters(ParameterCollection p)
41 | {
42 | if (p == null) throw new ArgumentNullException(nameof(p));
43 |
44 | base.ExportToParameters(p);
45 | p.SetBookmark();
46 | {
47 | var (n, f) = Utils.CoordToDxpFrac(Radius);
48 | p.Add("RADIUS", n);
49 | p.Add("RADIUS_FRAC", f);
50 | }
51 | p.Add("LINEWIDTH", LineWidth);
52 | p.Add("STARTANGLE", StartAngle);
53 | p.Add("ENDANGLE", EndAngle);
54 | p.MoveKeys("COLOR");
55 | }
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/AltiumSharp/Records/Sch/SchRectangle.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Drawing;
3 | using OriginalCircuit.AltiumSharp.BasicTypes;
4 |
5 | namespace OriginalCircuit.AltiumSharp.Records
6 | {
7 | public class SchRectangle : SchGraphicalObject
8 | {
9 | public override int Record => 14;
10 | public CoordPoint Corner { get; set; }
11 | public LineWidth LineWidth { get; set; }
12 | public bool IsSolid { get; set; }
13 | public bool Transparent { get; set; }
14 |
15 | public override CoordRect CalculateBounds() =>
16 | new CoordRect(Location, Corner);
17 |
18 | public SchRectangle() : base()
19 | {
20 | Corner = new CoordPoint(Utils.DxpFracToCoord(50, 0), Utils.DxpFracToCoord(50, 0));
21 | Color = ColorTranslator.FromWin32(128);
22 | AreaColor = ColorTranslator.FromWin32(11599871);
23 | IsSolid = true;
24 | }
25 |
26 | public override void ImportFromParameters(ParameterCollection p)
27 | {
28 | if (p == null) throw new ArgumentNullException(nameof(p));
29 |
30 | base.ImportFromParameters(p);
31 | Corner = new CoordPoint(
32 | Utils.DxpFracToCoord(p["CORNER.X"].AsIntOrDefault(), p["CORNER.X_FRAC"].AsIntOrDefault()),
33 | Utils.DxpFracToCoord(p["CORNER.Y"].AsIntOrDefault(), p["CORNER.Y_FRAC"].AsIntOrDefault()));
34 | LineWidth = p["LINEWIDTH"].AsEnumOrDefault();
35 | IsSolid = p["ISSOLID"].AsBool();
36 | Transparent = p["TRANSPARENT"].AsBool();
37 | }
38 |
39 | public override void ExportToParameters(ParameterCollection p)
40 | {
41 | if (p == null) throw new ArgumentNullException(nameof(p));
42 |
43 | base.ExportToParameters(p);
44 | p.SetBookmark();
45 | {
46 | var (n, f) = Utils.CoordToDxpFrac(Corner.X);
47 | p.Add("CORNER.X", n);
48 | p.Add("CORNER.X_FRAC", f);
49 | }
50 | {
51 | var (n, f) = Utils.CoordToDxpFrac(Corner.Y);
52 | p.Add("CORNER.Y", n);
53 | p.Add("CORNER.Y_FRAC", f);
54 | }
55 | p.Add("LINEWIDTH", LineWidth);
56 | p.MoveKeys("COLOR");
57 | p.Add("ISSOLID", IsSolid);
58 | p.Add("TRANSPARENT", Transparent);
59 | p.Add("UNIQUEID", Utils.GenerateUniqueId());
60 | }
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/AltiumSharp/Records/Sch/SchLibHeader.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using System.Collections.Generic;
4 | using OriginalCircuit.AltiumSharp.BasicTypes;
5 |
6 | namespace OriginalCircuit.AltiumSharp.Records
7 | {
8 | public class SchLibHeader : SchDocumentHeader
9 | {
10 | private IList _components;
11 |
12 | public static string Header => "Protel for Windows - Schematic Library Editor Binary File Version 5.0";
13 | public int MinorVersion { get; internal set; }
14 |
15 | public SchLibHeader(IList components)
16 | {
17 | _components = components;
18 |
19 | MinorVersion = 2;
20 | SheetStyle = 9;
21 | SheetNumberSpaceSize = 12;
22 | CustomX = 18000;
23 | CustomY = 18000;
24 | UseCustomSheet = true;
25 | ReferenceZonesOn = true;
26 | DisplayUnit = Unit.Mil;
27 | }
28 |
29 | public override void ImportFromParameters(ParameterCollection p)
30 | {
31 | if (p == null)
32 | throw new ArgumentNullException(nameof(p));
33 |
34 | var header = p["HEADER"].AsStringOrDefault();
35 | if (header == null || !string.Equals(header, Header, StringComparison.InvariantCultureIgnoreCase))
36 | throw new ArgumentOutOfRangeException($"{nameof(p)}[\"HEADER\"]");
37 |
38 | MinorVersion = p["MINORVERSION"].AsIntOrDefault();
39 |
40 | base.ImportFromParameters(p);
41 | }
42 |
43 | public override void ExportToParameters(ParameterCollection p)
44 | {
45 | if (p == null) throw new ArgumentNullException(nameof(p));
46 |
47 | p.Add("HEADER", Header);
48 | var totalPrimitiveCount = _components.Count +
49 | _components.SelectMany(e => e.GetAllPrimitives()).Count();
50 | p.Add("WEIGHT", totalPrimitiveCount + 1); // weight is the number of primitives + 1, for some reason
51 | p.Add("MINORVERSION", MinorVersion);
52 |
53 | base.ExportToParameters(p);
54 |
55 | p.Add("COMPCOUNT", _components.Count);
56 | for (var i = 0; i < _components.Count; ++i)
57 | {
58 | p.Add($"LIBREF{i}", _components[i].LibReference);
59 | p.Add($"COMPDESCR{i}", _components[i].ComponentDescription);
60 | p.Add($"PARTCOUNT{i}", _components[i].PartCount + 1); // part count is stored + 1
61 | }
62 | }
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/AltiumSharp/Records/Sch/SchTextFrame.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Drawing;
3 | using OriginalCircuit.AltiumSharp.BasicTypes;
4 |
5 | namespace OriginalCircuit.AltiumSharp.Records
6 | {
7 | public class SchTextFrame : SchRectangle
8 | {
9 | public override int Record => 28;
10 | public Color TextColor { get; set; }
11 | public int FontId { get; set; }
12 | public bool ShowBorder { get; set; }
13 | public int Alignment { get; set; }
14 | public bool WordWrap { get; set; }
15 | public bool ClipToRect { get; set; }
16 | public string Text { get; set; }
17 | public Coord TextMargin { get; set; }
18 |
19 | public SchTextFrame() : base()
20 | {
21 | Color = ColorTranslator.FromWin32(0);
22 | AreaColor = ColorTranslator.FromWin32(16777215);
23 | FontId = 1;
24 | IsSolid = true;
25 | Alignment = 1;
26 | WordWrap = true;
27 | ClipToRect = true;
28 | Text = "Text";
29 | TextMargin = Utils.DxpFracToCoord(0, 5);
30 | }
31 |
32 | public override void ImportFromParameters(ParameterCollection p)
33 | {
34 | if (p == null) throw new ArgumentNullException(nameof(p));
35 |
36 | base.ImportFromParameters(p);
37 | TextColor = p["TEXTCOLOR"].AsColorOrDefault();
38 | FontId = p["FONTID"].AsIntOrDefault();
39 | ShowBorder = p["SHOWBORDER"].AsBool();
40 | Alignment = p["ALIGNMENT"].AsIntOrDefault();
41 | WordWrap = p["WORDWRAP"].AsBool();
42 | ClipToRect = p["CLIPTORECT"].AsBool();
43 | Text = p["TEXT"].AsStringOrDefault();
44 | TextMargin = Utils.DxpFracToCoord(p["TEXTMARGIN"].AsIntOrDefault(), p["TEXTMARGIN_FRAC"].AsIntOrDefault(5));
45 | }
46 |
47 | public override void ExportToParameters(ParameterCollection p)
48 | {
49 | if (p == null) throw new ArgumentNullException(nameof(p));
50 |
51 | base.ExportToParameters(p);
52 | p.SetBookmark();
53 | p.Add("TEXTCOLOR", TextColor);
54 | p.Add("FONTID", FontId);
55 | p.MoveKeys("ISSOLID");
56 | p.Add("SHOWBORDER", ShowBorder);
57 | p.Add("ALIGNMENT", Alignment);
58 | p.Add("WORDWRAP", WordWrap);
59 | p.Add("CLIPTORECT", ClipToRect);
60 | p.Add("TEXT", Text);
61 | {
62 | var (n, f) = Utils.CoordToDxpFrac(TextMargin);
63 | p.Add("TEXTMARGIN.Y", n);
64 | p.Add("TEXTMARGIN_FRAC", f);
65 | }
66 | }
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/AltiumSharp/Records/Sch/SchPolygon.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using OriginalCircuit.AltiumSharp.BasicTypes;
5 |
6 | namespace OriginalCircuit.AltiumSharp.Records
7 | {
8 | public class SchPolygon : SchGraphicalObject
9 | {
10 | public override int Record => 7;
11 | public bool IsSolid { get; set; }
12 | public LineWidth LineWidth { get; set; }
13 | public List Vertices { get; set; } = new List();
14 | public bool Transparent { get; set; }
15 |
16 | public SchPolygon() : base()
17 | {
18 | LineWidth = LineWidth.Small;
19 | }
20 |
21 | public override CoordRect CalculateBounds() =>
22 | new CoordRect(
23 | new CoordPoint(Vertices.Min(p => p.X), Vertices.Min(p => p.Y)),
24 | new CoordPoint(Vertices.Max(p => p.X), Vertices.Max(p => p.Y)));
25 |
26 | public override void ImportFromParameters(ParameterCollection p)
27 | {
28 | if (p == null) throw new ArgumentNullException(nameof(p));
29 |
30 | base.ImportFromParameters(p);
31 | IsSolid = p["ISSOLID"].AsBool();
32 | LineWidth = p["LINEWIDTH"].AsEnumOrDefault();
33 | Vertices = Enumerable.Range(1, p["LOCATIONCOUNT"].AsInt())
34 | .Select(i => new CoordPoint(
35 | Utils.DxpFracToCoord(p[$"X{i}"].AsIntOrDefault(), p[$"X{i}_FRAC"].AsIntOrDefault()),
36 | Utils.DxpFracToCoord(p[$"Y{i}"].AsIntOrDefault(), p[$"Y{i}_FRAC"].AsIntOrDefault())))
37 | .ToList();
38 | Transparent = p["TRANSPARENT"].AsBool();
39 | }
40 |
41 | public override void ExportToParameters(ParameterCollection p)
42 | {
43 | if (p == null) throw new ArgumentNullException(nameof(p));
44 |
45 | base.ExportToParameters(p);
46 | p.SetBookmark();
47 | p.Add("LINEWIDTH", LineWidth);
48 | p.MoveKeys("COLOR");
49 | p.Add("ISSOLID", IsSolid);
50 | p.Add("TRANSPARENT", Transparent);
51 | p.Add("LOCATIONCOUNT", Vertices.Count);
52 | for (var i = 0; i < Vertices.Count; i++)
53 | {
54 | {
55 | var (n, f) = Utils.CoordToDxpFrac(Vertices[i].X);
56 | p.Add($"X{i+1}", n);
57 | p.Add($"X{i+1}_FRAC", f);
58 | }
59 | {
60 | var (n, f) = Utils.CoordToDxpFrac(Vertices[i].Y);
61 | p.Add($"Y{i+1}", n);
62 | p.Add($"Y{i+1}_FRAC", f);
63 | }
64 | }
65 | }
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/AltiumSharp/Records/Sch/SchParameter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using OriginalCircuit.AltiumSharp.BasicTypes;
3 |
4 | namespace OriginalCircuit.AltiumSharp.Records
5 | {
6 | public class SchParameter : SchLabel
7 | {
8 | public override int Record => 41;
9 | public ParameterType ParamType { get; set; }
10 | public string Name { get; set; }
11 | public bool ShowName { get; set; }
12 | public string Description { get; set; }
13 | public int ReadOnlyState { get; set; }
14 | public string UniqueId { get; set; }
15 | public string Value => string.IsNullOrEmpty(Description) ? base.DisplayText : Description;
16 | internal override string DisplayText => ShowName ? $"{Name}: {Value}" : Value;
17 | public override bool IsOfCurrentPart => true;
18 | public override bool IsOfCurrentDisplayMode => true;
19 |
20 | public override bool IsVisible =>
21 | base.IsVisible &&
22 | Name?.Equals("Comment", StringComparison.InvariantCultureIgnoreCase) == false &&
23 | Name?.Equals("HiddenNetName", StringComparison.InvariantCultureIgnoreCase) == false;
24 |
25 | public SchParameter() : base()
26 | {
27 | IsNotAccesible = false;
28 | OwnerPartId = -1;
29 | Text = "*";
30 | IsHidden = true;
31 | UniqueId = Utils.GenerateUniqueId();
32 | }
33 |
34 | public override string ToString()
35 | {
36 | return $"({Name}: {Value})";
37 | }
38 |
39 | public override void ImportFromParameters(ParameterCollection p)
40 | {
41 | if (p == null) throw new ArgumentNullException(nameof(p));
42 |
43 | base.ImportFromParameters(p);
44 | ParamType = p["PARAMTYPE"].AsEnumOrDefault();
45 | Name = p["NAME"].AsStringOrDefault();
46 | ShowName = p["SHOWNAME"].AsBool();
47 | Description = p["DESCRIPTION"].AsStringOrDefault();
48 | ReadOnlyState = p["READONLYSTATE"].AsIntOrDefault();
49 | UniqueId = p["UNIQUEID"].AsStringOrDefault();
50 | }
51 |
52 | public override void ExportToParameters(ParameterCollection p)
53 | {
54 | if (p == null) throw new ArgumentNullException(nameof(p));
55 |
56 | base.ExportToParameters(p);
57 | p.Add("PARAMTYPE", ParamType);
58 | p.Add("NAME", Name);
59 | p.Add("SHOWNAME", ShowName);
60 | p.Add("DESCRIPTION", Description);
61 | p.Add("READONLYSTATE", ReadOnlyState);
62 | p.Add("UNIQUEID", UniqueId);
63 | }
64 | }
65 |
66 | public enum ParameterType
67 | {
68 | String,
69 | Boolean,
70 | Integer,
71 | Float
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/AltiumSharp/Drawing/OverlineHelper.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Drawing;
4 | using System.Linq;
5 | using System.Text;
6 |
7 | namespace OriginalCircuit.AltiumSharp.Drawing
8 | {
9 | internal static class OverlineHelper
10 | {
11 | private enum State { NoBar, InBar, CheckBar }
12 |
13 | public static CharacterRange[] Parse(string text)
14 | {
15 | text = text.TrimStart('\\'); // remove leading backslashes
16 |
17 | var overlineRanges = new List();
18 | var state = State.NoBar;
19 | int charIndex = 0;
20 | int startIndex = 0;
21 | foreach (var c in text)
22 | {
23 | switch (state)
24 | {
25 | case State.NoBar:
26 | if (c != '\\')
27 | {
28 | charIndex++;
29 | }
30 | else
31 | {
32 | state = State.InBar;
33 | startIndex = charIndex - 1;
34 | }
35 | break;
36 | case State.InBar:
37 | if (c != '\\')
38 | {
39 | state = State.CheckBar;
40 | charIndex++;
41 | }
42 | break;
43 | case State.CheckBar:
44 | if (c != '\\')
45 | {
46 | var length = charIndex - 1 - startIndex;
47 | overlineRanges.Add(new CharacterRange(startIndex, length));
48 | startIndex = charIndex;
49 | state = State.NoBar;
50 | charIndex++;
51 | }
52 | else
53 | {
54 | state = State.InBar;
55 | }
56 | break;
57 | default:
58 | throw new InvalidOperationException();
59 | }
60 | }
61 |
62 | if (state != State.NoBar)
63 | {
64 | if (state == State.CheckBar) --charIndex; // last character isn't overlined
65 | if (startIndex < charIndex)
66 | {
67 | overlineRanges.Add(new CharacterRange(startIndex, charIndex - startIndex));
68 | }
69 | }
70 |
71 | // limit size to 32 as it's the maximum allowed by SetMeasurableCharacterRanges
72 | return overlineRanges.Take(32).ToArray();
73 | }
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/AltiumSharp/Records/Pcb/PcbText.cs:
--------------------------------------------------------------------------------
1 | using OriginalCircuit.AltiumSharp.BasicTypes;
2 |
3 | namespace OriginalCircuit.AltiumSharp.Records
4 | {
5 | public enum PcbTextKind { Stroke, TrueType, BarCode }
6 |
7 | public enum PcbTextStrokeFont { Default = 0, SansSerif = 1, Serif = 3 }
8 |
9 | public enum PcbTextJustification
10 | {
11 | BottomRight = 1, MiddleRight, TopRight,
12 | BottomCenter = 4, MiddleCenter, TopCenter,
13 | BottomLeft = 7, MiddleLeft, TopLeft
14 | }
15 |
16 | public class PcbText : PcbRectangularPrimitive
17 | {
18 | public override PcbPrimitiveDisplayInfo GetDisplayInfo() =>
19 | new PcbPrimitiveDisplayInfo(Text, null, null);
20 |
21 | public override PcbPrimitiveObjectId ObjectId => PcbPrimitiveObjectId.Text;
22 | public bool Mirrored { get; set; }
23 | public PcbTextKind TextKind { get; set; }
24 | public PcbTextStrokeFont StrokeFont { get; set; }
25 | public Coord StrokeWidth { get; set; }
26 | public bool FontBold { get; set; }
27 | public bool FontItalic { get; set; }
28 | public string FontName { get; set; }
29 | public Coord BarcodeLRMargin { get; set; }
30 | public Coord BarcodeTBMargin { get; set; }
31 | public bool FontInverted { get; set; }
32 | public Coord FontInvertedBorder { get; set; }
33 | public bool FontInvertedRect { get; set; }
34 | public Coord FontInvertedRectWidth { get; set; }
35 | public Coord FontInvertedRectHeight { get; set; }
36 | public PcbTextJustification FontInvertedRectJustification { get; set; }
37 | public Coord FontInvertedRectTextOffset { get; set; }
38 | public string Text { get; set; }
39 | internal int WideStringsIndex { get; set; }
40 |
41 | public PcbText() : base()
42 | {
43 | Text = "String";
44 | Height = Coord.FromMils(60);
45 | TextKind = PcbTextKind.Stroke;
46 | StrokeFont = PcbTextStrokeFont.SansSerif;
47 | StrokeWidth = Coord.FromMils(10);
48 | FontName = "Arial";
49 | FontInvertedBorder = Coord.FromMils(20);
50 | FontInvertedRectJustification = PcbTextJustification.MiddleCenter;
51 | FontInvertedRectTextOffset = Coord.FromMils(2);
52 | }
53 |
54 | internal CoordRect CalculateRect(bool useAbsolutePosition)
55 | {
56 | var w = (TextKind == PcbTextKind.Stroke) ? (Text.Length * Height * 12) / 13 : (Text.Length * Height / 2);
57 | var h = Height;
58 | var x = Mirrored ? -w : 0;
59 | var y = 0;
60 | if (useAbsolutePosition)
61 | {
62 | x += Corner1.X;
63 | y += Corner1.Y;
64 | }
65 | return new CoordRect(x, y, w, h);
66 | }
67 |
68 | public override CoordRect CalculateBounds()
69 | {
70 | return CoordRect.FromRotatedRect(CalculateRect(true), Corner1, Rotation);
71 | }
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/LibraryViewer/Properties/Resources.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.42000
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace LibraryViewer.Properties
12 | {
13 |
14 |
15 | ///
16 | /// A strongly-typed resource class, for looking up localized strings, etc.
17 | ///
18 | // This class was auto-generated by the StronglyTypedResourceBuilder
19 | // class via a tool like ResGen or Visual Studio.
20 | // To add or remove a member, edit your .ResX file then rerun ResGen
21 | // with the /str option, or rebuild your VS project.
22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
25 | internal class Resources
26 | {
27 |
28 | private static global::System.Resources.ResourceManager resourceMan;
29 |
30 | private static global::System.Globalization.CultureInfo resourceCulture;
31 |
32 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
33 | internal Resources()
34 | {
35 | }
36 |
37 | ///
38 | /// Returns the cached ResourceManager instance used by this class.
39 | ///
40 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
41 | internal static global::System.Resources.ResourceManager ResourceManager
42 | {
43 | get
44 | {
45 | if ((resourceMan == null))
46 | {
47 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("LibraryViewer.Properties.Resources", typeof(Resources).Assembly);
48 | resourceMan = temp;
49 | }
50 | return resourceMan;
51 | }
52 | }
53 |
54 | ///
55 | /// Overrides the current thread's CurrentUICulture property for all
56 | /// resource lookups using this strongly typed resource class.
57 | ///
58 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
59 | internal static global::System.Globalization.CultureInfo Culture
60 | {
61 | get
62 | {
63 | return resourceCulture;
64 | }
65 | set
66 | {
67 | resourceCulture = value;
68 | }
69 | }
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/AltiumSharp/Records/Pcb/PcbComponent.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections;
3 | using System.Collections.Generic;
4 | using System.Linq;
5 | using OriginalCircuit.AltiumSharp.BasicTypes;
6 | using OriginalCircuit.AltiumSharp.Records;
7 |
8 | namespace OriginalCircuit.AltiumSharp
9 | {
10 | public class PcbComponent : IComponent, IEnumerable
11 | {
12 | public string Pattern { get; set; }
13 | public string Description { get; set; }
14 | public Coord Height { get; set; }
15 | public string ItemGuid { get; set; }
16 | public string RevisionGuid { get; set; }
17 |
18 | string IComponent.Name => Pattern;
19 | string IComponent.Description => Description;
20 |
21 | public int Pads => Primitives.Where(p => p is PcbPad).Count();
22 |
23 | public List Primitives { get; } = new List();
24 |
25 | public IEnumerable GetPrimitivesOfType(bool flatten) where T : Primitive =>
26 | Primitives.OfType();
27 |
28 | public CoordRect CalculateBounds() =>
29 | CoordRect.Union(GetPrimitivesOfType(true).Select(p => p.CalculateBounds()));
30 |
31 | public void ImportFromParameters(ParameterCollection p)
32 | {
33 | if (p == null) throw new ArgumentNullException(nameof(p));
34 |
35 | Pattern = p["PATTERN"].AsStringOrDefault();
36 | Height = p["HEIGHT"].AsCoord();
37 | Description = p["DESCRIPTION"].AsStringOrDefault();
38 | ItemGuid = p["ITEMGUID"].AsStringOrDefault();
39 | RevisionGuid = p["REVISIONGUID"].AsStringOrDefault();
40 | }
41 |
42 | public void ExportToParameters(ParameterCollection p)
43 | {
44 | if (p == null) throw new ArgumentNullException(nameof(p));
45 |
46 | p.Add("PATTERN", Pattern);
47 | p.Add("HEIGHT", Height, false);
48 | p.Add("DESCRIPTION", Description, false);
49 | p.Add("ITEMGUID", ItemGuid, false);
50 | p.Add("REVISIONGUID", RevisionGuid, false);
51 | }
52 |
53 | public ParameterCollection ExportToParameters()
54 | {
55 | var parameters = new ParameterCollection();
56 | ExportToParameters(parameters);
57 | return parameters;
58 | }
59 |
60 | public void Add(PcbPrimitive primitive)
61 | {
62 | if (primitive is PcbPad pad)
63 | {
64 | pad.Designator = pad.Designator ??
65 | Utils.GenerateDesignator(GetPrimitivesOfType(false).Select(p => p.Designator));
66 | }
67 | else if (primitive is PcbMetaTrack metaTrack)
68 | {
69 | foreach (var line in metaTrack.Lines)
70 | {
71 | Primitives.Add(new PcbTrack
72 | {
73 | Layer = metaTrack.Layer,
74 | Flags = metaTrack.Flags,
75 | Start = line.Item1,
76 | End = line.Item2
77 | });
78 | }
79 | return; // ignore the actual primitive
80 | }
81 |
82 | Primitives.Add(primitive);
83 | }
84 |
85 | IEnumerator IEnumerable.GetEnumerator() => Primitives.GetEnumerator();
86 | IEnumerator IEnumerable.GetEnumerator() => Primitives.GetEnumerator();
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/AltiumSharp/Records/Pcb/PcbPrimitive.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using OriginalCircuit.AltiumSharp.BasicTypes;
3 |
4 | namespace OriginalCircuit.AltiumSharp.Records
5 | {
6 | public enum PcbPrimitiveObjectId
7 | {
8 | None,
9 | Arc,
10 | Pad,
11 | Via,
12 | Track,
13 | Text,
14 | Fill,
15 | Region = 11,
16 | ComponentBody
17 | }
18 |
19 | [Flags]
20 | public enum PcbFlags
21 | {
22 | None = 0,
23 | Unknown2 = 2,
24 | Unlocked = 4,
25 | Unknown8 = 8,
26 | Unknown16 = 16,
27 | TentingTop = 32,
28 | TentingBottom = 64,
29 | FabricationTop = 128,
30 | FabricationBottom = 256,
31 | KeepOut = 512
32 | }
33 |
34 | public enum PcbStackMode
35 | {
36 | Simple,
37 | TopMiddleBottom,
38 | FullStack
39 | }
40 |
41 | public class PcbPrimitiveDisplayInfo
42 | {
43 | public string Name { get; }
44 | public Coord? SizeX { get; }
45 | public Coord? SizeY { get; }
46 | public PcbPrimitiveDisplayInfo() { }
47 | public PcbPrimitiveDisplayInfo(string name, Coord? sizeX, Coord? sizeY) =>
48 | (Name, SizeX, SizeY) = (name, sizeX, sizeY);
49 | }
50 |
51 | public abstract class PcbPrimitive : Primitive
52 | {
53 | public virtual PcbPrimitiveDisplayInfo GetDisplayInfo() => new PcbPrimitiveDisplayInfo();
54 |
55 | public abstract PcbPrimitiveObjectId ObjectId { get; }
56 |
57 | public Layer Layer { get; set; }
58 |
59 | public PcbFlags Flags { get; set; }
60 |
61 | public bool IsLocked
62 | {
63 | get => !Flags.HasFlag(PcbFlags.Unlocked);
64 | set => Flags = Flags.WithFlag(PcbFlags.Unlocked, !value);
65 | }
66 |
67 | public bool IsTentingTop
68 | {
69 | get => Flags.HasFlag(PcbFlags.TentingTop);
70 | set => Flags = Flags.WithFlag(PcbFlags.TentingTop, value);
71 | }
72 |
73 | public bool IsTentingBottom
74 | {
75 | get => Flags.HasFlag(PcbFlags.TentingBottom);
76 | set => Flags = Flags.WithFlag(PcbFlags.TentingBottom, value);
77 | }
78 |
79 | public bool IsKeepOut
80 | {
81 | get => Flags.HasFlag(PcbFlags.KeepOut);
82 | set => Flags = Flags.WithFlag(PcbFlags.KeepOut, value);
83 | }
84 |
85 | public bool IsFabricationTop
86 | {
87 | get => Flags.HasFlag(PcbFlags.FabricationTop);
88 | set => Flags = Flags.WithFlag(PcbFlags.FabricationTop, value);
89 | }
90 |
91 | public bool IsFabricationBottom
92 | {
93 | get => Flags.HasFlag(PcbFlags.FabricationBottom);
94 | set => Flags = Flags.WithFlag(PcbFlags.FabricationBottom, value);
95 | }
96 |
97 | public string UniqueId { get; set; }
98 |
99 | public override CoordRect CalculateBounds() => CoordRect.Empty;
100 |
101 | protected PcbPrimitive()
102 | {
103 | Layer = LayerMetadata.Get("TopLayer").Id;
104 | Flags = PcbFlags.Unlocked | PcbFlags.Unknown8;
105 | }
106 | }
107 |
108 | public class PcbUnknown : PcbPrimitive
109 | {
110 | private PcbPrimitiveObjectId _objectId;
111 | public override PcbPrimitiveObjectId ObjectId => _objectId;
112 |
113 | public PcbUnknown(PcbPrimitiveObjectId objectId)
114 | {
115 | _objectId = objectId;
116 | }
117 | }
118 | }
119 |
--------------------------------------------------------------------------------
/AltiumSharp/BasicTypes/Coord.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace OriginalCircuit.AltiumSharp.BasicTypes
4 | {
5 | ///
6 | /// Internal coordinate value, stored as a fixed point integer.
7 | ///
8 | ///
9 | public readonly struct Coord : IEquatable, IComparable
10 | {
11 | ///
12 | /// Length of 1 inch as a coordinate value.
13 | ///
14 | public static readonly Coord OneInch = Utils.MilsToCoord(1000);
15 |
16 | private readonly int _value;
17 | private Coord(int value) => _value = value;
18 |
19 | public static Coord FromMils(double mils) => Utils.MilsToCoord(mils);
20 | public double ToMils() => Utils.CoordToMils(this);
21 |
22 | public static Coord FromMMs(double mms) => Utils.MMsToCoord(mms);
23 | public double ToMMs() => Utils.CoordToMMs(this);
24 |
25 | ///
26 | /// Creates a coordinate value from an integer.
27 | ///
28 | /// Value to be used as coordenate
29 | ///
30 | public static Coord FromInt32(int value) => new Coord(value);
31 |
32 | ///
33 | /// Gets the integer value of this coordinate.
34 | ///
35 | ///
36 | public int ToInt32() => _value;
37 |
38 | ///
39 | /// Gets the string representation of this coordinate using the unit.
40 | ///
41 | public override string ToString() => Utils.CoordUnitToString(_value, Unit.Mil);
42 |
43 | ///
44 | /// Gets the string representation of this coordinate using the given .
45 | ///
46 | public string ToString(Unit unit) => Utils.CoordUnitToString(_value, unit);
47 |
48 | ///
49 | /// Gets the string representation of this coordinate using the given ,
50 | /// and snapping the coordinate to the size .
51 | ///
52 | public string ToString(Unit unit, Coord grid) => Utils.CoordUnitToString(_value, unit, grid);
53 |
54 | ///
55 | /// Implicit conversion operator so we can use integers and coordinates transparently.
56 | ///
57 | ///
58 | static public implicit operator Coord(int value) => FromInt32(value);
59 |
60 | ///
61 | /// Implicit conversion operator so we can use integers and coordinates transparently.
62 | ///
63 | static public implicit operator int(Coord coord) => coord._value;
64 |
65 | #region 'boilerplate'
66 | public override bool Equals(object obj) => obj is Coord other && Equals(other);
67 | public bool Equals(Coord other) => _value == other._value;
68 | public int CompareTo(Coord other) => _value < other._value ? -1 : _value > other._value ? 1 : 0;
69 | public override int GetHashCode() => _value.GetHashCode();
70 | public static bool operator ==(Coord left, Coord right) => left.Equals(right);
71 | public static bool operator !=(Coord left, Coord right) => !left.Equals(right);
72 | public static bool operator <(Coord left, Coord right) => left.CompareTo(right) < 0;
73 | public static bool operator <=(Coord left, Coord right) => left.CompareTo(right) <= 0;
74 | public static bool operator >(Coord left, Coord right) => left.CompareTo(right) > 0;
75 | public static bool operator >=(Coord left, Coord right) => left.CompareTo(right) >= 0;
76 | #endregion
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/LibraryViewer/PropertyViewer.Designer.cs:
--------------------------------------------------------------------------------
1 | namespace LibraryViewer
2 | {
3 | partial class PropertyViewer
4 | {
5 | ///
6 | /// Required designer variable.
7 | ///
8 | private System.ComponentModel.IContainer components = null;
9 |
10 | ///
11 | /// Clean up any resources being used.
12 | ///
13 | /// true if managed resources should be disposed; otherwise, false.
14 | protected override void Dispose(bool disposing)
15 | {
16 | if (disposing && (components != null))
17 | {
18 | components.Dispose();
19 | }
20 | base.Dispose(disposing);
21 | }
22 |
23 | #region Windows Form Designer generated code
24 |
25 | ///
26 | /// Required method for Designer support - do not modify
27 | /// the contents of this method with the code editor.
28 | ///
29 | private void InitializeComponent()
30 | {
31 | this.propertyGrid = new System.Windows.Forms.PropertyGrid();
32 | this.comboBoxObjects = new System.Windows.Forms.ComboBox();
33 | this.SuspendLayout();
34 | //
35 | // propertyGrid
36 | //
37 | this.propertyGrid.DisabledItemForeColor = System.Drawing.SystemColors.ControlText;
38 | this.propertyGrid.Dock = System.Windows.Forms.DockStyle.Fill;
39 | this.propertyGrid.HelpVisible = false;
40 | this.propertyGrid.Location = new System.Drawing.Point(0, 21);
41 | this.propertyGrid.Name = "propertyGrid";
42 | this.propertyGrid.PropertySort = System.Windows.Forms.PropertySort.NoSort;
43 | this.propertyGrid.SelectedObject = this;
44 | this.propertyGrid.Size = new System.Drawing.Size(284, 430);
45 | this.propertyGrid.TabIndex = 0;
46 | this.propertyGrid.ToolbarVisible = false;
47 | this.propertyGrid.PropertyValueChanged += new System.Windows.Forms.PropertyValueChangedEventHandler(this.propertyGrid_PropertyValueChanged);
48 | //
49 | // comboBoxObjects
50 | //
51 | this.comboBoxObjects.Dock = System.Windows.Forms.DockStyle.Top;
52 | this.comboBoxObjects.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
53 | this.comboBoxObjects.FormattingEnabled = true;
54 | this.comboBoxObjects.Location = new System.Drawing.Point(0, 0);
55 | this.comboBoxObjects.Name = "comboBoxObjects";
56 | this.comboBoxObjects.Size = new System.Drawing.Size(284, 21);
57 | this.comboBoxObjects.TabIndex = 1;
58 | this.comboBoxObjects.SelectedIndexChanged += new System.EventHandler(this.ComboBoxObjects_SelectedIndexChanged);
59 | //
60 | // PropertyViewer
61 | //
62 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
63 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
64 | this.ClientSize = new System.Drawing.Size(284, 451);
65 | this.Controls.Add(this.propertyGrid);
66 | this.Controls.Add(this.comboBoxObjects);
67 | this.MaximizeBox = false;
68 | this.MinimizeBox = false;
69 | this.Name = "PropertyViewer";
70 | this.ShowIcon = false;
71 | this.ShowInTaskbar = false;
72 | this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
73 | this.Text = "Property Viewer";
74 | this.Load += new System.EventHandler(this.PropertyViewer_Load);
75 | this.ResumeLayout(false);
76 |
77 | }
78 |
79 | #endregion
80 |
81 | private System.Windows.Forms.PropertyGrid propertyGrid;
82 | private System.Windows.Forms.ComboBox comboBoxObjects;
83 | }
84 | }
--------------------------------------------------------------------------------
/AltiumSharp/BasicTypes/CoordRect.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 |
5 | namespace OriginalCircuit.AltiumSharp.BasicTypes
6 | {
7 | public readonly struct CoordRect : IEquatable
8 | {
9 | public static readonly CoordRect Empty = new CoordRect();
10 | public CoordPoint Location1 { get; }
11 | public CoordPoint Location2 { get; }
12 | public Coord Width => Location2.X - Location1.X;
13 | public Coord Height => Location2.Y - Location1.Y;
14 | public bool IsEmpty => Width == 0 && Height == 0;
15 | public CoordPoint Center =>
16 | new CoordPoint((Location1.X + Location2.X) / 2, (Location1.Y + Location2.Y) / 2);
17 |
18 | public CoordRect(CoordPoint loc1, CoordPoint loc2)
19 | {
20 | Location1 = new CoordPoint(Math.Min(loc1.X, loc2.X), Math.Min(loc1.Y, loc2.Y));
21 | Location2 = new CoordPoint(Math.Max(loc1.X, loc2.X), Math.Max(loc1.Y, loc2.Y));
22 | }
23 |
24 | public CoordRect(Coord x, Coord y, Coord w, Coord h) :
25 | this(new CoordPoint(x, y), new CoordPoint(x + w, y + h))
26 | {
27 | }
28 |
29 | public void Deconstruct(out CoordPoint location1, out CoordPoint location2) =>
30 | (location1, location2) = (Location1, Location2);
31 |
32 | public void Deconstruct(out Coord x, out Coord y, out Coord w, out Coord h) =>
33 | (x, y, w, h) = (Location1.X, Location1.Y, Width, Height);
34 |
35 | public bool Contains(in CoordPoint point) =>
36 | Location1.X <= point.X && point.X <= Location2.X &&
37 | Location1.Y <= point.Y && point.Y <= Location2.Y;
38 |
39 | public bool Intersects(in CoordRect other) =>
40 | Location1.X <= other.Location2.X && Location2.X >= other.Location1.X &&
41 | Location1.Y <= other.Location2.Y && Location2.Y >= other.Location1.Y;
42 |
43 | public CoordPoint[] GetPoints()
44 | {
45 | return new[] { Location1, new CoordPoint(Location2.X, Location1.Y),
46 | Location2, new CoordPoint(Location1.X, Location2.Y) };
47 | }
48 |
49 | public CoordPoint[] RotatedPoints(CoordPoint anchorPoint, double rotationDegrees)
50 | {
51 | var points = GetPoints();
52 | return Utils.RotatePoints(ref points, anchorPoint, rotationDegrees);
53 | }
54 |
55 | public override string ToString() => $"({Location1} {Location2})";
56 |
57 | public static CoordRect FromRotatedRect(in CoordRect coordRect, in CoordPoint anchorPoint, double rotationDegrees)
58 | {
59 | var points = coordRect.RotatedPoints(anchorPoint, rotationDegrees);
60 | return new CoordRect(new CoordPoint(points.Min(p => p.X), points.Min(p => p.Y)),
61 | new CoordPoint(points.Max(p => p.X), points.Max(p => p.Y)));
62 | }
63 |
64 | public static CoordRect Union(in CoordRect left, in CoordRect right)
65 | {
66 | if (left.IsEmpty)
67 | {
68 | return right;
69 | }
70 | else if (right.IsEmpty)
71 | {
72 | return left;
73 | }
74 | else
75 | {
76 | return new CoordRect(
77 | new CoordPoint(Math.Min(left.Location1.X, right.Location1.X),
78 | Math.Min(left.Location1.Y, right.Location1.Y)),
79 | new CoordPoint(Math.Max(left.Location2.X, right.Location2.X),
80 | Math.Max(left.Location2.Y, right.Location2.Y)));
81 | }
82 | }
83 |
84 | public static CoordRect Union(IEnumerable collection)
85 | {
86 | return collection.Aggregate(Empty, (acc, rect) => Union(acc, rect));
87 | }
88 |
89 | #region 'boilerplate'
90 | public override bool Equals(object obj) => obj is CoordRect other && Equals(other);
91 | public bool Equals(CoordRect other) => Location1 == other.Location1 && Location2 == other.Location2;
92 | public override int GetHashCode() => Location1.GetHashCode() ^ Location2.GetHashCode();
93 | public static bool operator ==(CoordRect left, CoordRect right) => left.Equals(right);
94 | public static bool operator !=(CoordRect left, CoordRect right) => !(left == right);
95 | #endregion
96 | }
97 | }
98 |
--------------------------------------------------------------------------------
/AltiumSharp/Records/Sch/SchPrimitive.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using OriginalCircuit.AltiumSharp.BasicTypes;
5 |
6 | namespace OriginalCircuit.AltiumSharp.Records
7 | {
8 | public class SchPrimitive : Primitive, IContainer
9 | {
10 | public virtual int Record { get; }
11 |
12 | public bool IsNotAccesible { get; set; }
13 |
14 | public int? IndexInSheet => (Owner as SchSheetHeader)?.GetPrimitiveIndexOf(this);
15 |
16 | internal int OwnerIndex { get; set; }
17 |
18 | public int? OwnerPartId { get; set; }
19 |
20 | public int? OwnerPartDisplayMode { get; set; }
21 |
22 | public bool GraphicallyLocked { get; set; }
23 |
24 | private List _primitives = new List();
25 | internal IReadOnlyList Primitives => _primitives;
26 |
27 | public virtual bool IsOfCurrentPart =>
28 | OwnerPartId <= 0 || (Owner is SchComponent component && component.CurrentPartId == OwnerPartId);
29 |
30 | public virtual bool IsOfCurrentDisplayMode =>
31 | !(Owner is SchComponent) ||
32 | (Owner is SchComponent component && component.DisplayMode == OwnerPartDisplayMode);
33 |
34 | public override bool IsVisible =>
35 | base.IsVisible && IsOfCurrentPart && IsOfCurrentDisplayMode;
36 |
37 | public SchPrimitive() : base()
38 | {
39 | }
40 |
41 | public IEnumerable GetPrimitivesOfType(bool flatten = true) where T : Primitive
42 | {
43 | if (flatten)
44 | {
45 | return Enumerable.Concat(
46 | GetPrimitivesOfType(false),
47 | Primitives.SelectMany(p => p.GetPrimitivesOfType(true)));
48 | }
49 | else
50 | {
51 | return GetAllPrimitives().OfType();
52 | }
53 | }
54 |
55 | protected int GetPrimitiveIndexOf(SchPrimitive primitive) =>
56 | _primitives.IndexOf(primitive);
57 |
58 | public override CoordRect CalculateBounds() => CoordRect.Empty;
59 |
60 | public virtual void ImportFromParameters(ParameterCollection p)
61 | {
62 | if (p == null) throw new ArgumentNullException(nameof(p));
63 |
64 | var recordType = p["RECORD"].AsIntOrDefault();
65 | if (Record != 0 && recordType != Record) throw new ArgumentException($"Record type mismatch when deserializing. Expected {Record} but got {recordType}", nameof(p));
66 |
67 | OwnerIndex = p["OWNERINDEX"].AsIntOrDefault();
68 | IsNotAccesible = p["ISNOTACCESIBLE"].AsBool();
69 | OwnerPartId = p["OWNERPARTID"].AsIntOrDefault();
70 | OwnerPartDisplayMode = p["OWNERPARTDISPLAYMODE"].AsIntOrDefault();
71 | GraphicallyLocked = p["GRAPHICALLYLOCKED"].AsBool();
72 | }
73 |
74 | public virtual void ExportToParameters(ParameterCollection p)
75 | {
76 | if (p == null) throw new ArgumentNullException(nameof(p));
77 |
78 | p.Add("RECORD", Record);
79 | p.Add("OWNERINDEX", OwnerIndex);
80 | p.Add("ISNOTACCESIBLE", IsNotAccesible);
81 | p.Add("INDEXINSHEET", IndexInSheet ?? default);
82 | p.Add("OWNERPARTID", OwnerPartId ?? default);
83 | p.Add("OWNERPARTDISPLAYMODE", OwnerPartDisplayMode ?? default);
84 | p.Add("GRAPHICALLYLOCKED", GraphicallyLocked);
85 | }
86 |
87 | public ParameterCollection ExportToParameters()
88 | {
89 | var parameters = new ParameterCollection();
90 | ExportToParameters(parameters);
91 | return parameters;
92 | }
93 |
94 | public IEnumerable GetAllPrimitives()
95 | {
96 | return Enumerable.Concat(Primitives, DoGetParameters());
97 | }
98 |
99 | protected virtual IEnumerable DoGetParameters()
100 | {
101 | return Enumerable.Empty();
102 | }
103 |
104 | public void Add(SchPrimitive primitive)
105 | {
106 | if (primitive == null) throw new ArgumentNullException(nameof(primitive));
107 | if (primitive == this) return;
108 |
109 | if (DoAdd(primitive))
110 | {
111 | primitive.Owner = this;
112 | _primitives.Add(primitive);
113 | }
114 | }
115 |
116 | protected virtual bool DoAdd(SchPrimitive primitive)
117 | {
118 | return true;
119 | }
120 |
121 | public void Remove(SchPrimitive primitive)
122 | {
123 | if (primitive == null) throw new ArgumentNullException(nameof(primitive));
124 |
125 | primitive.Owner = null;
126 | _primitives.Remove(primitive);
127 | }
128 | }
129 | }
--------------------------------------------------------------------------------
/AltiumSharp/Records/Sch/SchGraphicalObject.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Drawing;
3 | using OriginalCircuit.AltiumSharp.BasicTypes;
4 |
5 | namespace OriginalCircuit.AltiumSharp.Records
6 | {
7 | [Flags]
8 | public enum TextOrientations
9 | {
10 | None = 0,
11 | Rotated = 1,
12 | Flipped = 2
13 | }
14 |
15 | public struct TextJustification : IEquatable
16 | {
17 | public static readonly TextJustification BottomLeft = new TextJustification(0);
18 | public static readonly TextJustification BottomCenter = new TextJustification(1);
19 | public static readonly TextJustification BottomRight = new TextJustification(2);
20 | public static readonly TextJustification MiddleLeft = new TextJustification(3);
21 | public static readonly TextJustification MiddleCenter = new TextJustification(4);
22 | public static readonly TextJustification MiddleRight = new TextJustification(5);
23 | public static readonly TextJustification TopLeft = new TextJustification(6);
24 | public static readonly TextJustification TopCenter = new TextJustification(7);
25 | public static readonly TextJustification TopRight = new TextJustification(8);
26 |
27 | public enum HorizontalValue { Left, Center, Right }
28 | public enum VerticalValue { Bottom, Middle, Top }
29 |
30 | private readonly int _value;
31 |
32 | public TextJustification(int value) => _value = value;
33 |
34 | public TextJustification(HorizontalValue horizontal, VerticalValue vertical) =>
35 | _value = ((int)vertical * 3) + (int)horizontal;
36 |
37 | public HorizontalValue Horizontal => (HorizontalValue)(_value % 3);
38 |
39 | public VerticalValue Vertical => (VerticalValue)(_value / 3);
40 |
41 | public int ToInt32() => _value;
42 |
43 | public static TextJustification FromInt32(int value) => new TextJustification(value);
44 |
45 | static public explicit operator TextJustification(int value) => FromInt32(value);
46 |
47 | static public explicit operator int(TextJustification textJustification) => textJustification.ToInt32();
48 |
49 | #region 'boilerplate'
50 | public override bool Equals(object obj) => obj is TextJustification other && Equals(other);
51 | public bool Equals(TextJustification other) => _value == other._value;
52 | public override int GetHashCode() => _value.GetHashCode();
53 | public static bool operator ==(TextJustification left, TextJustification right) => left.Equals(right);
54 | public static bool operator !=(TextJustification left, TextJustification right) => !left.Equals(right);
55 | #endregion
56 | }
57 |
58 | public abstract class SchGraphicalObject : SchPrimitive
59 | {
60 | public CoordPoint Location { get; set; }
61 | public Color Color { get; set; }
62 | public Color AreaColor { get; set; }
63 |
64 | #region Transient values
65 | public bool EnableDraw { get; set; }
66 | public bool Selection { get; set; }
67 | #endregion
68 |
69 | public override bool IsVisible => base.IsVisible && EnableDraw;
70 |
71 | public SchGraphicalObject()
72 | {
73 | Color = ColorTranslator.FromWin32(0);
74 | AreaColor = ColorTranslator.FromWin32(0);
75 | IsNotAccesible = true;
76 | EnableDraw = true;
77 | }
78 |
79 | public override CoordRect CalculateBounds() =>
80 | new CoordRect(Location.X, Location.Y, 1, 1);
81 |
82 | public override void ImportFromParameters(ParameterCollection p)
83 | {
84 | if (p == null) throw new ArgumentNullException(nameof(p));
85 |
86 | base.ImportFromParameters(p);
87 | Location = new CoordPoint(
88 | Utils.DxpFracToCoord(p["LOCATION.X"].AsIntOrDefault(), p["LOCATION.X_FRAC"].AsIntOrDefault()),
89 | Utils.DxpFracToCoord(p["LOCATION.Y"].AsIntOrDefault(), p["LOCATION.Y_FRAC"].AsIntOrDefault()));
90 | Color = p["COLOR"].AsColorOrDefault();
91 | AreaColor = p["AREACOLOR"].AsColorOrDefault();
92 | }
93 |
94 | public override void ExportToParameters(ParameterCollection p)
95 | {
96 | if (p == null) throw new ArgumentNullException(nameof(p));
97 |
98 | base.ExportToParameters(p);
99 | {
100 | var (n, f) = Utils.CoordToDxpFrac(Location.X);
101 | p.Add("LOCATION.X", n);
102 | p.Add("LOCATION.X_FRAC", f);
103 | }
104 | {
105 | var (n, f) = Utils.CoordToDxpFrac(Location.Y);
106 | p.Add("LOCATION.Y", n);
107 | p.Add("LOCATION.Y_FRAC", f);
108 | }
109 | p.Add("COLOR", Color);
110 | p.Add("AREACOLOR", AreaColor);
111 | }
112 |
113 | // MoveTo(coord, rot)
114 | // MoveBy(coord)
115 | }
116 | }
117 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 | # AltiumSharp
3 | AltiumSharp is a .NET library that makes it easy to read and write Altium Designer library files using C# without requiring Altium to be installed on your system. With AltiumSharp, you can programmatically access and modify the schematics, PCBs, components and symbols created in Altium, making it a powerful tool for automating tasks. This library was specifically created to make it easier to automate library management tasks.
4 |
5 | Altium Designer is a leading electronic design automation software used for creating printed circuit board (PCB) designs. It stores information in a proprietary file format, which can be difficult to work with using traditional methods. AltiumSharp simplifies this process, allowing you to easily manipulate these files without the need for Altium Designer to be installed on your system.
6 |
7 | In addition to supporting PcbLib and SchLib files, AltiumSharp also supports SchDoc and PcbDoc files. With AltiumSharp, you can easily read, write, and render Altium files in your .NET projects. Whether you're looking to automate library management tasks or simply need a more convenient way to work with Altium files, AltiumSharp has you covered.
8 |
9 | Many thanks to Tiago Trinidad (@Kronal on [Discord](https://discord.gg/MEQ5Xe5)) for his huge efforts on this library.
10 |
11 | # Usage
12 | Before using AltiumSharp, you will need to add the following NuGet references to your project:
13 | * [OpenMcdf](https://www.nuget.org/packages/OpenMcdf) by [ironfede](https://github.com/ironfede)
14 | * [System.Text.Encoding.CodePages](https://www.nuget.org/packages/System.Text.Encoding.CodePages)
15 |
16 | Once you have these references added, you can use the AltiumSharp library to read and write Altium library files and render components as images. Check out the examples in the readme for more information on how to use AltiumSharp in your projects.
17 |
18 | ## Opening a PcbLib File
19 | Here's an example of how you can use AltiumSharp to open a PcbLib file and iterate through its components:
20 | ```csharp
21 | // Open a PcbLib file.
22 | using (var reader = new PcbLibReader(fileName))
23 | {
24 | // Read the file.
25 | reader.Read();
26 |
27 | // Iterate through each component in the library.
28 | foreach (var component in reader.Components)
29 | {
30 | // Print information about the component.
31 | Console.WriteLine($"Name: {component.Name}");
32 | Console.WriteLine($"Number of Pads: {component.Pads}");
33 | Console.WriteLine($"Number of Primitives: {component.Primitives.Count()}");
34 | }
35 |
36 | // Retrieve settings from the header.
37 | _displayUnit = reader.Header.DisplayUnit;
38 | _snapGridSize = reader.Header.SnapGridSize;
39 | _components = reader.Components.Cast().ToList();
40 | }
41 | ```
42 |
43 | ## Reading and Writing a SchLib File
44 | AltiumSharp also provides support for reading and writing SchLib files, as shown in this example:
45 | ```csharp
46 | // Set the path to the directory containing the SchLib files.
47 | string path = @"C:\altium-library\symbols\ARM Cortex";
48 |
49 | // Array of filenames to process.
50 | string[] files = {
51 | "SCH - ARM CORTEX - NXP LPC176X LQFP100.SCHLIB",
52 | "SCH - ARM CORTEX - NXP LPC176X TFBGA100.SCHLIB",
53 | "SCH - ARM CORTEX - NXP LPC176X WLCSP100.SCHLIB"
54 | };
55 |
56 | // Loop through each file.
57 | foreach (var file in files)
58 | {
59 | // Read the SchLib file.
60 | using (var reader = new AltiumSharp.SchLibReader())
61 | {
62 | var schLib = reader.Read(Path.Combine(path, file));
63 |
64 | // Iterate through each component in the library.
65 | foreach (var component in schLib.Items)
66 | {
67 | // Print the component name and comment.
68 | Console.WriteLine($"Name: {((IComponent)component).Name}");
69 | Console.WriteLine($"Comment: {component.Comment}");
70 | }
71 |
72 | // Write the SchLib file.
73 | using (var writer = new SchLibWriter())
74 | {
75 | writer.Write(schLib, Path.Combine(path, file), true);
76 | }
77 | }
78 | }
79 | ```
80 |
81 | ## Rendering a Component
82 | AltiumSharp includes a renderer for PcbLib files that allows you to display components in your own application. Here's an example of how you can use the renderer to render a component:
83 | ```csharp
84 | // Create a PcbLibRenderer.
85 | var renderer = new PcbLibRenderer();
86 |
87 | // Check if the renderer was created successfully.
88 | if (renderer != null)
89 | {
90 | // Set the component to be rendered.
91 | renderer.Component = _activeComponent;
92 |
93 | // Create a Bitmap to hold the rendered image.
94 | var image = new Bitmap(pictureBox.Width, pictureBox.Height);
95 |
96 | // Use a Graphics object to draw on the Bitmap.
97 | using (var g = Graphics.FromImage(image))
98 | {
99 | // Render the component to the Bitmap.
100 | renderer.Render(g, pictureBox.Width, pictureBox.Height, _autoZoom, fastRendering);
101 | }
102 |
103 | // Update the picture box with the rendered image.
104 | pictureBox.Image = image;
105 |
106 | // Reset the auto zoom flag.
107 | _autoZoom = false;
108 | }
109 | ```
--------------------------------------------------------------------------------
/LibraryViewer/Properties/Resources.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 | text/microsoft-resx
107 |
108 |
109 | 2.0
110 |
111 |
112 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
113 |
114 |
115 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
--------------------------------------------------------------------------------
/LibraryViewer/PropertyViewer.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
--------------------------------------------------------------------------------
/AltiumSharp/Records/Pcb/PcbVia.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using OriginalCircuit.AltiumSharp.BasicTypes;
5 | using OriginalCircuit.AltiumSharp.Records;
6 |
7 | namespace OriginalCircuit.AltiumSharp
8 | {
9 | public class PcbVia : PcbPrimitive
10 | {
11 | public override PcbPrimitiveDisplayInfo GetDisplayInfo() =>
12 | new PcbPrimitiveDisplayInfo($"{FromLayer} to {ToLayer}", Diameter, null);
13 |
14 | public override PcbPrimitiveObjectId ObjectId => PcbPrimitiveObjectId.Via;
15 |
16 | public CoordPoint Location { get; set; }
17 | public Coord HoleSize { get; set; }
18 | public Layer FromLayer { get; set; }
19 | public Layer ToLayer { get; set; }
20 | public Coord ThermalReliefAirGapWidth { get; set; }
21 | public int ThermalReliefConductors { get; set; }
22 | public Coord ThermalReliefConductorsWidth { get; set; }
23 | public bool SolderMaskExpansionManual { get; set; }
24 | public Coord SolderMaskExpansion { get; set; }
25 | public PcbStackMode DiameterStackMode { get; set; }
26 | public IList Diameters { get; } = new Coord[32];
27 |
28 | public Coord Diameter
29 | {
30 | get => Diameters[Diameters.Count - 1];
31 | set => SetDiameterAll(value);
32 | }
33 |
34 | public Coord DiameterTop
35 | {
36 | get => DiameterStackMode == PcbStackMode.Simple ? Diameter : Diameters[0];
37 | set => SetDiameterTop(value);
38 | }
39 |
40 | public Coord DiameterMiddle
41 | {
42 | get => DiameterStackMode == PcbStackMode.Simple ? Diameter : Diameters[1];
43 | set => SetDiameterMiddle(value);
44 | }
45 |
46 | public Coord DiameterBottom
47 | {
48 | get => DiameterStackMode == PcbStackMode.Simple ? Diameter : Diameters[Diameters.Count - 1];
49 | set => SetDiameterBottom(value);
50 | }
51 |
52 | public PcbVia() : base()
53 | {
54 | Diameter = Coord.FromMils(50);
55 | HoleSize = Coord.FromMils(28);
56 | FromLayer = 1;
57 | ToLayer = 32;
58 | ThermalReliefAirGapWidth = Coord.FromMils(10);
59 | ThermalReliefConductors = 4;
60 | ThermalReliefConductorsWidth = Coord.FromMils(10);
61 | SolderMaskExpansionManual = false;
62 | SolderMaskExpansion = Coord.FromMils(4);
63 | }
64 |
65 | internal List GetParts()
66 | {
67 | var result = new List();
68 | if (ToLayer.Name == "BottomLayer" && !IsTentingBottom)
69 | {
70 | result.Add(LayerMetadata.Get("BottomSolder").Id);
71 | }
72 | if (FromLayer.Name == "TopLayer" && !IsTentingTop)
73 | {
74 | result.Add(LayerMetadata.Get("TopSolder").Id);
75 | }
76 | result.Add(Layer);
77 | result.Add(LayerMetadata.Get("ViaHoleLayer").Id);
78 | if (FromLayer.Name != "TopLayer" || ToLayer.Name != "BottomLayer")
79 | {
80 | result.Add(FromLayer);
81 | result.Add(ToLayer);
82 | }
83 | return result;
84 | }
85 |
86 | internal CoordRect CalculatePartRect(LayerMetadata metadata, bool useAbsolutePosition)
87 | {
88 | var solderMaskExpansion = SolderMaskExpansionManual ? SolderMaskExpansion : Utils.MilsToCoord(8);
89 | var solderMaskExpansionTop = IsTentingTop ? Utils.MilsToCoord(0) : solderMaskExpansion;
90 | var solderMaskExpansionBottom = IsTentingBottom ? Utils.MilsToCoord(0) : solderMaskExpansion;
91 | Coord diameter;
92 | if (metadata.Name == "TopSolder")
93 | {
94 | diameter = DiameterTop + solderMaskExpansionTop;
95 | }
96 | else if (metadata.Name == "BottomSolder")
97 | {
98 | diameter = DiameterBottom + solderMaskExpansionBottom;
99 | }
100 | else if (metadata.Name == "MultiLayer")
101 | {
102 | diameter = Diameter;
103 | }
104 | else
105 | {
106 | diameter = HoleSize;
107 | }
108 |
109 | Coord x = -diameter / 2;
110 | Coord y = -diameter / 2;
111 | if (useAbsolutePosition)
112 | {
113 | x += Location.X;
114 | y += Location.Y;
115 | }
116 | return new CoordRect(x, y, diameter, diameter);
117 | }
118 |
119 | public override CoordRect CalculateBounds()
120 | {
121 | var result = CoordRect.Empty;
122 | foreach (var p in GetParts())
123 | {
124 | result = CoordRect.Union(result, CalculatePartRect(p.Metadata, true));
125 | }
126 | return result;
127 | }
128 |
129 | private void SetDiameterAll(Coord value)
130 | {
131 | for (int i = 0; i < Diameters.Count; ++i)
132 | {
133 | Diameters[i] = value;
134 | }
135 | }
136 |
137 | private void SetDiameterTop(Coord value)
138 | {
139 | if (DiameterStackMode == PcbStackMode.Simple)
140 | {
141 | SetDiameterAll(value);
142 | }
143 | else
144 | {
145 | Diameters[0] = value;
146 | }
147 | }
148 |
149 | private void SetDiameterMiddle(Coord value)
150 | {
151 | if (DiameterStackMode == PcbStackMode.Simple)
152 | {
153 | SetDiameterAll(value);
154 | }
155 | else
156 | {
157 | for (int i = 1; i < Diameters.Count - 1; ++i)
158 | {
159 | Diameters[i] = value;
160 | }
161 | }
162 | }
163 |
164 | private void SetDiameterBottom(Coord value)
165 | {
166 | if (DiameterStackMode == PcbStackMode.Simple)
167 | {
168 | SetDiameterAll(value);
169 | }
170 | else
171 | {
172 | Diameters[Diameters.Count - 1] = value;
173 | }
174 | }
175 | }
176 | }
--------------------------------------------------------------------------------
/AltiumSharp/Records/Pcb/PcbComponentBody.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Drawing;
4 | using System.Linq;
5 | using OriginalCircuit.AltiumSharp.BasicTypes;
6 |
7 | namespace OriginalCircuit.AltiumSharp.Records
8 | {
9 | public class PcbComponentBody : PcbPrimitive
10 | {
11 | public override PcbPrimitiveObjectId ObjectId => PcbPrimitiveObjectId.ComponentBody;
12 | public List Outline { get; } = new List();
13 |
14 | public string V7Layer { get; set; }
15 | public string Name { get; set; }
16 | public int Kind { get; set; }
17 | public int SubPolyIndex { get; set; }
18 | public int UnionIndex { get; set; }
19 | public Coord ArcResolution { get; set; }
20 | public bool IsShapeBased { get; set; }
21 | public Coord StandOffHeight { get; set; }
22 | public Coord OverallHeight { get; set; }
23 | public int BodyProjection { get; set; }
24 | public Color BodyColor3D { get; set; }
25 | public double BodyOpacity3D { get; set; }
26 | public string Identifier { get; set; }
27 | public string Texture { get; set; }
28 | public CoordPoint TextureCenter { get; set; }
29 | public CoordPoint TextureSize { get; set; }
30 | public double TextureRotation { get; set; }
31 | public string ModelId { get; set; }
32 | public int ModelChecksum { get; set; }
33 | public bool ModelEmbed { get; set; }
34 | public CoordPoint Model2DLocation { get; set; }
35 | public double Model2DRotation { get; set; }
36 | public double Model3DRotX { get; set; }
37 | public double Model3DRotY { get; set; }
38 | public double Model3DRotZ { get; set; }
39 | public Coord Model3DDz { get; set; }
40 | public int ModelSnapCount { get; set; }
41 | public int ModelType { get; set; }
42 |
43 | public string StepModel { get; set; }
44 |
45 | public PcbComponentBody()
46 | {
47 | V7Layer = "MECHANICAL1";
48 | SubPolyIndex = -1;
49 | BodyColor3D = ColorTranslator.FromWin32(14737632);
50 | BodyOpacity3D = 1.0;
51 | ModelEmbed = true;
52 | ModelType = 1;
53 | }
54 |
55 | public override CoordRect CalculateBounds()
56 | {
57 | return new CoordRect(
58 | new CoordPoint(Outline.Min(p => p.X), Outline.Min(p => p.Y)),
59 | new CoordPoint(Outline.Max(p => p.X), Outline.Max(p => p.Y)));
60 | }
61 |
62 | public void ImportFromParameters(ParameterCollection p)
63 | {
64 | if (p == null) throw new ArgumentNullException(nameof(p));
65 |
66 | V7Layer = p["V7_LAYER"].AsStringOrDefault();
67 | Name = p["NAME"].AsStringOrDefault();
68 | Kind = p["KIND"].AsIntOrDefault();
69 | SubPolyIndex = p["SUBPOLYINDEX"].AsIntOrDefault();
70 | UnionIndex = p["UNIONINDEX"].AsIntOrDefault();
71 | ArcResolution = p["ARCRESOLUTION"].AsCoord();
72 | IsShapeBased = p["ISSHAPEBASED"].AsBool();
73 | StandOffHeight = p["STANDOFFHEIGHT"].AsCoord();
74 | OverallHeight = p["OVERALLHEIGHT"].AsCoord();
75 | BodyProjection = p["BODYPROJECTION"].AsIntOrDefault();
76 | ArcResolution = p["ARCRESOLUTION"].AsCoord();
77 | BodyColor3D = p["BODYCOLOR3D"].AsColorOrDefault();
78 | BodyOpacity3D = p["BODYOPACITY3D"].AsDoubleOrDefault();
79 | Identifier = new string(p["IDENTIFIER"].AsIntList(',').Select(v => (char)v).ToArray());
80 | Texture = p["TEXTURE"].AsStringOrDefault();
81 | TextureCenter = new CoordPoint(p["TEXTURECENTERX"].AsCoord(), p["TEXTURECENTERY"].AsCoord());
82 | TextureSize = new CoordPoint(p["TEXTURESIZEX"].AsCoord(), p["TEXTURESIZEY"].AsCoord());
83 | TextureRotation = p["TEXTUREROTATION"].AsDouble();
84 | ModelId = p["MODELID"].AsStringOrDefault();
85 | ModelChecksum = p["MODEL.CHECKSUM"].AsIntOrDefault();
86 | ModelEmbed = p["MODEL.EMBED"].AsBool();
87 | Model2DLocation = new CoordPoint(p["MODEL.2D.X"].AsCoord(), p["MODEL.2D.Y"].AsCoord());
88 | Model2DRotation = p["MODEL.2D.ROTATION"].AsDoubleOrDefault();
89 | Model3DRotX = p["MODEL.3D.ROTX"].AsDoubleOrDefault();
90 | Model3DRotY = p["MODEL.3D.ROTY"].AsDoubleOrDefault();
91 | Model3DRotZ = p["MODEL.3D.ROTZ"].AsDoubleOrDefault();
92 | Model3DDz = p["MODEL.3D.DZ"].AsCoord();
93 | ModelSnapCount = p["MODEL.SNAPCOUNT"].AsIntOrDefault();
94 | ModelType = p["MODEL.MODELTYPE"].AsIntOrDefault();
95 | }
96 |
97 | public void ExportToParameters(ParameterCollection p)
98 | {
99 | if (p == null) throw new ArgumentNullException(nameof(p));
100 |
101 | p.UseLongBooleans = true;
102 |
103 | p.Add("V7_LAYER", V7Layer);
104 | p.Add("NAME", Name);
105 | p.Add("KIND", Kind);
106 | p.Add("SUBPOLYINDEX", SubPolyIndex);
107 | p.Add("UNIONINDEX", UnionIndex);
108 | p.Add("ARCRESOLUTION", ArcResolution);
109 | p.Add("ISSHAPEBASED", IsShapeBased);
110 | p.Add("STANDOFFHEIGHT", StandOffHeight);
111 | p.Add("OVERALLHEIGHT", OverallHeight);
112 | p.Add("BODYPROJECTION", BodyProjection);
113 | p.Add("ARCRESOLUTION", ArcResolution);
114 | p.Add("BODYCOLOR3D", BodyColor3D);
115 | p.Add("BODYOPACITY3D", BodyOpacity3D);
116 | p.Add("IDENTIFIER", string.Join(",", Identifier?.Select(c => (int)c) ?? Enumerable.Empty()));
117 | p.Add("TEXTURE", Texture);
118 | p.Add("TEXTURECENTERX", TextureCenter.X);
119 | p.Add("TEXTURECENTERY", TextureCenter.Y);
120 | p.Add("TEXTURESIZEX", TextureSize.X);
121 | p.Add("TEXTURESIZEY", TextureSize.Y);
122 | p.Add("TEXTUREROTATION", TextureRotation);
123 | p.Add("MODELID", ModelId);
124 | p.Add("MODEL.CHECKSUM", ModelChecksum);
125 | p.Add("MODEL.EMBED", ModelEmbed);
126 | p.Add("MODEL.2D.X", Model2DLocation.X);
127 | p.Add("MODEL.2D.Y", Model2DLocation.Y);
128 | p.Add("MODEL.2D.ROTATION", Model2DRotation);
129 | p.Add("MODEL.3D.ROTX", Model3DRotX);
130 | p.Add("MODEL.3D.ROTY", Model3DRotY);
131 | p.Add("MODEL.3D.ROTZ", Model3DRotZ);
132 | p.Add("MODEL.3D.DZ", Model3DDz);
133 | p.Add("MODEL.SNAPCOUNT", ModelSnapCount);
134 | p.Add("MODEL.MODELTYPE", ModelType);
135 | }
136 |
137 | public ParameterCollection ExportToParameters()
138 | {
139 | var parameters = new ParameterCollection();
140 | ExportToParameters(parameters);
141 | return parameters;
142 | }
143 | }
144 | }
145 |
--------------------------------------------------------------------------------
/AltiumSharp/Extensions.cs:
--------------------------------------------------------------------------------
1 | using OpenMcdf;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.IO;
5 | using System.Linq;
6 | using System.Text;
7 | using System.Text.RegularExpressions;
8 | using System.Globalization;
9 |
10 | namespace OriginalCircuit.AltiumSharp
11 | {
12 | public static class CFItemExtensions
13 | {
14 | public static CFItem TryGetChild(this CFItem item, string name)
15 | {
16 | if (item is CFStorage storage)
17 | {
18 | if (storage.TryGetStorage(name, out var resultStorage))
19 | {
20 | return resultStorage;
21 | }
22 | else if (storage.TryGetStream(name, out var resultStream))
23 | {
24 | return resultStream;
25 | }
26 | }
27 |
28 | return null;
29 | }
30 |
31 | public static CFItem GetChild(this CFItem item, string name)
32 | {
33 | if (item == null) throw new ArgumentNullException(nameof(item));
34 |
35 | if (item is CFStorage storage)
36 | {
37 | return TryGetChild(item, name) ?? throw new ArgumentException($"Item '{name}' doesn't exists within storage '{storage.Name}'.", nameof(name));
38 | }
39 | else
40 | {
41 | throw new InvalidOperationException($"Item '{item.Name}' is a stream and cannot have child items.");
42 | }
43 | }
44 |
45 | public static IEnumerable Children(this CFItem item)
46 | {
47 | if (item == null) throw new ArgumentNullException(nameof(item));
48 |
49 | var result = new List();
50 | if (item is CFStorage storage)
51 | {
52 | storage.VisitEntries(childItem => result.Add(childItem), false);
53 | }
54 | else
55 | {
56 | throw new InvalidOperationException($"Item '{item.Name}' is a stream and cannot have child items.");
57 | }
58 | return result;
59 | }
60 | }
61 |
62 | public static class CFStorageExtensions
63 | {
64 | public static CFStream GetOrAddStream(this CFStorage storage, string streamName)
65 | {
66 | if (storage == null) throw new ArgumentNullException(nameof(storage));
67 |
68 | return storage.TryGetStream(streamName, out var childStream) ? childStream : storage.AddStream(streamName);
69 | }
70 |
71 | public static CFStorage GetOrAddStorage(this CFStorage storage, string storageName)
72 | {
73 | if (storage == null) throw new ArgumentNullException(nameof(storage));
74 |
75 | return storage.TryGetStorage(storageName, out var childStorage) ? childStorage : storage.AddStorage(storageName);
76 | }
77 | }
78 |
79 | public static class CFStreamExtensions
80 | {
81 | public static MemoryStream GetMemoryStream(this CFStream stream)
82 | {
83 | if (stream == null) throw new ArgumentNullException(nameof(stream));
84 |
85 | return new MemoryStream(stream.GetData());
86 | }
87 |
88 | public static BinaryReader GetBinaryReader(this CFStream stream, Encoding encoding)
89 | {
90 | return new BinaryReader(stream.GetMemoryStream(), encoding, false);
91 | }
92 |
93 | public static BinaryReader GetBinaryReader(this CFStream stream)
94 | {
95 | return GetBinaryReader(stream, Encoding.UTF8);
96 | }
97 |
98 | public static void Write(this CFStream stream, Action action, Encoding encoding)
99 | {
100 | using (var memoryStream = new MemoryStream())
101 | using (var writer = new BinaryWriter(memoryStream, encoding))
102 | {
103 | action?.Invoke(writer);
104 | stream.SetData(memoryStream.ToArray());
105 | }
106 | }
107 |
108 | public static void Write(this CFStream stream, Action action)
109 | {
110 | stream.Write(action, Encoding.UTF8);
111 | }
112 | }
113 |
114 | public static class CompoundFileExtensions
115 | {
116 | private static readonly Regex PathElementSplitter = new Regex(@"(?(this T @enum, T flag, bool value = true) where T : Enum
160 | {
161 | var intEnum = Convert.ToInt32(@enum, CultureInfo.InvariantCulture);
162 | var intFlag = Convert.ToInt32(flag, CultureInfo.InvariantCulture);
163 | if (value)
164 | {
165 | return (T)Enum.ToObject(typeof(T), intEnum | intFlag);
166 | }
167 | else
168 | {
169 | return (T)Enum.ToObject(typeof(T), intEnum & ~intFlag);
170 | }
171 | }
172 |
173 | public static void SetFlag(ref this T @enum, T flag, bool value = true) where T : struct, Enum =>
174 | @enum = WithFlag(@enum, flag, value);
175 |
176 | public static void ClearFlag(ref this T @enum, T flag) where T : struct, Enum =>
177 | SetFlag(ref @enum, flag, false);
178 | }
179 | }
180 |
--------------------------------------------------------------------------------
/AltiumSharp/BasicTypes/Utils.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Globalization;
4 | using System.Linq;
5 | using System.Text;
6 | using System.Text.RegularExpressions;
7 |
8 | namespace OriginalCircuit.AltiumSharp.BasicTypes
9 | {
10 | public static class Utils
11 | {
12 | public static readonly Encoding Win1252Encoding = CodePagesEncodingProvider.Instance.GetEncoding(1252);
13 |
14 | public const double InternalUnits = 10000.0;
15 |
16 | public static double MilsToMMs(double mils) => mils * 0.0254;
17 |
18 | public static double MMsToMils(double mms) => mms / 0.0254;
19 |
20 | public static double CoordToMils(Coord coord) => (coord / InternalUnits);
21 |
22 | public static Coord MilsToCoord(double mils) => (int)(mils * InternalUnits);
23 |
24 | public static double CoordToMMs(Coord coord) => MilsToMMs(CoordToMils(coord));
25 |
26 | public static Coord MMsToCoord(double mms) => MilsToCoord(MMsToMils(mms));
27 |
28 | public static double CoordToCMs(Coord coord) => CoordToMMs(coord) * 0.1;
29 |
30 | public static Coord CMsToCoord(double cms) => MMsToCoord(cms * 10.0);
31 |
32 | public static double CoordToInches(Coord coord) => CoordToMils(coord) * 0.001;
33 |
34 | internal static Coord InchesToCoord(double inches) => MilsToCoord(inches * 1000.0);
35 |
36 | public static double CoordToDxp(Coord coord) =>
37 | CoordToMils(coord) / 10.0;
38 |
39 | public static Coord DxpToCoord(double value) =>
40 | MilsToCoord(value * 10.0);
41 |
42 | public static double DxpFracToMils(int num, int frac) =>
43 | num * 10.0 + frac / 10000.0;
44 |
45 | public static (int num, int frac) MilsToDxpFrac(double mils) =>
46 | ((int)mils / 10, (int)Math.Round((mils / 10.0 - Math.Truncate(mils / 10.0)) * 100000));
47 |
48 | public static (int num, int frac) CoordToDxpFrac(Coord coord) =>
49 | MilsToDxpFrac(CoordToMils(coord));
50 |
51 | public static Coord DxpFracToCoord(int num, int frac) =>
52 | MilsToCoord(DxpFracToMils(num, frac));
53 |
54 | public static Coord MetersToCoord(double meters) => MMsToCoord(meters * 1000.0);
55 |
56 | public static double CoordToMeters(Coord coord) => CoordToMMs(coord) * 0.001;
57 |
58 | public static Coord StringToCoordUnit(string input, out Unit unit) =>
59 | Unit.StringToCoordUnit(input, out unit);
60 |
61 | public static bool TryStringToCoordUnit(string input, out Coord result, out Unit unit) =>
62 | Unit.TryStringToCoordUnit(input, out result, out unit);
63 |
64 | public static string CoordUnitToString(Coord coord, Unit unit) =>
65 | CoordUnitToString(coord, unit, 1);
66 |
67 | public static string CoordUnitToString(Coord coord, Unit unit, Coord grid) =>
68 | Unit.CoordUnitToString(coord, unit, grid);
69 |
70 | public static string LayerToString(Layer layer) => LayerMetadata.GetName(layer);
71 |
72 | public static Layer StringToLayer(string layer) => LayerMetadata.Get(layer ?? "").Id;
73 |
74 | public static string UnitToString(Unit unit) => unit.ToString();
75 |
76 | internal static double StringToDouble(string str) =>
77 | double.Parse(str, NumberStyles.Any, CultureInfo.InvariantCulture);
78 |
79 | ///
80 | /// Makes sure angle is between [0, 360]
81 | ///
82 | public static double NormalizeAngle(double degrees) =>
83 | (degrees > 0 && degrees % 360.0 == 0) ? 360.0 : (degrees % 360.0 + 360.0) % 360.0;
84 |
85 | internal static bool TryStringToDouble(string str, out double value) =>
86 | double.TryParse(str, NumberStyles.Any, CultureInfo.InvariantCulture, out value);
87 |
88 | internal static string Format(string format, params object[] args) =>
89 | string.Format(CultureInfo.InvariantCulture, format, args);
90 |
91 | internal static ref CoordPoint[] TranslatePoints(ref CoordPoint[] points, in CoordPoint value)
92 | {
93 | if (value == CoordPoint.Zero) return ref points;
94 |
95 | for (var i = 0; i < points.Length; ++i)
96 | {
97 | var p = points[i];
98 | points[i] = new CoordPoint(p.X + value.X, p.Y + value.Y);
99 | }
100 |
101 | return ref points;
102 | }
103 |
104 | internal static ref CoordPoint[] RotatePoints(ref CoordPoint[] points,
105 | in CoordPoint anchor, double angleDegrees)
106 | {
107 | var angleRadians = -angleDegrees * Math.PI / 180.0;
108 | var cosAngle = Math.Cos(angleRadians);
109 | var sinAngle = Math.Sin(angleRadians);
110 | for (var i = 0; i < points.Length; ++i)
111 | {
112 | var (x, y) = points[i];
113 | double localX = x - anchor.X;
114 | double localY = y - anchor.Y;
115 | var rotatedX = localX * cosAngle + localY * sinAngle;
116 | var rotatedY = localY * cosAngle - localX * sinAngle;
117 | points[i] = new CoordPoint(anchor.X + (int)rotatedX, anchor.Y + (int)rotatedY);
118 | }
119 | return ref points;
120 | }
121 |
122 | private static Random rng = new Random();
123 |
124 | public static string GenerateUniqueId()
125 | {
126 | var result = new char[8];
127 | for (int i = 0; i < 8; ++i)
128 | {
129 | result[i] = (char)rng.Next('A', 'Z');
130 | }
131 | return new string(result);
132 | }
133 |
134 | private static Regex _designatorParser = new Regex(@"^(?.*?)(?\d*)\s*$");
135 |
136 | ///
137 | /// Generates a new designator by taking the last designator in order and then incrementing any ending integer.
138 | ///
139 | ///
140 | /// This mimicks the behavior of AD's Schematic Editor context menu "Place > Pin", which works very differently
141 | /// from AD's Properties pin list "Add" button, and the context menu behavior was chosen as it seemed more intuitive.
142 | ///
143 | public static string GenerateDesignator(IEnumerable existingDesignators)
144 | {
145 | var largestDesignator = existingDesignators
146 | .Select(s => _designatorParser.Match(s ?? ""))
147 | .Select(m => (m.Groups["Prefix"]?.Value ?? "", int.TryParse(m.Groups["Number"]?.Value ?? "", out int n) ? n : (int?)null))
148 | .OrderBy(pn => pn)
149 | .LastOrDefault();
150 | if (largestDesignator.Item2 != null)
151 | {
152 | return $"{largestDesignator.Item1}{largestDesignator.Item2 + 1}";
153 | }
154 | else if (largestDesignator.Item1 != null)
155 | {
156 | return largestDesignator.Item1;
157 | }
158 | else
159 | {
160 | return "1";
161 | }
162 | }
163 | }
164 | }
165 |
--------------------------------------------------------------------------------
/AltiumSharp/Records/Sch/SchDocumentHeader.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Drawing;
4 | using System.Globalization;
5 | using System.Linq;
6 | using OriginalCircuit.AltiumSharp.BasicTypes;
7 |
8 | namespace OriginalCircuit.AltiumSharp.Records
9 | {
10 | public abstract class SchDocumentHeader : SchPrimitive
11 | {
12 | public string UniqueId { get; internal set; }
13 | public List<(string FontName, int Size, int Rotation, bool Italic, bool Bold, bool Underline)> FontId { get; } =
14 | new List<(string FontName, int Size, int Rotation, bool Italic, bool Bold, bool Underline)>();
15 | public bool UseMbcs { get; set; }
16 | public bool IsBoc { get; set; }
17 | public bool HotSpotGridOn { get; internal set; }
18 | public int HotSpotGridSize { get; internal set; }
19 | public int SheetStyle { get; set; }
20 | public int SystemFont { get; set; }
21 | public bool BorderOn { get; set; }
22 | public bool TitleBlockOn { get; set; }
23 | public int SheetNumberSpaceSize { get; internal set; }
24 | public Color AreaColor { get; set; }
25 | public bool SnapGridOn { get; set; }
26 | public Coord SnapGridSize { get; set; }
27 | public bool VisibleGridOn { get; set; }
28 | public Coord VisibleGridSize { get; set; }
29 | public int CustomX { get; internal set; }
30 | public int CustomY { get; internal set; }
31 | public int CustomXZones { get; internal set; }
32 | public int CustomYZones { get; internal set; }
33 | public int CustomMarginWidth { get; internal set; }
34 | public bool UseCustomSheet { get; internal set; }
35 | public bool ReferenceZonesOn { get; internal set; }
36 | public bool ShowTemplateGraphics { get; internal set; }
37 | public Unit DisplayUnit { get; set; }
38 |
39 | public SchDocumentHeader() : base()
40 | {
41 | FontId.Add(("Times New Roman", 10, 0, false, false, false));
42 | SystemFont = 1;
43 | UseMbcs = true;
44 | IsBoc = true;
45 | BorderOn = true;
46 | AreaColor = ColorTranslator.FromWin32(16317695);
47 | SnapGridOn = true;
48 | SnapGridSize = Utils.DxpToCoord(10);
49 | VisibleGridOn = true;
50 | VisibleGridSize = Utils.DxpToCoord(10);
51 | }
52 |
53 | public override void ImportFromParameters(ParameterCollection p)
54 | {
55 | if (p == null) throw new ArgumentNullException(nameof(p));
56 |
57 | base.ImportFromParameters(p);
58 | UniqueId = p["UNIQUEID"].AsStringOrDefault();
59 | var fontIdCount = p["FONTIDCOUNT"].AsIntOrDefault();
60 | FontId.Clear();
61 | for (int i = 0; i < fontIdCount; ++i)
62 | {
63 | var fontId = (
64 | p[$"FONTNAME{i+1}"].AsStringOrDefault(),
65 | p[$"SIZE{i+1}"].AsIntOrDefault(),
66 | p[$"ROTATION{i+1}"].AsIntOrDefault(),
67 | p[$"ITALIC{i+1}"].AsBool(),
68 | p[$"BOLD{i+1}"].AsBool(),
69 | p[$"UNDERLINE{i+1}"].AsBool()
70 | );
71 | FontId.Add(fontId);
72 | }
73 | UseMbcs = p["USEMBCS"].AsBool();
74 | IsBoc = p["ISBOC"].AsBool();
75 | HotSpotGridOn = p["HOTSPOTGRIDON"].AsBool();
76 | HotSpotGridSize = p["HOTSPOTGRIDSIZE"].AsIntOrDefault();
77 | SheetStyle = p["SHEETSTYLE"].AsIntOrDefault();
78 | SystemFont = p["SYSTEMFONT"].AsIntOrDefault(1);
79 | BorderOn = p["BORDERON"].AsBool();
80 | TitleBlockOn = p["TITLEBLOCKON"].AsBool();
81 | SheetNumberSpaceSize = p["SHEETNUMBERSPACESIZE"].AsIntOrDefault();
82 | AreaColor = p["AREACOLOR"].AsColorOrDefault();
83 | SnapGridOn = p["SNAPGRIDON"].AsBool();
84 | SnapGridSize = Utils.DxpFracToCoord(p["SNAPGRIDSIZE"].AsIntOrDefault(), p["SNAPGRIDSIZE_FRAC"].AsIntOrDefault());
85 | VisibleGridOn = p["VISIBLEGRIDON"].AsBool();
86 | VisibleGridSize = Utils.DxpFracToCoord(p["VISIBLEGRIDSIZE"].AsIntOrDefault(), p["VISIBLEGRIDSIZE_FRAC"].AsIntOrDefault());
87 | CustomX = p["CUSTOMX"].AsIntOrDefault();
88 | CustomY = p["CUSTOMY"].AsIntOrDefault();
89 | CustomXZones = p["CUSTOMXZONES"].AsIntOrDefault();
90 | CustomYZones = p["CUSTOMYZONES"].AsIntOrDefault();
91 | CustomMarginWidth = p["CUSTOMMARGINWIDTH"].AsIntOrDefault();
92 | UseCustomSheet = p["USECUSTOMSHEET"].AsBool();
93 | ReferenceZonesOn = p["REFERENCEZONESON"].AsBool();
94 | ShowTemplateGraphics = p["SHOWTEMPLATEGRAPHICS"].AsBool();
95 | DisplayUnit = (Unit)p["DISPLAY_UNIT"].AsIntOrDefault();
96 | }
97 |
98 | public override void ExportToParameters(ParameterCollection p)
99 | {
100 | if (p == null) throw new ArgumentNullException(nameof(p));
101 |
102 | base.ExportToParameters(p);
103 | p.Add("UNIQUEID", UniqueId);
104 | p.Add("FONTIDCOUNT", FontId.Count);
105 | for (var i = 0; i < FontId.Count; ++i)
106 | {
107 | var fontId = FontId[i];
108 | p.Add($"SIZE{i+1}", fontId.Size);
109 | p.Add($"ROTATION{i+1}", fontId.Rotation);
110 | p.Add($"ITALIC{i+1}", fontId.Italic);
111 | p.Add($"BOLD{i+1}", fontId.Bold);
112 | p.Add($"UNDERLINE{i+1}", fontId.Underline);
113 | p.Add($"FONTNAME{i+1}", fontId.FontName);
114 | }
115 | p.Add("USEMBCS", UseMbcs);
116 | p.Add("ISBOC", IsBoc);
117 | p.Add("HOTSPOTGRIDON", HotSpotGridOn);
118 | p.Add("HOTSPOTGRIDSIZE", HotSpotGridSize);
119 | p.Add("SHEETSTYLE", SheetStyle);
120 | p.Add("SYSTEMFONT", SystemFont);
121 | p.Add("BORDERON", BorderOn);
122 | p.Add("TITLEBLOCKON", TitleBlockOn);
123 | p.Add("SHEETNUMBERSPACESIZE", SheetNumberSpaceSize);
124 | p.Add("AREACOLOR", AreaColor);
125 | p.Add("SNAPGRIDON", SnapGridOn);
126 | {
127 | var (n, f) = Utils.CoordToDxpFrac(SnapGridSize);
128 | if (n != 0 || f != 0) p.Add("SNAPGRIDSIZE", n);
129 | if (f != 0) p.Add("SNAPGRIDSIZE" + "_FRAC", f);
130 | }
131 | p.Add("VISIBLEGRIDON", VisibleGridOn);
132 | {
133 | var (n, f) = Utils.CoordToDxpFrac(VisibleGridSize);
134 | if (n != 0 || f != 0) p.Add("VISIBLEGRIDSIZE", n);
135 | if (f != 0) p.Add("VISIBLEGRIDSIZE" + "_FRAC", f);
136 | }
137 | p.Add("CUSTOMX", CustomX);
138 | p.Add("CUSTOMY", CustomY);
139 | p.Add("CUSTOMXZONES", CustomXZones);
140 | p.Add("CUSTOMYZONES", CustomYZones);
141 | p.Add("CUSTOMMARGINWIDTH", CustomMarginWidth);
142 | p.Add("USECUSTOMSHEET", UseCustomSheet);
143 | p.Add("REFERENCEZONESON", ReferenceZonesOn);
144 | p.Add("SHOWTEMPLATEGRAPHICS", ShowTemplateGraphics);
145 | p.Add("DISPLAY_UNIT", (int)DisplayUnit, false);
146 | }
147 | }
148 | }
149 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 | ##
4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
5 |
6 | # User-specific files
7 | *.rsuser
8 | *.suo
9 | *.user
10 | *.userosscache
11 | *.sln.docstates
12 |
13 | # User-specific files (MonoDevelop/Xamarin Studio)
14 | *.userprefs
15 |
16 | # Mono auto generated files
17 | mono_crash.*
18 |
19 | # Build results
20 | [Dd]ebug/
21 | [Dd]ebugPublic/
22 | [Rr]elease/
23 | [Rr]eleases/
24 | x64/
25 | x86/
26 | [Aa][Rr][Mm]/
27 | [Aa][Rr][Mm]64/
28 | bld/
29 | [Bb]in/
30 | [Oo]bj/
31 | [Ll]og/
32 |
33 | # Visual Studio 2015/2017 cache/options directory
34 | .vs/
35 | # Uncomment if you have tasks that create the project's static files in wwwroot
36 | #wwwroot/
37 |
38 | # Visual Studio 2017 auto generated files
39 | Generated\ Files/
40 |
41 | # MSTest test Results
42 | [Tt]est[Rr]esult*/
43 | [Bb]uild[Ll]og.*
44 |
45 | # NUnit
46 | *.VisualState.xml
47 | TestResult.xml
48 | nunit-*.xml
49 |
50 | # Build Results of an ATL Project
51 | [Dd]ebugPS/
52 | [Rr]eleasePS/
53 | dlldata.c
54 |
55 | # Benchmark Results
56 | BenchmarkDotNet.Artifacts/
57 |
58 | # .NET Core
59 | project.lock.json
60 | project.fragment.lock.json
61 | artifacts/
62 |
63 | # StyleCop
64 | StyleCopReport.xml
65 |
66 | # Files built by Visual Studio
67 | *_i.c
68 | *_p.c
69 | *_h.h
70 | *.ilk
71 | *.meta
72 | *.obj
73 | *.iobj
74 | *.pch
75 | *.pdb
76 | *.ipdb
77 | *.pgc
78 | *.pgd
79 | *.rsp
80 | *.sbr
81 | *.tlb
82 | *.tli
83 | *.tlh
84 | *.tmp
85 | *.tmp_proj
86 | *_wpftmp.csproj
87 | *.log
88 | *.vspscc
89 | *.vssscc
90 | .builds
91 | *.pidb
92 | *.svclog
93 | *.scc
94 |
95 | # Chutzpah Test files
96 | _Chutzpah*
97 |
98 | # Visual C++ cache files
99 | ipch/
100 | *.aps
101 | *.ncb
102 | *.opendb
103 | *.opensdf
104 | *.sdf
105 | *.cachefile
106 | *.VC.db
107 | *.VC.VC.opendb
108 |
109 | # Visual Studio profiler
110 | *.psess
111 | *.vsp
112 | *.vspx
113 | *.sap
114 |
115 | # Visual Studio Trace Files
116 | *.e2e
117 |
118 | # TFS 2012 Local Workspace
119 | $tf/
120 |
121 | # Guidance Automation Toolkit
122 | *.gpState
123 |
124 | # ReSharper is a .NET coding add-in
125 | _ReSharper*/
126 | *.[Rr]e[Ss]harper
127 | *.DotSettings.user
128 |
129 | # JustCode is a .NET coding add-in
130 | .JustCode
131 |
132 | # TeamCity is a build add-in
133 | _TeamCity*
134 |
135 | # DotCover is a Code Coverage Tool
136 | *.dotCover
137 |
138 | # AxoCover is a Code Coverage Tool
139 | .axoCover/*
140 | !.axoCover/settings.json
141 |
142 | # Visual Studio code coverage results
143 | *.coverage
144 | *.coveragexml
145 |
146 | # NCrunch
147 | _NCrunch_*
148 | .*crunch*.local.xml
149 | nCrunchTemp_*
150 |
151 | # MightyMoose
152 | *.mm.*
153 | AutoTest.Net/
154 |
155 | # Web workbench (sass)
156 | .sass-cache/
157 |
158 | # Installshield output folder
159 | [Ee]xpress/
160 |
161 | # DocProject is a documentation generator add-in
162 | DocProject/buildhelp/
163 | DocProject/Help/*.HxT
164 | DocProject/Help/*.HxC
165 | DocProject/Help/*.hhc
166 | DocProject/Help/*.hhk
167 | DocProject/Help/*.hhp
168 | DocProject/Help/Html2
169 | DocProject/Help/html
170 |
171 | # Click-Once directory
172 | publish/
173 |
174 | # Publish Web Output
175 | *.[Pp]ublish.xml
176 | *.azurePubxml
177 | # Note: Comment the next line if you want to checkin your web deploy settings,
178 | # but database connection strings (with potential passwords) will be unencrypted
179 | *.pubxml
180 | *.publishproj
181 |
182 | # Microsoft Azure Web App publish settings. Comment the next line if you want to
183 | # checkin your Azure Web App publish settings, but sensitive information contained
184 | # in these scripts will be unencrypted
185 | PublishScripts/
186 |
187 | # NuGet Packages
188 | *.nupkg
189 | # NuGet Symbol Packages
190 | *.snupkg
191 | # The packages folder can be ignored because of Package Restore
192 | **/[Pp]ackages/*
193 | # except build/, which is used as an MSBuild target.
194 | !**/[Pp]ackages/build/
195 | # Uncomment if necessary however generally it will be regenerated when needed
196 | #!**/[Pp]ackages/repositories.config
197 | # NuGet v3's project.json files produces more ignorable files
198 | *.nuget.props
199 | *.nuget.targets
200 |
201 | # Microsoft Azure Build Output
202 | csx/
203 | *.build.csdef
204 |
205 | # Microsoft Azure Emulator
206 | ecf/
207 | rcf/
208 |
209 | # Windows Store app package directories and files
210 | AppPackages/
211 | BundleArtifacts/
212 | Package.StoreAssociation.xml
213 | _pkginfo.txt
214 | *.appx
215 | *.appxbundle
216 | *.appxupload
217 |
218 | # Visual Studio cache files
219 | # files ending in .cache can be ignored
220 | *.[Cc]ache
221 | # but keep track of directories ending in .cache
222 | !?*.[Cc]ache/
223 |
224 | # Others
225 | ClientBin/
226 | ~$*
227 | *~
228 | *.dbmdl
229 | *.dbproj.schemaview
230 | *.jfm
231 | *.pfx
232 | *.publishsettings
233 | orleans.codegen.cs
234 |
235 | # Including strong name files can present a security risk
236 | # (https://github.com/github/gitignore/pull/2483#issue-259490424)
237 | #*.snk
238 |
239 | # Since there are multiple workflows, uncomment next line to ignore bower_components
240 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
241 | #bower_components/
242 |
243 | # RIA/Silverlight projects
244 | Generated_Code/
245 |
246 | # Backup & report files from converting an old project file
247 | # to a newer Visual Studio version. Backup files are not needed,
248 | # because we have git ;-)
249 | _UpgradeReport_Files/
250 | Backup*/
251 | UpgradeLog*.XML
252 | UpgradeLog*.htm
253 | ServiceFabricBackup/
254 | *.rptproj.bak
255 |
256 | # SQL Server files
257 | *.mdf
258 | *.ldf
259 | *.ndf
260 |
261 | # Business Intelligence projects
262 | *.rdl.data
263 | *.bim.layout
264 | *.bim_*.settings
265 | *.rptproj.rsuser
266 | *- [Bb]ackup.rdl
267 | *- [Bb]ackup ([0-9]).rdl
268 | *- [Bb]ackup ([0-9][0-9]).rdl
269 |
270 | # Microsoft Fakes
271 | FakesAssemblies/
272 |
273 | # GhostDoc plugin setting file
274 | *.GhostDoc.xml
275 |
276 | # Node.js Tools for Visual Studio
277 | .ntvs_analysis.dat
278 | node_modules/
279 |
280 | # Visual Studio 6 build log
281 | *.plg
282 |
283 | # Visual Studio 6 workspace options file
284 | *.opt
285 |
286 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
287 | *.vbw
288 |
289 | # Visual Studio LightSwitch build output
290 | **/*.HTMLClient/GeneratedArtifacts
291 | **/*.DesktopClient/GeneratedArtifacts
292 | **/*.DesktopClient/ModelManifest.xml
293 | **/*.Server/GeneratedArtifacts
294 | **/*.Server/ModelManifest.xml
295 | _Pvt_Extensions
296 |
297 | # Paket dependency manager
298 | .paket/paket.exe
299 | paket-files/
300 |
301 | # FAKE - F# Make
302 | .fake/
303 |
304 | # CodeRush personal settings
305 | .cr/personal
306 |
307 | # Python Tools for Visual Studio (PTVS)
308 | __pycache__/
309 | *.pyc
310 |
311 | # Cake - Uncomment if you are using it
312 | # tools/**
313 | # !tools/packages.config
314 |
315 | # Tabs Studio
316 | *.tss
317 |
318 | # Telerik's JustMock configuration file
319 | *.jmconfig
320 |
321 | # BizTalk build output
322 | *.btp.cs
323 | *.btm.cs
324 | *.odx.cs
325 | *.xsd.cs
326 |
327 | # OpenCover UI analysis results
328 | OpenCover/
329 |
330 | # Azure Stream Analytics local run output
331 | ASALocalRun/
332 |
333 | # MSBuild Binary and Structured Log
334 | *.binlog
335 |
336 | # NVidia Nsight GPU debugger configuration file
337 | *.nvuser
338 |
339 | # MFractors (Xamarin productivity tool) working folder
340 | .mfractor/
341 |
342 | # Local History for Visual Studio
343 | .localhistory/
344 |
345 | # BeatPulse healthcheck temp database
346 | healthchecksdb
347 |
348 | # Backup folder for Package Reference Convert tool in Visual Studio 2017
349 | MigrationBackup/
350 |
--------------------------------------------------------------------------------
/AltiumSharp/SchLibWriter.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Globalization;
3 | using System.IO;
4 | using System.Linq;
5 | using System.Text;
6 | using OriginalCircuit.AltiumSharp.BasicTypes;
7 | using OriginalCircuit.AltiumSharp.Records;
8 | using OpenMcdf;
9 |
10 | namespace OriginalCircuit.AltiumSharp
11 | {
12 | ///
13 | /// Schematic library writer.
14 | ///
15 | public sealed class SchLibWriter : SchWriter
16 | {
17 | public SchLibWriter() : base()
18 | {
19 |
20 | }
21 |
22 | protected override void DoWrite(string fileName)
23 | {
24 | WriteFileHeader();
25 | WriteSectionKeys();
26 |
27 | foreach (var component in Data.Items)
28 | {
29 | WriteComponent(component);
30 | }
31 |
32 | var embeddedImages = GetEmbeddedImages(Data.Items);
33 | WriteStorageEmbeddedImages(embeddedImages);
34 | }
35 |
36 | private void WriteSectionKeys()
37 | {
38 | // only write section keys for components that need them
39 | var components = Data.Items.Where(c => GetSectionKeyFromComponentPattern(c.LibReference) != c.LibReference).ToList();
40 | if (components.Count == 0) return;
41 |
42 | var parameters = new ParameterCollection
43 | {
44 | { "KEYCOUNT", components.Count }
45 | };
46 |
47 | for (int i = 0; i < components.Count; ++i)
48 | {
49 | var component = components[i];
50 | var componentRefName = component.LibReference;
51 | var sectionKey = GetSectionKeyFromComponentPattern(componentRefName);
52 |
53 | parameters.Add($"LIBREF{i}", componentRefName);
54 | parameters.Add($"SECTIONKEY{i}", sectionKey);
55 | }
56 |
57 | Cf.RootStorage.GetOrAddStream("SectionKeys").Write(writer =>
58 | {
59 | WriteBlock(writer, w => WriteParameters(w, parameters));
60 | });
61 | }
62 |
63 | ///
64 | /// Writes the "FileHeader" section which contains the list of components that
65 | /// exist in the current library file.
66 | ///
67 | ///
68 | private void WriteFileHeader()
69 | {
70 | Cf.RootStorage.GetOrAddStream("FileHeader").Write(writer =>
71 | {
72 | // write header
73 | var parameters = Data.Header.ExportToParameters();
74 | WriteBlock(writer, w => WriteParameters(w, parameters));
75 |
76 | // write the binary list of component ref names
77 | writer.Write(Data.Items.Count);
78 | foreach (var component in Data.Items)
79 | {
80 | WriteStringBlock(writer, component.LibReference);
81 | }
82 | });
83 | }
84 |
85 | ///
86 | /// Writes a component to the adequate section key in the current file.
87 | ///
88 | /// Component to be serialized.
89 | private void WriteComponent(SchComponent component)
90 | {
91 | var resourceName = GetSectionKeyFromComponentPattern(component.LibReference);
92 | var componentStorage = Cf.RootStorage.GetOrAddStorage(resourceName);
93 |
94 | var pinsFrac = new Dictionary();
95 | var pinsWideText = new Dictionary();
96 | var pinsTextData = new Dictionary();
97 | var pinsSymbolLineWidth = new Dictionary();
98 |
99 | componentStorage.GetOrAddStream("Data").Write(writer =>
100 | {
101 | WriteComponentPrimitives(writer, component, pinsFrac, pinsWideText, pinsTextData, pinsSymbolLineWidth);
102 | });
103 |
104 | WritePinFrac(componentStorage, pinsFrac);
105 | WritePinTextData(componentStorage, pinsTextData);
106 | WriteComponentExtendedParameters(componentStorage, "PinWideText", pinsWideText);
107 | WriteComponentExtendedParameters(componentStorage, "PinSymbolLineWidth", pinsSymbolLineWidth);
108 | }
109 |
110 | private static void WriteComponentPrimitives(BinaryWriter writer, SchComponent component,
111 | Dictionary pinsFrac,
112 | Dictionary pinsWideText, Dictionary pinsTextData,
113 | Dictionary pinsSymbolLineWidth)
114 | {
115 | var index = 0;
116 | var pinIndex = 0;
117 | WritePrimitive(writer, component, true, 0, ref index, ref pinIndex,
118 | pinsFrac, pinsWideText, pinsTextData, pinsSymbolLineWidth);
119 | }
120 |
121 | ///
122 | /// Writes a pin text data for the component at .
123 | ///
124 | private static void WritePinFrac(CFStorage componentStorage, Dictionary data)
125 | {
126 | if (data.Count == 0) return;
127 |
128 | componentStorage.GetOrAddStream("PinFrac").Write(writer =>
129 | {
130 | var parameters = new ParameterCollection
131 | {
132 | { "HEADER", "PinFrac" },
133 | { "WEIGHT", data.Count }
134 | };
135 | WriteBlock(writer, w => WriteParameters(w, parameters));
136 |
137 | foreach (var kv in data)
138 | {
139 | WriteCompressedStorage(writer, kv.Key.ToString(CultureInfo.InvariantCulture), ws =>
140 | {
141 | ws.Write(kv.Value.x);
142 | ws.Write(kv.Value.y);
143 | ws.Write(kv.Value.length);
144 | });
145 | }
146 | });
147 | }
148 |
149 | ///
150 | /// Writes a pin text data for the component at .
151 | ///
152 | private static void WritePinTextData(CFStorage componentStorage, Dictionary data)
153 | {
154 | if (data.Count == 0) return;
155 |
156 | componentStorage.GetOrAddStream("PinTextData").Write(writer =>
157 | {
158 | var parameters = new ParameterCollection
159 | {
160 | { "HEADER", "PinTextData" },
161 | { "WEIGHT", data.Count }
162 | };
163 | WriteBlock(writer, w => WriteParameters(w, parameters));
164 |
165 | foreach (var kv in data)
166 | {
167 | WriteCompressedStorage(writer, kv.Key.ToString(CultureInfo.InvariantCulture), kv.Value);
168 | }
169 | });
170 | }
171 |
172 | ///
173 | /// Writes a component extended list of parameter at .
174 | ///
175 | /// Component storage.
176 | /// Name of the stream inside the component storage.
177 | /// Key, value set of parameters to store.
178 | private static void WriteComponentExtendedParameters(CFStorage componentStorage, string streamName,
179 | Dictionary data)
180 | {
181 | if (data.Count == 0) return;
182 |
183 | componentStorage.GetOrAddStream(streamName).Write(writer =>
184 | {
185 | var parameters = new ParameterCollection
186 | {
187 | { "HEADER", streamName },
188 | { "WEIGHT", data.Count }
189 | };
190 | WriteBlock(writer, w => WriteParameters(w, parameters));
191 |
192 | foreach (var kv in data)
193 | {
194 | WriteCompressedStorage(writer, kv.Key.ToString(CultureInfo.InvariantCulture), ws =>
195 | WriteBlock(ws, wb => WriteParameters(wb, kv.Value, true, Encoding.Unicode, false)));
196 | }
197 | });
198 | }
199 | }
200 | }
201 |
--------------------------------------------------------------------------------
/AltiumSharp/SchWriter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Drawing;
4 | using System.Drawing.Imaging;
5 | using System.IO;
6 | using System.Linq;
7 | using System.Text;
8 | using OriginalCircuit.AltiumSharp.BasicTypes;
9 | using OriginalCircuit.AltiumSharp.Records;
10 |
11 | namespace OriginalCircuit.AltiumSharp
12 | {
13 | public abstract class SchWriter : CompoundFileWriter
14 | where TData : SchData, new()
15 | {
16 | protected SchWriter() : base()
17 | {
18 |
19 | }
20 |
21 | protected IDictionary GetEmbeddedImages(IEnumerable dataItems)
22 | {
23 | return dataItems
24 | .SelectMany(item => item.GetPrimitivesOfType().Where(p => p.EmbedImage))
25 | .Select(p => (p.Filename, p.Image))
26 | .GroupBy(p => p.Filename).Select(g => g.First()) // only one image per file name
27 | .ToDictionary(kv => kv.Filename, kv => kv.Image);
28 | }
29 |
30 | ///
31 | /// Writes embedded images from the "Storage" section of the file.
32 | ///
33 | protected void WriteStorageEmbeddedImages(IDictionary embeddedImages)
34 | {
35 | byte[] ImageToBytes(Image image)
36 | {
37 | // we need to make a copy of the image because otherwise Save() fails with a generic GDI+ error
38 | // Source: https://social.microsoft.com/Forums/en-US/b15357f1-ad9d-4c80-9ec1-92c786cca4e6/bitmapsave-a-generic-error-occurred-in-gdi#c780991d-50c3-4bdc-8c90-a5474f4739a2
39 | using (var stream = new MemoryStream())
40 | using (var bitmap = new Bitmap(image))
41 | {
42 | bitmap.Save(stream, ImageFormat.Bmp);
43 | return stream.ToArray();
44 | }
45 | }
46 |
47 | Cf.RootStorage.GetOrAddStream("Storage").Write(writer =>
48 | {
49 | var parameters = new ParameterCollection
50 | {
51 | { "HEADER", "Icon storage" },
52 | { "WEIGHT", embeddedImages.Count }
53 | };
54 | WriteBlock(writer, w => WriteParameters(w, parameters));
55 |
56 | foreach (var ei in embeddedImages)
57 | {
58 | WriteCompressedStorage(writer, ei.Key, ImageToBytes(ei.Value));
59 | }
60 | });
61 | }
62 |
63 | protected static void WritePrimitive(BinaryWriter writer, SchPrimitive primitive, bool pinAsBinary,
64 | int ownerIndex, ref int index, ref int pinIndex,
65 | Dictionary pinsFrac,
66 | Dictionary pinsWideText, Dictionary pinsTextData,
67 | Dictionary pinsSymbolLineWidth)
68 | {
69 | if (primitive == null)
70 | throw new ArgumentNullException(nameof(primitive));
71 |
72 | if (pinsSymbolLineWidth == null)
73 | throw new ArgumentNullException(nameof(pinsSymbolLineWidth));
74 |
75 | primitive.OwnerIndex = ownerIndex;
76 |
77 | if (pinAsBinary && primitive is SchPin pin)
78 | {
79 | WritePinRecord(writer, pin, out var pinFrac, out var pinWideText, out var pinTextData, out var pinSymbolLineWidth);
80 |
81 | if (pinFrac.x != 0 || pinFrac.y != 0 || pinFrac.length != 0)
82 | {
83 | pinsFrac?.Add(pinIndex, pinFrac);
84 | }
85 | if (pinTextData?.Length > 0)
86 | {
87 | pinsTextData?.Add(pinIndex, pinTextData);
88 | }
89 | if (pinWideText?.Count > 0)
90 | {
91 | pinsWideText?.Add(pinIndex, pinWideText);
92 | }
93 | if (pinSymbolLineWidth?.Count > 0)
94 | {
95 | pinsSymbolLineWidth.Add(pinIndex, pinSymbolLineWidth);
96 | }
97 |
98 | pinIndex++;
99 | }
100 | else
101 | {
102 | WriteAsciiRecord(writer, primitive);
103 | }
104 |
105 | var currentIndex = index++;
106 |
107 | foreach (var child in primitive.GetAllPrimitives())
108 | {
109 | WritePrimitive(writer, child, pinAsBinary, currentIndex, ref index, ref pinIndex,
110 | pinsFrac, pinsWideText, pinsTextData, pinsSymbolLineWidth);
111 | }
112 | }
113 |
114 | ///
115 | /// Writes an ASCII parameter based Record entry.
116 | ///
117 | /// Binary writer.
118 | /// Primitive to be serialized as a record.
119 | protected static void WriteAsciiRecord(BinaryWriter writer, SchPrimitive primitive)
120 | {
121 | if (primitive == null)
122 | throw new ArgumentNullException(nameof(primitive));
123 | if (writer == null)
124 | throw new ArgumentNullException(nameof(writer));
125 |
126 | var parameters = primitive.ExportToParameters();
127 | WriteBlock(writer, w => WriteParameters(w, parameters), 0);
128 | }
129 |
130 | /// Checks if the string can be represented as ASCII
131 | private static bool IsAscii(string s) => s == null || Encoding.UTF8.GetByteCount(s) == s.Length;
132 |
133 | ///
134 | /// Writes a binary SchPin Record entry.
135 | ///
136 | /// Binary writer.
137 | /// Pin primitive to be serialized as a record.
138 | protected static void WritePinRecord(BinaryWriter writer, SchPin pin, out (int x, int y, int length) pinFrac,
139 | out ParameterCollection pinWideText, out byte[] pinTextData, out ParameterCollection pinSymbolLineWidth)
140 | {
141 | if (pin == null)
142 | throw new ArgumentNullException(nameof(pin));
143 | if (writer == null)
144 | throw new ArgumentNullException(nameof(writer));
145 |
146 | var pinLocationX = Utils.CoordToDxpFrac(pin.Location.X);
147 | var pinLocationY = Utils.CoordToDxpFrac(pin.Location.Y);
148 | var pinLength = Utils.CoordToDxpFrac(pin.PinLength);
149 |
150 | WriteBlock(writer, w =>
151 | {
152 | pin.SymbolLineWidth = LineWidth.Smallest;
153 |
154 | w.Write(pin.Record);
155 | w.Write((byte)0); // TODO: unknown
156 | w.Write((short)pin.OwnerPartId);
157 | w.Write((byte)pin.OwnerPartDisplayMode);
158 | w.Write((byte)pin.SymbolInnerEdge);
159 | w.Write((byte)pin.SymbolOuterEdge);
160 | w.Write((byte)pin.SymbolInside);
161 | w.Write((byte)pin.SymbolOutside);
162 | WritePascalShortString(w, pin.Description);
163 | w.Write((byte)0); // TODO: unknown
164 | w.Write((byte)pin.Electrical);
165 | w.Write((byte)pin.PinConglomerate);
166 | w.Write((short)pinLength.num);
167 | w.Write((short)pinLocationX.num);
168 | w.Write((short)pinLocationY.num);
169 | w.Write(ColorTranslator.ToWin32(pin.Color));
170 | WritePascalShortString(w, pin.Name);
171 | WritePascalShortString(w, pin.Designator);
172 | WritePascalShortString(w, pin.SwapIdGroup);
173 | var partAndSequence = string.Empty;
174 | if (!(pin.SwapIdPart == 0 && string.IsNullOrEmpty(pin.SwapIdSequence)))
175 | {
176 | partAndSequence = pin.SwapIdPart != 0
177 | ? $"{pin.SwapIdPart}|&|{pin.SwapIdSequence}"
178 | : $"|&|{pin.SwapIdSequence}";
179 | }
180 | WritePascalShortString(w, partAndSequence);
181 | WritePascalShortString(w, pin.DefaultValue);
182 | }, (byte)0x01); // flag needs to be 1
183 |
184 | pinFrac = (pinLocationX.frac, pinLocationY.frac, pinLength.frac);
185 |
186 | pinWideText = new ParameterCollection();
187 | if (!IsAscii(pin.Description)) pinWideText.Add("DESC", pin.Description);
188 | if (!IsAscii(pin.Name)) pinWideText.Add("NAME", pin.Name);
189 | if (!IsAscii(pin.Designator)) pinWideText.Add("DESIG", pin.Designator);
190 |
191 | pinTextData = Array.Empty();
192 |
193 | pinSymbolLineWidth = new ParameterCollection
194 | {
195 | { "SYMBOL_LINEWIDTH", pin.SymbolLineWidth }
196 | };
197 | }
198 | }
199 | }
200 |
--------------------------------------------------------------------------------
/AltiumSharp/Records/Sch/SchPin.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using OriginalCircuit.AltiumSharp.BasicTypes;
4 |
5 | namespace OriginalCircuit.AltiumSharp.Records
6 | {
7 | public enum PinElectricalType
8 | {
9 | Input = 0, InputOutput, Output, OpenCollector, Passive, HiZ, OpenEmitter, Power
10 | }
11 |
12 | public enum PinSymbol
13 | {
14 | None = 0,
15 | Dot = 1,
16 | RightLeftSignalFlow = 2,
17 | Clock = 3,
18 | ActiveLowInput = 4,
19 | AnalogSignalIn = 5,
20 | NotLogicConnection = 6,
21 | PostponedOutput = 8,
22 | OpenCollector = 9,
23 | HiZ = 10,
24 | HighCurrent = 11,
25 | Pulse = 12,
26 | Schmitt = 13,
27 | ActiveLowOutput = 17,
28 | OpenCollectorPullUp = 22,
29 | OpenEmitter = 23,
30 | OpenEmitterPullUp = 24,
31 | DigitalSignalIn = 25,
32 | ShiftLeft = 30,
33 | OpenOutput = 32,
34 | LeftRightSignalFlow = 33,
35 | BidirectionalSignalFlow = 34,
36 | }
37 |
38 | [Flags]
39 | public enum PinConglomerateFlags
40 | {
41 | None = 0x00,
42 | Rotated = 0x01,
43 | Flipped = 0x02,
44 | Hide = 0x04,
45 | DisplayNameVisible = 0x08,
46 | DesignatorVisible = 0x10,
47 | Unknown = 0x20,
48 | GraphicallyLocked = 0x40,
49 | }
50 |
51 | public class SchPin : SchGraphicalObject
52 | {
53 | public override int Record => 2;
54 | public PinSymbol SymbolInnerEdge { get; set; }
55 | public PinSymbol SymbolOuterEdge { get; set; }
56 | public PinSymbol SymbolInside { get; set; }
57 | public PinSymbol SymbolOutside { get; set; }
58 | public LineWidth SymbolLineWidth { get; set; }
59 | public string Description { get; set; }
60 | public int FormalType { get; set; }
61 | public PinElectricalType Electrical { get; set; }
62 | public PinConglomerateFlags PinConglomerate { get; set; }
63 | public Coord PinLength { get; set; }
64 | public string Name { get; set; }
65 | public string Designator { get; set; }
66 | public string SwapIdGroup { get; set; }
67 | public int SwapIdPart { get; set; }
68 | public string SwapIdSequence { get; set; }
69 | public string HiddenNetName { get; set; }
70 | public string DefaultValue { get; set; }
71 | public double PinPropagationDelay { get; set; }
72 | public string UniqueId { get; set; }
73 |
74 | public override bool IsVisible => base.IsVisible && !PinConglomerate.HasFlag(PinConglomerateFlags.Hide);
75 |
76 | public bool IsNameVisible
77 | {
78 | get => PinConglomerate.HasFlag(PinConglomerateFlags.DisplayNameVisible);
79 | set => PinConglomerate = PinConglomerate.WithFlag(PinConglomerateFlags.DisplayNameVisible, value);
80 | }
81 |
82 | public bool IsDesignatorVisible
83 | {
84 | get => PinConglomerate.HasFlag(PinConglomerateFlags.DesignatorVisible);
85 | set => PinConglomerate = PinConglomerate.WithFlag(PinConglomerateFlags.DesignatorVisible, value);
86 | }
87 |
88 | public TextOrientations Orientation
89 | {
90 | get => TextOrientations.None
91 | .WithFlag(TextOrientations.Rotated, PinConglomerate.HasFlag(PinConglomerateFlags.Rotated))
92 | .WithFlag(TextOrientations.Flipped, PinConglomerate.HasFlag(PinConglomerateFlags.Flipped));
93 | set => PinConglomerate = PinConglomerate
94 | .WithFlag(PinConglomerateFlags.Rotated, value.HasFlag(TextOrientations.Rotated))
95 | .WithFlag(PinConglomerateFlags.Flipped, value.HasFlag(TextOrientations.Flipped));
96 | }
97 |
98 | public SchPin() : base()
99 | {
100 | Electrical = PinElectricalType.Passive;
101 | PinConglomerate =
102 | PinConglomerateFlags.DisplayNameVisible |
103 | PinConglomerateFlags.DesignatorVisible |
104 | PinConglomerateFlags.Unknown;
105 | PinLength = Utils.DxpFracToCoord(30, 0);
106 | Designator = null;
107 | Name = null;
108 | }
109 |
110 | public CoordPoint GetCorner()
111 | {
112 | if (PinConglomerate.HasFlag(PinConglomerateFlags.Rotated))
113 | {
114 | if (PinConglomerate.HasFlag(PinConglomerateFlags.Flipped))
115 | {
116 | return new CoordPoint(Location.X, Location.Y - PinLength);
117 | }
118 | else
119 | {
120 | return new CoordPoint(Location.X, Location.Y + PinLength);
121 | }
122 | }
123 | else
124 | {
125 | if (PinConglomerate.HasFlag(PinConglomerateFlags.Flipped))
126 | {
127 | return new CoordPoint(Location.X - PinLength, Location.Y);
128 | }
129 | else
130 | {
131 | return new CoordPoint(Location.X + PinLength, Location.Y);
132 | }
133 | }
134 | }
135 |
136 | public override CoordRect CalculateBounds() =>
137 | new CoordRect(Location, GetCorner());
138 |
139 | public override void ImportFromParameters(ParameterCollection p)
140 | {
141 | if (p == null) throw new ArgumentNullException(nameof(p));
142 |
143 | base.ImportFromParameters(p);
144 | SymbolInnerEdge = (PinSymbol)p["SYMBOL_INNEREDGE"].AsIntOrDefault();
145 | SymbolOuterEdge = (PinSymbol)p["SYMBOL_OUTEREDGE"].AsIntOrDefault();
146 | SymbolInside = (PinSymbol)p["SYMBOL_INSIDE"].AsIntOrDefault();
147 | SymbolOutside = (PinSymbol)p["SYMBOL_OUTSIDE"].AsIntOrDefault();
148 | SymbolLineWidth = p["SYMBOL_LINEWIDTH"].AsEnumOrDefault();
149 | Description = p["DESCRIPTION"].AsStringOrDefault();
150 | FormalType = p["FORMALTYPE"].AsIntOrDefault();
151 | Electrical = p["ELECTRICAL"].AsEnumOrDefault();
152 | PinConglomerate = (PinConglomerateFlags)p["PINCONGLOMERATE"].AsIntOrDefault();
153 | PinLength = Utils.DxpFracToCoord(p["PINLENGTH"].AsIntOrDefault(), p["PINLENGTH_FRAC"].AsIntOrDefault());
154 | Name = p["NAME"].AsStringOrDefault();
155 | Designator = p["DESIGNATOR"].AsStringOrDefault();
156 | SwapIdPart = p["SWAPIDPART"].AsIntOrDefault();
157 | PinPropagationDelay = p["PINPROPAGATIONDELAY"].AsDoubleOrDefault();
158 | UniqueId = p["UNIQUEID"].AsStringOrDefault();
159 | }
160 |
161 | public override void ExportToParameters(ParameterCollection p)
162 | {
163 | if (p == null) throw new ArgumentNullException(nameof(p));
164 |
165 | base.ExportToParameters(p);
166 | p.SetBookmark();
167 | p.Add("SYMBOL_INNEREDGE", SymbolInnerEdge);
168 | p.Add("SYMBOL_OUTEREDGE", SymbolOuterEdge);
169 | p.Add("SYMBOL_INSIDE", (int)SymbolInside);
170 | p.Add("SYMBOL_OUTSIDE", (int)SymbolOutside);
171 | p.Add("SYMBOL_LINEWIDTH", SymbolLineWidth);
172 | p.Add("DESCRIPTION", Description);
173 | p.Add("FORMALTYPE", FormalType);
174 | p.Add("ELECTRICAL", Electrical);
175 | p.Add("PINCONGLOMERATE", (int)PinConglomerate);
176 | {
177 | var (n, f) = Utils.CoordToDxpFrac(PinLength);
178 | p.Add("PINLENGTH", n);
179 | p.Add("PINLENGTH_FRAC", f);
180 | }
181 | p.MoveKeys("LOCATION.X");
182 | p.Add("NAME", Name);
183 | p.Add("DESIGNATOR", Designator);
184 | p.Add("SWAPIDPART", SwapIdPart);
185 | p.Add("PINPROPAGATIONDELAY", PinPropagationDelay);
186 | }
187 |
188 | protected override bool DoAdd(SchPrimitive primitive)
189 | {
190 | if (primitive == null) return false;
191 |
192 | if (primitive is SchParameter parameter)
193 | {
194 | if (parameter.Name == "PinUniqueId")
195 | {
196 | UniqueId = parameter.Text;
197 | return false;
198 | }
199 | else if (parameter.Name == "HiddenNetName")
200 | {
201 | HiddenNetName = parameter.Text;
202 | return false;
203 | }
204 | }
205 | return true;
206 | }
207 |
208 | protected override IEnumerable DoGetParameters()
209 | {
210 | if (!string.IsNullOrEmpty(HiddenNetName))
211 | {
212 | yield return new SchParameter { Name = "HiddenNetName", Text = HiddenNetName };
213 | }
214 |
215 | if (!string.IsNullOrEmpty(UniqueId))
216 | {
217 | yield return new SchParameter {Name = "PinUniqueId", Text = UniqueId, Location = Location};
218 | }
219 | }
220 | }
221 | }
222 |
--------------------------------------------------------------------------------
/LibraryViewer/Main.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 | True
122 |
123 |
124 | True
125 |
126 |
127 | True
128 |
129 |
130 | True
131 |
132 |
133 | True
134 |
135 |
136 | True
137 |
138 |
139 | True
140 |
141 |
142 | True
143 |
144 |
145 | True
146 |
147 |
148 | True
149 |
150 |
151 | True
152 |
153 |
154 | True
155 |
156 |
157 | 17, 17
158 |
159 |
160 | 133, 17
161 |
162 |
163 | 248, 17
164 |
165 |
166 | 381, 17
167 |
168 |
169 | 510, 17
170 |
171 |
--------------------------------------------------------------------------------
/AltiumSharp/BasicTypes/Layer.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Diagnostics;
4 | using System.Drawing;
5 |
6 | namespace OriginalCircuit.AltiumSharp.BasicTypes
7 | {
8 | ///
9 | /// Layer data type used for ease of handling PCB layer references.
10 | ///
11 | [DebuggerDisplay("{Name,nq}")]
12 | public readonly struct Layer : IEquatable, IComparable
13 | {
14 | public static readonly Layer NoLayer = 0;
15 | public static readonly Layer TopLayer = 1;
16 | public static readonly Layer MidLayer1 = 2;
17 | public static readonly Layer MidLayer2 = 3;
18 | public static readonly Layer MidLayer3 = 4;
19 | public static readonly Layer MidLayer4 = 5;
20 | public static readonly Layer MidLayer5 = 6;
21 | public static readonly Layer MidLayer6 = 7;
22 | public static readonly Layer MidLayer7 = 8;
23 | public static readonly Layer MidLayer8 = 9;
24 | public static readonly Layer MidLayer9 = 10;
25 | public static readonly Layer MidLayer10 = 11;
26 | public static readonly Layer MidLayer11 = 12;
27 | public static readonly Layer MidLayer12 = 13;
28 | public static readonly Layer MidLayer13 = 14;
29 | public static readonly Layer MidLayer14 = 15;
30 | public static readonly Layer MidLayer15 = 16;
31 | public static readonly Layer MidLayer16 = 17;
32 | public static readonly Layer MidLayer17 = 18;
33 | public static readonly Layer MidLayer18 = 19;
34 | public static readonly Layer MidLayer19 = 20;
35 | public static readonly Layer MidLayer20 = 21;
36 | public static readonly Layer MidLayer21 = 22;
37 | public static readonly Layer MidLayer22 = 23;
38 | public static readonly Layer MidLayer23 = 24;
39 | public static readonly Layer MidLayer24 = 25;
40 | public static readonly Layer MidLayer25 = 26;
41 | public static readonly Layer MidLayer26 = 27;
42 | public static readonly Layer MidLayer27 = 28;
43 | public static readonly Layer MidLayer28 = 29;
44 | public static readonly Layer MidLayer29 = 30;
45 | public static readonly Layer MidLayer30 = 31;
46 | public static readonly Layer BottomLayer = 32;
47 | public static readonly Layer TopOverlay = 33;
48 | public static readonly Layer BottomOverlay = 34;
49 | public static readonly Layer TopPaste = 35;
50 | public static readonly Layer BottomPaste = 36;
51 | public static readonly Layer TopSolder = 37;
52 | public static readonly Layer BottomSolder = 38;
53 | public static readonly Layer InternalPlane1 = 39;
54 | public static readonly Layer InternalPlane2 = 40;
55 | public static readonly Layer InternalPlane3 = 41;
56 | public static readonly Layer InternalPlane4 = 42;
57 | public static readonly Layer InternalPlane5 = 43;
58 | public static readonly Layer InternalPlane6 = 44;
59 | public static readonly Layer InternalPlane7 = 45;
60 | public static readonly Layer InternalPlane8 = 46;
61 | public static readonly Layer InternalPlane9 = 47;
62 | public static readonly Layer InternalPlane10 = 48;
63 | public static readonly Layer InternalPlane11 = 49;
64 | public static readonly Layer InternalPlane12 = 50;
65 | public static readonly Layer InternalPlane13 = 51;
66 | public static readonly Layer InternalPlane14 = 52;
67 | public static readonly Layer InternalPlane15 = 53;
68 | public static readonly Layer InternalPlane16 = 54;
69 | public static readonly Layer DrillGuide = 55;
70 | public static readonly Layer KeepOutLayer = 56;
71 | public static readonly Layer Mechanical1 = 57;
72 | public static readonly Layer Mechanical2 = 58;
73 | public static readonly Layer Mechanical3 = 59;
74 | public static readonly Layer Mechanical4 = 60;
75 | public static readonly Layer Mechanical5 = 61;
76 | public static readonly Layer Mechanical6 = 62;
77 | public static readonly Layer Mechanical7 = 63;
78 | public static readonly Layer Mechanical8 = 64;
79 | public static readonly Layer Mechanical9 = 65;
80 | public static readonly Layer Mechanical10 = 66;
81 | public static readonly Layer Mechanical11 = 67;
82 | public static readonly Layer Mechanical12 = 68;
83 | public static readonly Layer Mechanical13 = 69;
84 | public static readonly Layer Mechanical14 = 70;
85 | public static readonly Layer Mechanical15 = 71;
86 | public static readonly Layer Mechanical16 = 72;
87 | public static readonly Layer DrillDrawing = 73;
88 | public static readonly Layer MultiLayer = 74;
89 | public static readonly Layer ConnectLayer = 75;
90 | public static readonly Layer BackGroundLayer = 76;
91 | public static readonly Layer DRCErrorLayer = 77;
92 | public static readonly Layer HighlightLayer = 78;
93 | public static readonly Layer GridColor1 = 79;
94 | public static readonly Layer GridColor10 = 80;
95 | public static readonly Layer PadHoleLayer = 81;
96 | public static readonly Layer ViaHoleLayer = 82;
97 |
98 | public static readonly Layer TopPadMaster = 83;
99 | public static readonly Layer BottomPadMaster = 84;
100 | public static readonly Layer DRCDetailLayer = 85;
101 | public static readonly Layer Unknown = byte.MaxValue;
102 |
103 | public static IEnumerable Names => LayerMetadata.Names;
104 | public static IEnumerable Values => LayerMetadata.Values;
105 |
106 | private readonly byte _value;
107 | public Layer(byte value) => _value = value;
108 | public byte ToByte() => _value;
109 |
110 | internal LayerMetadata Metadata => LayerMetadata.Get(_value);
111 |
112 | ///
113 | /// Gets the internal name of a PCB layer.
114 | ///
115 | public string Name => Metadata?.InternalName ?? nameof(Unknown);
116 |
117 | ///
118 | /// Gets the long name of a PCB layer.
119 | ///
120 | public string LongName => Metadata?.LongName ?? nameof(Unknown);
121 |
122 | ///
123 | /// Gets the medium name of a PCB layer.
124 | ///
125 | public string MediumName => Metadata?.MediumName ?? nameof(Unknown);
126 |
127 | ///
128 | /// Gets the short name of a PCB layer.
129 | ///
130 | public string ShortName => Metadata?.ShortName ?? nameof(Unknown);
131 |
132 | ///
133 | /// Gets the color to be used for this PCB layer.
134 | ///
135 | public Color Color => Metadata?.Color ?? Color.Empty;
136 |
137 | ///
138 | /// Gets the drawing priority for this PCB layer.
139 | ///
140 | /// The lower this number, the higher the priority.
141 | ///
142 | ///
143 | public int DrawPriority => Metadata?.DrawPriority ?? 0;
144 |
145 | ///
146 | /// Creates a layer reference from an internal layer name.
147 | ///
148 | ///
149 | ///
150 | public static Layer FromString(string layerName) => LayerMetadata.Get(layerName)?.Id ?? Unknown;
151 |
152 | public override string ToString() => Name;
153 |
154 | ///
155 | /// Get a layer color from it's internal layer name.
156 | ///
157 | /// Internal layer name.
158 | /// Color attributed to the given layer.
159 | public static Color GetLayerColor(string layerName) => LayerMetadata.Get(layerName)?.Color ?? Color.Empty;
160 |
161 | ///
162 | /// Creates a layer reference from a byte value with the layer identifier.
163 | ///
164 | ///
165 | ///
166 | public static Layer FromByte(byte value) => new Layer(value);
167 |
168 | ///
169 | /// Implicit conversion operator so we can use bytes and layers transparently.
170 | ///
171 | static public implicit operator Layer(byte value) => new Layer(value);
172 |
173 | ///
174 | /// Implicit conversion operator so we can use bytes and layers transparently.
175 | ///
176 | static public implicit operator byte(Layer coord) => coord._value;
177 |
178 | #region 'boilerplate'
179 | public override bool Equals(object obj) => obj is Layer other && Equals(other);
180 | public bool Equals(Layer other) => _value == other._value;
181 | public override int GetHashCode() => _value.GetHashCode();
182 | public int CompareTo(Layer other) => _value < other._value ? -1 : _value > other._value ? 1 : 0;
183 | public static bool operator ==(Layer left, Layer right) => left.Equals(right);
184 | public static bool operator !=(Layer left, Layer right) => !(left.Equals(right));
185 | public static bool operator <(Layer left, Layer right) => left.CompareTo(right) < 0;
186 | public static bool operator <=(Layer left, Layer right) => left.CompareTo(right) <= 0;
187 | public static bool operator >(Layer left, Layer right) => left.CompareTo(right) > 0;
188 | public static bool operator >=(Layer left, Layer right) => left.CompareTo(right) >= 0;
189 | #endregion
190 | }
191 | }
192 |
--------------------------------------------------------------------------------