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
|
@@ -8,6 +8,7 @@ import { SchematicTypography } from './SchematicTypography.mjs'
|
|
|
8
8
|
|
|
9
9
|
const { escapeHtml, formatNumber, projectSchematicY } = SchematicSvgUtils
|
|
10
10
|
const MINIMUM_NOTE_TEXT_SIZE = 4
|
|
11
|
+
const COMPACT_SINGLE_LINE_HEIGHT_RATIO = 1.6
|
|
11
12
|
|
|
12
13
|
/**
|
|
13
14
|
* Renders boxed schematic notes recovered from Altium note records.
|
|
@@ -15,7 +16,7 @@ const MINIMUM_NOTE_TEXT_SIZE = 4
|
|
|
15
16
|
export class SchematicNoteRenderer {
|
|
16
17
|
/**
|
|
17
18
|
* Builds one boxed schematic note/callout with wrapped text rows.
|
|
18
|
-
* @param {{ x: number, y: number, color: string, fontSize?: number, fontFamily?: string, fontWeight?: number, fontStyle?: string, cornerX?: number, cornerY?: number, fill?: string, borderColor?: string, lineWidth?: number, isSolid?: boolean, showBorder?: boolean, textMargin?: number, noteLines?: string[] }} text
|
|
19
|
+
* @param {{ x: number, y: number, color: string, fontSize?: number, fontFamily?: string, fontWeight?: number, fontStyle?: string, anchor?: 'start' | 'middle' | 'end', cornerX?: number, cornerY?: number, fill?: string, borderColor?: string, lineWidth?: number, isSolid?: boolean, showBorder?: boolean, textMargin?: number, noteLines?: string[] }} text
|
|
19
20
|
* @param {number} sheetHeight
|
|
20
21
|
* @returns {string}
|
|
21
22
|
*/
|
|
@@ -59,6 +60,10 @@ export class SchematicNoteRenderer {
|
|
|
59
60
|
height,
|
|
60
61
|
requestedTextSize
|
|
61
62
|
)
|
|
63
|
+
const compactMarkerNote = SchematicNoteRenderer.#isCompactMarkerNote(
|
|
64
|
+
noteSourceLines,
|
|
65
|
+
compactSingleLineNote
|
|
66
|
+
)
|
|
62
67
|
const horizontalTextMargin =
|
|
63
68
|
SchematicNoteRenderer.#resolveHorizontalTextMargin(
|
|
64
69
|
textMargin,
|
|
@@ -94,6 +99,7 @@ export class SchematicNoteRenderer {
|
|
|
94
99
|
lineHeight,
|
|
95
100
|
textSize,
|
|
96
101
|
compactSingleLineNote,
|
|
102
|
+
compactMarkerNote,
|
|
97
103
|
text
|
|
98
104
|
)
|
|
99
105
|
)
|
|
@@ -323,7 +329,10 @@ export class SchematicNoteRenderer {
|
|
|
323
329
|
String(line || '').trim()
|
|
324
330
|
).length
|
|
325
331
|
|
|
326
|
-
return
|
|
332
|
+
return (
|
|
333
|
+
visibleLineCount === 1 &&
|
|
334
|
+
height <= requestedTextSize * COMPACT_SINGLE_LINE_HEIGHT_RATIO
|
|
335
|
+
)
|
|
327
336
|
}
|
|
328
337
|
|
|
329
338
|
/**
|
|
@@ -462,7 +471,8 @@ export class SchematicNoteRenderer {
|
|
|
462
471
|
* @param {number} lineHeight
|
|
463
472
|
* @param {number} textSize
|
|
464
473
|
* @param {boolean} compactSingleLineNote
|
|
465
|
-
* @param {
|
|
474
|
+
* @param {boolean} compactMarkerNote
|
|
475
|
+
* @param {{ color: string, fontFamily?: string, fontWeight?: number, fontStyle?: string, anchor?: 'start' | 'middle' | 'end' }} text
|
|
466
476
|
* @returns {string}
|
|
467
477
|
*/
|
|
468
478
|
static #buildNoteLineMarkup(
|
|
@@ -476,9 +486,21 @@ export class SchematicNoteRenderer {
|
|
|
476
486
|
lineHeight,
|
|
477
487
|
textSize,
|
|
478
488
|
compactSingleLineNote,
|
|
489
|
+
compactMarkerNote,
|
|
479
490
|
text
|
|
480
491
|
) {
|
|
481
|
-
const
|
|
492
|
+
const anchor = SchematicNoteRenderer.#resolveTextAnchor(
|
|
493
|
+
text,
|
|
494
|
+
compactMarkerNote
|
|
495
|
+
)
|
|
496
|
+
const x = SchematicNoteRenderer.#resolveLineX(
|
|
497
|
+
left,
|
|
498
|
+
right,
|
|
499
|
+
horizontalTextMargin,
|
|
500
|
+
anchor
|
|
501
|
+
)
|
|
502
|
+
const ruleLeft = left + horizontalTextMargin
|
|
503
|
+
const ruleRight = right - horizontalTextMargin
|
|
482
504
|
const y =
|
|
483
505
|
top +
|
|
484
506
|
verticalTextMargin +
|
|
@@ -491,11 +513,11 @@ export class SchematicNoteRenderer {
|
|
|
491
513
|
if (/^_+$/.test(String(line || '').trim())) {
|
|
492
514
|
return (
|
|
493
515
|
'<line class="schematic-note-rule" x1="' +
|
|
494
|
-
formatNumber(
|
|
516
|
+
formatNumber(ruleLeft) +
|
|
495
517
|
'" y1="' +
|
|
496
518
|
formatNumber(y - textSize * 0.35) +
|
|
497
519
|
'" x2="' +
|
|
498
|
-
formatNumber(
|
|
520
|
+
formatNumber(ruleRight) +
|
|
499
521
|
'" y2="' +
|
|
500
522
|
formatNumber(y - textSize * 0.35) +
|
|
501
523
|
'" stroke="' +
|
|
@@ -521,7 +543,9 @@ export class SchematicNoteRenderer {
|
|
|
521
543
|
'--schematic-text-color'
|
|
522
544
|
)
|
|
523
545
|
) +
|
|
524
|
-
'" text-anchor="
|
|
546
|
+
'" text-anchor="' +
|
|
547
|
+
escapeHtml(anchor) +
|
|
548
|
+
'" font-size="' +
|
|
525
549
|
formatNumber(textSize) +
|
|
526
550
|
'" font-family="' +
|
|
527
551
|
escapeHtml(text.fontFamily || 'Times New Roman') +
|
|
@@ -534,6 +558,62 @@ export class SchematicNoteRenderer {
|
|
|
534
558
|
)
|
|
535
559
|
}
|
|
536
560
|
|
|
561
|
+
/**
|
|
562
|
+
* Resolves the x coordinate for a note line from its text anchor.
|
|
563
|
+
* @param {number} left Note box left edge.
|
|
564
|
+
* @param {number} right Note box right edge.
|
|
565
|
+
* @param {number} horizontalTextMargin Text margin.
|
|
566
|
+
* @param {'start' | 'middle' | 'end'} anchor Text anchor.
|
|
567
|
+
* @returns {number}
|
|
568
|
+
*/
|
|
569
|
+
static #resolveLineX(left, right, horizontalTextMargin, anchor) {
|
|
570
|
+
if (anchor === 'middle') return (left + right) / 2
|
|
571
|
+
if (anchor === 'end') return right - horizontalTextMargin
|
|
572
|
+
|
|
573
|
+
return left + horizontalTextMargin
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
/**
|
|
577
|
+
* Returns true for tight single-token marker boxes that Altium centers
|
|
578
|
+
* inside the authored note rectangle.
|
|
579
|
+
* @param {string[]} noteLines Source note rows.
|
|
580
|
+
* @param {boolean} compactSingleLineNote True for tight one-line note boxes.
|
|
581
|
+
* @returns {boolean}
|
|
582
|
+
*/
|
|
583
|
+
static #isCompactMarkerNote(noteLines, compactSingleLineNote) {
|
|
584
|
+
if (!compactSingleLineNote) {
|
|
585
|
+
return false
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
const visibleLines = noteLines
|
|
589
|
+
.map((line) => String(line || '').trim())
|
|
590
|
+
.filter(Boolean)
|
|
591
|
+
|
|
592
|
+
if (visibleLines.length !== 1) {
|
|
593
|
+
return false
|
|
594
|
+
}
|
|
595
|
+
|
|
596
|
+
return /^[A-Z0-9._/-]{1,4}$/u.test(visibleLines[0])
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
/**
|
|
600
|
+
* Normalizes note text anchors to SVG text-anchor values.
|
|
601
|
+
* @param {{ anchor?: string }} text Note text.
|
|
602
|
+
* @param {boolean} compactMarkerNote True for centered marker notes.
|
|
603
|
+
* @returns {'start' | 'middle' | 'end'}
|
|
604
|
+
*/
|
|
605
|
+
static #resolveTextAnchor(text, compactMarkerNote) {
|
|
606
|
+
if (compactMarkerNote) {
|
|
607
|
+
return 'middle'
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
if (text.anchor === 'middle' || text.anchor === 'end') {
|
|
611
|
+
return text.anchor
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
return 'start'
|
|
615
|
+
}
|
|
616
|
+
|
|
537
617
|
/**
|
|
538
618
|
* Builds an optional note font-style attribute.
|
|
539
619
|
* @param {string | undefined} fontStyle
|