altium-toolkit 1.1.2 → 1.1.22
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.
- package/docs/api.md +37 -0
- package/docs/model-format.md +18 -0
- package/docs/schemas/altium_toolkit/normalized_model_a1.schema.json +2 -2
- package/docs/testing.md +5 -0
- package/package.json +1 -1
- package/spec/library-scope.md +5 -0
- package/src/core/altium/AltiumLayoutParser.mjs +275 -13
- package/src/core/altium/AltiumLibraryBatchExporter.mjs +206 -0
- package/src/core/altium/AltiumLibraryRecordBuilder.mjs +293 -0
- package/src/core/altium/AltiumParser.mjs +245 -10
- package/src/core/altium/AltiumPcbLibExporter.mjs +101 -0
- package/src/core/altium/AltiumSchLibExporter.mjs +57 -0
- package/src/core/altium/AsciiRecordParser.mjs +43 -11
- package/src/core/altium/PcbComponentKindPolicy.mjs +9 -9
- package/src/core/altium/PcbEmbeddedFontExtractor.mjs +186 -43
- package/src/core/altium/PcbEmbeddedModelExtractor.mjs +22 -3
- package/src/core/altium/PcbOutlineRecovery.mjs +94 -0
- package/src/core/altium/PrintableTextDecoder.mjs +133 -13
- package/src/core/altium/SchematicComponentOwnerTextResolver.mjs +13 -0
- package/src/core/altium/SchematicComponentTextResolver.mjs +40 -1
- package/src/core/altium/SchematicDirectiveParser.mjs +5 -17
- package/src/core/altium/SchematicImageParser.mjs +291 -6
- package/src/core/altium/SchematicMultipartDesignatorNormalizer.mjs +164 -0
- package/src/core/altium/SchematicMultipartOwnerMatcher.mjs +2 -0
- package/src/core/altium/SchematicNoErcSymbolResolver.mjs +36 -0
- package/src/core/altium/SchematicPinParser.mjs +262 -24
- package/src/core/altium/SchematicPrimitiveParser.mjs +116 -8
- package/src/core/altium/SchematicSheetStyleResolver.mjs +38 -0
- package/src/core/altium/SchematicStreamExtractor.mjs +62 -15
- package/src/core/altium/SchematicTextParser.mjs +125 -11
- package/src/core/altium/SchematicTextPostProcessor.mjs +146 -102
- package/src/core/altium/SourceBundleExporter.mjs +156 -0
- package/src/core/altium/SourceComponentBundleNormalizer.mjs +295 -0
- package/src/core/altium/SourceComponentClient.mjs +239 -0
- package/src/core/ole/OleCompoundDocumentWriter.mjs +449 -0
- package/src/parser.mjs +8 -0
- package/src/styles/altium-renderers.css +6 -6
- package/src/ui/PcbArcUtils.mjs +19 -2
- package/src/ui/PcbScene3dBuilder.mjs +202 -20
- package/src/ui/PcbScene3dModelRegistry.mjs +28 -18
- package/src/ui/PcbScene3dPlacementSideResolver.mjs +48 -6
- package/src/ui/SchematicColorResolver.mjs +263 -0
- package/src/ui/SchematicContentLayout.mjs +58 -1
- package/src/ui/SchematicDirectiveRenderer.mjs +133 -22
- package/src/ui/SchematicImageRenderer.mjs +125 -10
- package/src/ui/SchematicJunctionRenderer.mjs +1 -1
- package/src/ui/SchematicLineColorResolver.mjs +88 -0
- package/src/ui/SchematicNativeFooterPartitioner.mjs +275 -0
- package/src/ui/SchematicNoteRenderer.mjs +87 -7
- package/src/ui/SchematicOwnerPinLabelLayout.mjs +560 -10
- package/src/ui/SchematicOwnerPinMarkerLineThemer.mjs +155 -0
- package/src/ui/SchematicPinSvgRenderer.mjs +397 -48
- package/src/ui/SchematicPowerDiagramImageProcessor.mjs +970 -0
- package/src/ui/SchematicPowerDiagramLineMasks.mjs +631 -0
- package/src/ui/SchematicPowerPortRenderer.mjs +1 -1
- package/src/ui/SchematicShapeRenderer.mjs +109 -24
- package/src/ui/SchematicSvgRenderer.mjs +1210 -71
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
// SPDX-FileCopyrightText: 2026 André Fiedler
|
|
2
|
+
//
|
|
3
|
+
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
4
|
+
|
|
5
|
+
const COMPACT_PIN_MAX_LENGTH = 15
|
|
6
|
+
const MARKER_LINE_BASE_TOLERANCE = 6
|
|
7
|
+
const MARKER_LINE_BASE_MAX_LENGTH = 8
|
|
8
|
+
const MARKER_LINE_COLOR = 'var(--schematic-accent-ink-color)'
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Normalizes compact owner-authored marker strokes around hidden pin stubs.
|
|
12
|
+
*/
|
|
13
|
+
export class SchematicOwnerPinMarkerLineThemer {
|
|
14
|
+
/**
|
|
15
|
+
* Applies schematic pin color to compact owner marker strokes.
|
|
16
|
+
* @param {{ x1?: number, y1?: number, x2?: number, y2?: number, color?: string, ownerIndex?: string }[]} lines Line primitives.
|
|
17
|
+
* @param {{ x?: number, y?: number, length?: number, name?: string, designator?: string, electrical?: number, ownerIndex?: string }[]} pins Pin primitives.
|
|
18
|
+
* @returns {{ x1?: number, y1?: number, x2?: number, y2?: number, color?: string, ownerIndex?: string }[]}
|
|
19
|
+
*/
|
|
20
|
+
static theme(lines, pins) {
|
|
21
|
+
const anchorsByOwner =
|
|
22
|
+
SchematicOwnerPinMarkerLineThemer.#buildCompactPinAnchors(pins)
|
|
23
|
+
|
|
24
|
+
if (anchorsByOwner.size === 0) {
|
|
25
|
+
return lines || []
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
return (lines || []).map((line) =>
|
|
29
|
+
SchematicOwnerPinMarkerLineThemer.#isCompactMarkerLine(
|
|
30
|
+
line,
|
|
31
|
+
anchorsByOwner
|
|
32
|
+
)
|
|
33
|
+
? { ...line, color: MARKER_LINE_COLOR }
|
|
34
|
+
: line
|
|
35
|
+
)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Builds lookup anchors for compact unnamed owner pins.
|
|
40
|
+
* @param {{ x?: number, y?: number, length?: number, name?: string, designator?: string, electrical?: number, ownerIndex?: string }[]} pins Pin primitives.
|
|
41
|
+
* @returns {Map<string, { x: number, y: number, tolerance: number, maxLineLength: number }[]>}
|
|
42
|
+
*/
|
|
43
|
+
static #buildCompactPinAnchors(pins) {
|
|
44
|
+
const anchorsByOwner = new Map()
|
|
45
|
+
|
|
46
|
+
for (const pin of pins || []) {
|
|
47
|
+
if (!SchematicOwnerPinMarkerLineThemer.#isCompactMarkerPin(pin)) {
|
|
48
|
+
continue
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const ownerIndex = String(pin.ownerIndex || '').trim()
|
|
52
|
+
const length = Math.abs(Number(pin.length || 0))
|
|
53
|
+
const anchor = {
|
|
54
|
+
x: Number(pin.x),
|
|
55
|
+
y: Number(pin.y),
|
|
56
|
+
tolerance: Math.max(MARKER_LINE_BASE_TOLERANCE, length * 0.6),
|
|
57
|
+
maxLineLength: Math.max(
|
|
58
|
+
MARKER_LINE_BASE_MAX_LENGTH,
|
|
59
|
+
length * 0.8
|
|
60
|
+
)
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
if (!anchorsByOwner.has(ownerIndex)) {
|
|
64
|
+
anchorsByOwner.set(ownerIndex, [])
|
|
65
|
+
}
|
|
66
|
+
anchorsByOwner.get(ownerIndex).push(anchor)
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
return anchorsByOwner
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Returns true for compact unnamed owner pins that are marker anchors.
|
|
74
|
+
* @param {{ x?: number, y?: number, length?: number, name?: string, designator?: string, electrical?: number, ownerIndex?: string } | null | undefined} pin Pin primitive.
|
|
75
|
+
* @returns {boolean}
|
|
76
|
+
*/
|
|
77
|
+
static #isCompactMarkerPin(pin) {
|
|
78
|
+
const ownerIndex = String(pin?.ownerIndex || '').trim()
|
|
79
|
+
const name = String(pin?.name || '').trim()
|
|
80
|
+
const designator = String(pin?.designator || '').trim()
|
|
81
|
+
const length = Math.abs(Number(pin?.length || 0))
|
|
82
|
+
const electrical = Number(pin?.electrical)
|
|
83
|
+
const x = Number(pin?.x)
|
|
84
|
+
const y = Number(pin?.y)
|
|
85
|
+
|
|
86
|
+
return (
|
|
87
|
+
Boolean(ownerIndex) &&
|
|
88
|
+
!name &&
|
|
89
|
+
/^\d+$/.test(designator) &&
|
|
90
|
+
Number.isFinite(x) &&
|
|
91
|
+
Number.isFinite(y) &&
|
|
92
|
+
length > 0 &&
|
|
93
|
+
length <= COMPACT_PIN_MAX_LENGTH &&
|
|
94
|
+
(!Number.isFinite(electrical) || electrical === 4)
|
|
95
|
+
)
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Returns true when one owner line is compact marker linework near a pin.
|
|
100
|
+
* @param {{ x1?: number, y1?: number, x2?: number, y2?: number, ownerIndex?: string } | null | undefined} line Line primitive.
|
|
101
|
+
* @param {Map<string, { x: number, y: number, tolerance: number, maxLineLength: number }[]>} anchorsByOwner Marker anchors by owner.
|
|
102
|
+
* @returns {boolean}
|
|
103
|
+
*/
|
|
104
|
+
static #isCompactMarkerLine(line, anchorsByOwner) {
|
|
105
|
+
const ownerIndex = String(line?.ownerIndex || '').trim()
|
|
106
|
+
const anchors = anchorsByOwner.get(ownerIndex)
|
|
107
|
+
|
|
108
|
+
if (!anchors?.length) {
|
|
109
|
+
return false
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
const pointA = {
|
|
113
|
+
x: Number(line?.x1),
|
|
114
|
+
y: Number(line?.y1)
|
|
115
|
+
}
|
|
116
|
+
const pointB = {
|
|
117
|
+
x: Number(line?.x2),
|
|
118
|
+
y: Number(line?.y2)
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
if (
|
|
122
|
+
!Number.isFinite(pointA.x) ||
|
|
123
|
+
!Number.isFinite(pointA.y) ||
|
|
124
|
+
!Number.isFinite(pointB.x) ||
|
|
125
|
+
!Number.isFinite(pointB.y)
|
|
126
|
+
) {
|
|
127
|
+
return false
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
const lineLength = SchematicOwnerPinMarkerLineThemer.#distance(
|
|
131
|
+
pointA,
|
|
132
|
+
pointB
|
|
133
|
+
)
|
|
134
|
+
|
|
135
|
+
return anchors.some(
|
|
136
|
+
(anchor) =>
|
|
137
|
+
lineLength > 0 &&
|
|
138
|
+
lineLength <= anchor.maxLineLength &&
|
|
139
|
+
SchematicOwnerPinMarkerLineThemer.#distance(pointA, anchor) <=
|
|
140
|
+
anchor.tolerance &&
|
|
141
|
+
SchematicOwnerPinMarkerLineThemer.#distance(pointB, anchor) <=
|
|
142
|
+
anchor.tolerance
|
|
143
|
+
)
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Measures planar distance between two schematic points.
|
|
148
|
+
* @param {{ x: number, y: number }} pointA First point.
|
|
149
|
+
* @param {{ x: number, y: number }} pointB Second point.
|
|
150
|
+
* @returns {number}
|
|
151
|
+
*/
|
|
152
|
+
static #distance(pointA, pointB) {
|
|
153
|
+
return Math.hypot(pointA.x - pointB.x, pointA.y - pointB.y)
|
|
154
|
+
}
|
|
155
|
+
}
|