altium-toolkit 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. package/AGENTS.md +67 -0
  2. package/COMMERCIAL-LICENSE.md +20 -0
  3. package/CONTRIBUTING.md +19 -0
  4. package/LICENSE +22 -0
  5. package/LICENSES/CC-BY-SA-4.0.txt +170 -0
  6. package/LICENSES/GPL-3.0-or-later.txt +232 -0
  7. package/NOTICE.md +32 -0
  8. package/README.md +116 -0
  9. package/docs/api.md +73 -0
  10. package/docs/model-format.md +36 -0
  11. package/docs/testing.md +25 -0
  12. package/examples/README.md +47 -0
  13. package/examples/arduino-uno/PcbThreeSceneRenderer.mjs +635 -0
  14. package/examples/arduino-uno/SvgViewportController.mjs +306 -0
  15. package/examples/arduino-uno/example.mjs +480 -0
  16. package/examples/arduino-uno/index.html +163 -0
  17. package/examples/arduino-uno/styles.css +552 -0
  18. package/examples/server.mjs +212 -0
  19. package/package.json +53 -0
  20. package/spec/library-scope.md +32 -0
  21. package/src/core/BinaryReader.mjs +127 -0
  22. package/src/core/altium/AltiumLayoutParser.mjs +485 -0
  23. package/src/core/altium/AltiumParser.mjs +1007 -0
  24. package/src/core/altium/AsciiRecordParser.mjs +151 -0
  25. package/src/core/altium/ParserUtils.mjs +173 -0
  26. package/src/core/altium/PcbBinaryPrimitiveParser.mjs +424 -0
  27. package/src/core/altium/PcbEmbeddedModelExtractor.mjs +505 -0
  28. package/src/core/altium/PcbModelParser.mjs +336 -0
  29. package/src/core/altium/PcbOutlineRasterizer.mjs +852 -0
  30. package/src/core/altium/PcbOutlineRecovery.mjs +957 -0
  31. package/src/core/altium/PcbStreamExtractor.mjs +210 -0
  32. package/src/core/altium/PrintableTextDecoder.mjs +156 -0
  33. package/src/core/altium/SchematicAnnotationParser.mjs +220 -0
  34. package/src/core/altium/SchematicBusEntryParser.mjs +48 -0
  35. package/src/core/altium/SchematicDirectiveParser.mjs +47 -0
  36. package/src/core/altium/SchematicImageParser.mjs +173 -0
  37. package/src/core/altium/SchematicJunctionParser.mjs +43 -0
  38. package/src/core/altium/SchematicMultipartOwnerMatcher.mjs +564 -0
  39. package/src/core/altium/SchematicNetlistBuilder.mjs +351 -0
  40. package/src/core/altium/SchematicPinParser.mjs +767 -0
  41. package/src/core/altium/SchematicPrimitiveParser.mjs +716 -0
  42. package/src/core/altium/SchematicSheetParser.mjs +241 -0
  43. package/src/core/altium/SchematicSheetStyleResolver.mjs +46 -0
  44. package/src/core/altium/SchematicStandaloneCalloutNormalizer.mjs +592 -0
  45. package/src/core/altium/SchematicTextParser.mjs +708 -0
  46. package/src/core/altium/SchematicTextPostProcessor.mjs +801 -0
  47. package/src/core/ole/OleCompoundDocument.mjs +439 -0
  48. package/src/core/ole/OleConstants.mjs +64 -0
  49. package/src/core/ole/OleDirectoryEntry.mjs +95 -0
  50. package/src/index.mjs +7 -0
  51. package/src/parser.mjs +21 -0
  52. package/src/renderers.mjs +15 -0
  53. package/src/scene3d.mjs +9 -0
  54. package/src/styles/altium-renderers.css +358 -0
  55. package/src/ui/BomTableRenderer.mjs +46 -0
  56. package/src/ui/PcbArcUtils.mjs +189 -0
  57. package/src/ui/PcbEdgeFacingGlyphNormalizer.mjs +808 -0
  58. package/src/ui/PcbFootprintPrimitiveSelector.mjs +128 -0
  59. package/src/ui/PcbScene3dBuilder.mjs +742 -0
  60. package/src/ui/PcbScene3dModelRegistry.mjs +309 -0
  61. package/src/ui/PcbScene3dPackages.mjs +137 -0
  62. package/src/ui/PcbScene3dScenePreparator.mjs +36 -0
  63. package/src/ui/PcbScene3dSummaryRenderer.mjs +65 -0
  64. package/src/ui/PcbSvgRenderer.mjs +906 -0
  65. package/src/ui/SchematicColorResolver.mjs +132 -0
  66. package/src/ui/SchematicContentLayout.mjs +661 -0
  67. package/src/ui/SchematicDirectiveRenderer.mjs +184 -0
  68. package/src/ui/SchematicImageRenderer.mjs +135 -0
  69. package/src/ui/SchematicJunctionRenderer.mjs +381 -0
  70. package/src/ui/SchematicNoteRenderer.mjs +427 -0
  71. package/src/ui/SchematicOwnerPinLabelLayout.mjs +173 -0
  72. package/src/ui/SchematicPinSvgRenderer.mjs +495 -0
  73. package/src/ui/SchematicPortRenderer.mjs +558 -0
  74. package/src/ui/SchematicPowerPortRenderer.mjs +574 -0
  75. package/src/ui/SchematicRegionRenderer.mjs +94 -0
  76. package/src/ui/SchematicShapeRenderer.mjs +398 -0
  77. package/src/ui/SchematicSheetChromeRenderer.mjs +1025 -0
  78. package/src/ui/SchematicSheetSymbolRenderer.mjs +228 -0
  79. package/src/ui/SchematicSvgRenderer.mjs +756 -0
  80. package/src/ui/SchematicSvgUtils.mjs +182 -0
  81. package/src/ui/SchematicTypography.mjs +204 -0
  82. package/src/workers/altium-parser.worker.mjs +29 -0
@@ -0,0 +1,128 @@
1
+ // SPDX-FileCopyrightText: 2026 André Fiedler
2
+ //
3
+ // SPDX-License-Identifier: GPL-3.0-or-later
4
+
5
+ /**
6
+ * Selects documentation-layer primitives that should render as package
7
+ * outlines or silkscreen on one board side.
8
+ */
9
+ export class PcbFootprintPrimitiveSelector {
10
+ /**
11
+ * Selects one prioritized primitive family for the requested board side.
12
+ * @param {{ layerId: number, name: string }[]} primitiveLayers
13
+ * @param {{ x1: number, y1: number, x2: number, y2: number, layerCode?: number, layerId?: number }[]} fills
14
+ * @param {{ x1: number, y1: number, x2: number, y2: number, width: number, layerCode?: number, layerId?: number }[]} tracks
15
+ * @param {{ x: number, y: number, radius: number, startAngle: number, endAngle: number, width: number, layerCode?: number, layerId?: number }[]} arcs
16
+ * @param {'top' | 'bottom'} [side]
17
+ * @returns {{ fills: { x1: number, y1: number, x2: number, y2: number, layerCode?: number, layerId?: number }[], tracks: { x1: number, y1: number, x2: number, y2: number, width: number, layerCode?: number, layerId?: number }[], arcs: { x: number, y: number, radius: number, startAngle: number, endAngle: number, width: number, layerCode?: number, layerId?: number }[] }}
18
+ */
19
+ static select(primitiveLayers, fills, tracks, arcs, side = 'top') {
20
+ const prioritizedLayerMatchers =
21
+ PcbFootprintPrimitiveSelector.#resolveLayerMatchers(side)
22
+
23
+ for (const matchesLayerName of prioritizedLayerMatchers) {
24
+ const layerIds = new Set(
25
+ (primitiveLayers || [])
26
+ .filter((layer) => matchesLayerName(layer.name))
27
+ .map((layer) => Number(layer.layerId))
28
+ .filter((layerId) => Number.isInteger(layerId))
29
+ )
30
+
31
+ if (!layerIds.size) {
32
+ continue
33
+ }
34
+
35
+ const layerFills = (fills || []).filter((fill) =>
36
+ layerIds.has(fill.layerId)
37
+ )
38
+ const layerTracks = (tracks || []).filter((track) =>
39
+ layerIds.has(track.layerId)
40
+ )
41
+ const layerArcs = (arcs || []).filter((arc) =>
42
+ layerIds.has(arc.layerId)
43
+ )
44
+
45
+ if (layerFills.length || layerTracks.length || layerArcs.length) {
46
+ return {
47
+ fills: layerFills,
48
+ tracks: layerTracks,
49
+ arcs: layerArcs
50
+ }
51
+ }
52
+ }
53
+
54
+ return {
55
+ fills: [],
56
+ tracks: [],
57
+ arcs: []
58
+ }
59
+ }
60
+
61
+ /**
62
+ * Resolves the prioritized layer-name matchers for one board side.
63
+ * @param {'top' | 'bottom'} side
64
+ * @returns {((layerName: string) => boolean)[]}
65
+ */
66
+ static #resolveLayerMatchers(side) {
67
+ if (side === 'bottom') {
68
+ return [
69
+ (layerName) =>
70
+ PcbFootprintPrimitiveSelector.#includesLayerName(
71
+ layerName,
72
+ 'BOTTOM OVERLAY'
73
+ ),
74
+ (layerName) =>
75
+ PcbFootprintPrimitiveSelector.#includesLayerName(
76
+ layerName,
77
+ 'BOTTOM ASSEMBLY'
78
+ ),
79
+ (layerName) =>
80
+ PcbFootprintPrimitiveSelector.#includesLayerName(
81
+ layerName,
82
+ 'PLACEMENT OUTLINE'
83
+ ),
84
+ (layerName) =>
85
+ PcbFootprintPrimitiveSelector.#includesLayerName(
86
+ layerName,
87
+ 'BOTTOM MECHANIC'
88
+ )
89
+ ]
90
+ }
91
+
92
+ return [
93
+ (layerName) =>
94
+ PcbFootprintPrimitiveSelector.#includesLayerName(
95
+ layerName,
96
+ 'TOP OVERLAY'
97
+ ),
98
+ (layerName) =>
99
+ PcbFootprintPrimitiveSelector.#includesLayerName(
100
+ layerName,
101
+ 'TOP ASSEMBLY'
102
+ ),
103
+ (layerName) =>
104
+ PcbFootprintPrimitiveSelector.#includesLayerName(
105
+ layerName,
106
+ 'PLACEMENT OUTLINE'
107
+ ),
108
+ (layerName) =>
109
+ PcbFootprintPrimitiveSelector.#includesLayerName(
110
+ layerName,
111
+ 'TOP MECHANIC'
112
+ )
113
+ ]
114
+ }
115
+
116
+ /**
117
+ * Returns true when one primitive layer name contains the target label.
118
+ * @param {string} layerName
119
+ * @param {string} needle
120
+ * @returns {boolean}
121
+ */
122
+ static #includesLayerName(layerName, needle) {
123
+ return String(layerName || '')
124
+ .trim()
125
+ .toUpperCase()
126
+ .includes(needle)
127
+ }
128
+ }