altium-toolkit 1.0.2 → 1.0.8
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/package.json +1 -1
- package/src/core/altium/AltiumParser.mjs +17 -6
- package/src/core/altium/AsciiRecordParser.mjs +28 -1
- package/src/core/altium/SchematicPinDesignatorInferer.mjs +36 -3
- package/src/core/altium/SchematicPinParser.mjs +139 -14
- package/src/core/altium/SchematicPrimitiveParser.mjs +75 -4
- package/src/core/altium/SchematicTextParser.mjs +22 -18
- package/src/core/altium/SchematicTextPostProcessor.mjs +127 -10
- package/src/core/altium/SchematicWireNormalizer.mjs +1162 -0
- package/src/renderers.mjs +3 -0
- package/src/styles/altium-renderers.css +6 -0
- package/src/ui/PcbInteractionGeometry.mjs +350 -0
- package/src/ui/PcbInteractionIndex.mjs +588 -0
- package/src/ui/PcbInteractionItemRegistry.mjs +66 -0
- package/src/ui/PcbInteractionLayerModel.mjs +99 -0
- package/src/ui/PcbScene3dBoardOutlineRefiner.mjs +74 -9
- package/src/ui/PcbScene3dBuilder.mjs +32 -4
- package/src/ui/PcbSvgRenderer.mjs +2 -2
- package/src/ui/PcbTextPrimitiveRenderer.mjs +58 -2
- package/src/ui/SchematicContentLayout.mjs +124 -22
- package/src/ui/SchematicJunctionRenderer.mjs +21 -3
- package/src/ui/SchematicNoteRenderer.mjs +75 -10
- package/src/ui/SchematicPinSvgRenderer.mjs +48 -7
- package/src/ui/SchematicPowerPortRenderer.mjs +53 -160
- package/src/ui/SchematicSheetChromeRenderer.mjs +29 -15
- package/src/ui/SchematicSvgRenderer.mjs +341 -39
- package/src/ui/SchematicSvgUtils.mjs +9 -2
- package/src/ui/SchematicTypography.mjs +13 -10
|
@@ -243,7 +243,7 @@ export class SchematicTextPostProcessor {
|
|
|
243
243
|
* or off-sheet port keep their original left-to-right flow.
|
|
244
244
|
* @param {{ x: number, y: number, text: string, name?: string, ownerIndex?: string, recordType?: string, rotation?: number, anchor?: 'start' | 'middle' | 'end' }[]} texts
|
|
245
245
|
* @param {{ x1: number, y1: number, x2: number, y2: number, ownerIndex?: string }[]} lines
|
|
246
|
-
* @param {{ x: number, y: number, length: number, orientation: 'left' | 'right' | 'top' | 'bottom' }[]} pins
|
|
246
|
+
* @param {{ x: number, y: number, length: number, orientation: 'left' | 'right' | 'top' | 'bottom', designator?: string, labelMode?: 'hidden' | 'number-only' | 'name-only' | 'name-and-number', symbolOuter?: number }[]} pins
|
|
247
247
|
* @param {{ x: number, y: number, width: number, direction?: 'left' | 'right' | 'up' | 'down' }[]} ports
|
|
248
248
|
* @returns {{ x: number, y: number, text: string, name?: string, ownerIndex?: string, recordType?: string, rotation?: number, anchor?: 'start' | 'middle' | 'end' }[]}
|
|
249
249
|
*/
|
|
@@ -258,46 +258,163 @@ export class SchematicTextPostProcessor {
|
|
|
258
258
|
return text
|
|
259
259
|
}
|
|
260
260
|
|
|
261
|
+
const pinOffsetText =
|
|
262
|
+
SchematicTextPostProcessor.#offsetWireLabelPastRightPinNumber(
|
|
263
|
+
text,
|
|
264
|
+
pins
|
|
265
|
+
)
|
|
261
266
|
const hasNearbyRightDesignator = texts.some(
|
|
262
267
|
(candidate) =>
|
|
263
268
|
candidate &&
|
|
264
269
|
candidate.name === 'Designator' &&
|
|
265
270
|
!candidate.rotation &&
|
|
266
|
-
candidate.x >
|
|
267
|
-
candidate.x -
|
|
268
|
-
Math.abs(candidate.y -
|
|
271
|
+
candidate.x > pinOffsetText.x &&
|
|
272
|
+
candidate.x - pinOffsetText.x <= 80 &&
|
|
273
|
+
Math.abs(candidate.y - pinOffsetText.y) <= 2
|
|
269
274
|
)
|
|
270
275
|
|
|
271
276
|
if (!hasNearbyRightDesignator) {
|
|
272
|
-
return
|
|
277
|
+
return pinOffsetText
|
|
273
278
|
}
|
|
274
279
|
|
|
275
280
|
if (
|
|
276
281
|
SchematicTextPostProcessor.#hasPinConnectedAtWireStart(
|
|
277
|
-
|
|
282
|
+
pinOffsetText,
|
|
278
283
|
lines,
|
|
279
284
|
pins
|
|
280
285
|
) ||
|
|
281
286
|
SchematicTextPostProcessor.#hasLineConnectedAtWireStart(
|
|
282
|
-
|
|
287
|
+
pinOffsetText,
|
|
283
288
|
lines
|
|
284
289
|
) ||
|
|
285
290
|
SchematicTextPostProcessor.#hasPortConnectedAtWireStart(
|
|
286
|
-
|
|
291
|
+
pinOffsetText,
|
|
287
292
|
lines,
|
|
288
293
|
ports
|
|
289
294
|
)
|
|
290
295
|
) {
|
|
291
|
-
return
|
|
296
|
+
return pinOffsetText
|
|
292
297
|
}
|
|
293
298
|
|
|
294
299
|
return {
|
|
295
|
-
...
|
|
300
|
+
...pinOffsetText,
|
|
296
301
|
anchor: 'end'
|
|
297
302
|
}
|
|
298
303
|
})
|
|
299
304
|
}
|
|
300
305
|
|
|
306
|
+
/**
|
|
307
|
+
* Moves a start-anchored horizontal wire label rightward when it starts at
|
|
308
|
+
* the outer endpoint of a visible right-facing pin number.
|
|
309
|
+
* @param {{ x: number, y: number, text: string, recordType?: string, rotation?: number, anchor?: 'start' | 'middle' | 'end' }} text
|
|
310
|
+
* @param {{ x: number, y: number, length: number, orientation: 'left' | 'right' | 'top' | 'bottom', designator?: string, labelMode?: 'hidden' | 'number-only' | 'name-only' | 'name-and-number', symbolOuter?: number }[]} pins
|
|
311
|
+
* @returns {{ x: number, y: number, text: string, recordType?: string, rotation?: number, anchor?: 'start' | 'middle' | 'end' }}
|
|
312
|
+
*/
|
|
313
|
+
static #offsetWireLabelPastRightPinNumber(text, pins) {
|
|
314
|
+
const requiredX = pins.reduce((maxX, pin) => {
|
|
315
|
+
if (
|
|
316
|
+
!SchematicTextPostProcessor.#isVisibleRightPinNumber(pin) ||
|
|
317
|
+
!SchematicTextPostProcessor.#textStartsAtPinOuterEndpoint(
|
|
318
|
+
text,
|
|
319
|
+
pin
|
|
320
|
+
)
|
|
321
|
+
) {
|
|
322
|
+
return maxX
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
return Math.max(
|
|
326
|
+
maxX,
|
|
327
|
+
SchematicTextPostProcessor.#resolveRightPinNumberTextEndX(pin) +
|
|
328
|
+
4
|
|
329
|
+
)
|
|
330
|
+
}, text.x)
|
|
331
|
+
|
|
332
|
+
if (requiredX <= text.x) {
|
|
333
|
+
return text
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
return {
|
|
337
|
+
...text,
|
|
338
|
+
x: requiredX
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
/**
|
|
343
|
+
* Returns true when one pin renders a right-side number label.
|
|
344
|
+
* @param {{ orientation: 'left' | 'right' | 'top' | 'bottom', designator?: string, labelMode?: 'hidden' | 'number-only' | 'name-only' | 'name-and-number' }} pin
|
|
345
|
+
* @returns {boolean}
|
|
346
|
+
*/
|
|
347
|
+
static #isVisibleRightPinNumber(pin) {
|
|
348
|
+
const labelMode = pin?.labelMode || 'name-and-number'
|
|
349
|
+
|
|
350
|
+
return (
|
|
351
|
+
pin?.orientation === 'right' &&
|
|
352
|
+
labelMode !== 'hidden' &&
|
|
353
|
+
labelMode !== 'name-only' &&
|
|
354
|
+
String(pin.designator || '').trim() !== ''
|
|
355
|
+
)
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
/**
|
|
359
|
+
* Returns true when a text record starts on one pin's outer wire endpoint.
|
|
360
|
+
* @param {{ x: number, y: number }} text
|
|
361
|
+
* @param {{ x: number, y: number, length: number, orientation: 'left' | 'right' | 'top' | 'bottom' }} pin
|
|
362
|
+
* @returns {boolean}
|
|
363
|
+
*/
|
|
364
|
+
static #textStartsAtPinOuterEndpoint(text, pin) {
|
|
365
|
+
const endpoint =
|
|
366
|
+
SchematicTextPostProcessor.#projectPinOuterEndpoint(pin)
|
|
367
|
+
|
|
368
|
+
return (
|
|
369
|
+
endpoint !== null &&
|
|
370
|
+
Math.abs(endpoint.x - text.x) <= 2 &&
|
|
371
|
+
Math.abs(endpoint.y - text.y) <= 2
|
|
372
|
+
)
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
/**
|
|
376
|
+
* Estimates the x coordinate immediately after one rendered right pin
|
|
377
|
+
* number.
|
|
378
|
+
* @param {{ x: number, designator?: string, symbolOuter?: number }} pin
|
|
379
|
+
* @returns {number}
|
|
380
|
+
*/
|
|
381
|
+
static #resolveRightPinNumberTextEndX(pin) {
|
|
382
|
+
return (
|
|
383
|
+
Number(pin.x) +
|
|
384
|
+
SchematicTextPostProcessor.#resolveHorizontalPinNumberClearance(
|
|
385
|
+
pin.symbolOuter
|
|
386
|
+
) +
|
|
387
|
+
SchematicTextPostProcessor.#estimatePinNumberWidth(pin.designator)
|
|
388
|
+
)
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
/**
|
|
392
|
+
* Returns the horizontal clearance used by authored outer pin markers.
|
|
393
|
+
* @param {number | undefined} symbolOuter
|
|
394
|
+
* @returns {number}
|
|
395
|
+
*/
|
|
396
|
+
static #resolveHorizontalPinNumberClearance(symbolOuter) {
|
|
397
|
+
switch (Number(symbolOuter || 0)) {
|
|
398
|
+
case 34:
|
|
399
|
+
return 17
|
|
400
|
+
case 1:
|
|
401
|
+
case 2:
|
|
402
|
+
case 33:
|
|
403
|
+
return 8
|
|
404
|
+
default:
|
|
405
|
+
return 2
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
/**
|
|
410
|
+
* Estimates one schematic pin-number label width in viewer SVG units.
|
|
411
|
+
* @param {string | undefined} designator
|
|
412
|
+
* @returns {number}
|
|
413
|
+
*/
|
|
414
|
+
static #estimatePinNumberWidth(designator) {
|
|
415
|
+
return Math.max(String(designator || '').trim().length * 5, 5)
|
|
416
|
+
}
|
|
417
|
+
|
|
301
418
|
/**
|
|
302
419
|
* Builds per-owner primitive bounds from drawable lines, pins, and bodies.
|
|
303
420
|
* @param {{ x1: number, y1: number, x2: number, y2: number, ownerIndex?: string }[]} lines
|