circuitscript 0.0.28 → 0.0.31
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/dist/cjs/BaseVisitor.js +6 -1
- package/dist/cjs/antlr/CircuitScriptLexer.js +204 -200
- package/dist/cjs/antlr/CircuitScriptParser.js +1066 -1173
- package/dist/cjs/draw_symbols.js +383 -103
- package/dist/cjs/execute.js +39 -14
- package/dist/cjs/geometry.js +79 -18
- package/dist/cjs/globals.js +41 -7
- package/dist/cjs/helpers.js +40 -2
- package/dist/cjs/layout.js +72 -39
- package/dist/cjs/main.js +10 -4
- package/dist/cjs/objects/ClassComponent.js +2 -0
- package/dist/cjs/objects/ExecutionScope.js +1 -1
- package/dist/cjs/objects/Net.js +3 -2
- package/dist/cjs/objects/PinTypes.js +7 -1
- package/dist/cjs/objects/types.js +11 -1
- package/dist/cjs/regenerate-tests.js +84 -14
- package/dist/cjs/render.js +22 -15
- package/dist/cjs/sizing.js +4 -6
- package/dist/cjs/utils.js +29 -5
- package/dist/cjs/visitor.js +176 -10
- package/dist/esm/BaseVisitor.mjs +6 -1
- package/dist/esm/antlr/CircuitScriptLexer.mjs +204 -200
- package/dist/esm/antlr/CircuitScriptParser.mjs +1061 -1171
- package/dist/esm/antlr/CircuitScriptVisitor.mjs +3 -0
- package/dist/esm/draw_symbols.mjs +378 -102
- package/dist/esm/execute.mjs +40 -15
- package/dist/esm/geometry.mjs +79 -17
- package/dist/esm/globals.mjs +40 -6
- package/dist/esm/helpers.mjs +38 -1
- package/dist/esm/layout.mjs +75 -42
- package/dist/esm/main.mjs +11 -5
- package/dist/esm/objects/ClassComponent.mjs +6 -0
- package/dist/esm/objects/ExecutionScope.mjs +1 -1
- package/dist/esm/objects/Net.mjs +3 -2
- package/dist/esm/objects/PinTypes.mjs +6 -0
- package/dist/esm/objects/types.mjs +14 -0
- package/dist/esm/regenerate-tests.mjs +85 -15
- package/dist/esm/render.mjs +23 -16
- package/dist/esm/sizing.mjs +3 -4
- package/dist/esm/utils.mjs +26 -4
- package/dist/esm/visitor.mjs +179 -13
- package/dist/types/antlr/CircuitScriptLexer.d.ts +42 -41
- package/dist/types/antlr/CircuitScriptParser.d.ts +144 -133
- package/dist/types/antlr/CircuitScriptVisitor.d.ts +6 -0
- package/dist/types/draw_symbols.d.ts +24 -6
- package/dist/types/execute.d.ts +5 -4
- package/dist/types/geometry.d.ts +5 -3
- package/dist/types/globals.d.ts +38 -6
- package/dist/types/helpers.d.ts +12 -0
- package/dist/types/layout.d.ts +2 -1
- package/dist/types/objects/ClassComponent.d.ts +8 -0
- package/dist/types/objects/PinTypes.d.ts +1 -0
- package/dist/types/objects/Wire.d.ts +4 -2
- package/dist/types/objects/types.d.ts +8 -0
- package/dist/types/sizing.d.ts +0 -4
- package/dist/types/utils.d.ts +3 -0
- package/dist/types/visitor.d.ts +8 -1
- package/fonts/Arial.ttf +0 -0
- package/libs/lib.cst +78 -55
- package/package.json +1 -1
package/dist/esm/execute.mjs
CHANGED
|
@@ -3,7 +3,7 @@ import { ClassComponent } from './objects/ClassComponent.mjs';
|
|
|
3
3
|
import { ActiveObject, ExecutionScope, FrameAction, SequenceAction } from './objects/ExecutionScope.mjs';
|
|
4
4
|
import { Net } from './objects/Net.mjs';
|
|
5
5
|
import { PortSide } from './objects/PinDefinition.mjs';
|
|
6
|
-
import { Direction } from './objects/types.mjs';
|
|
6
|
+
import { DeclaredReference, Direction } from './objects/types.mjs';
|
|
7
7
|
import { Wire } from './objects/Wire.mjs';
|
|
8
8
|
import { Frame } from './objects/Frame.mjs';
|
|
9
9
|
import { CalculatePinPositions } from './layout.mjs';
|
|
@@ -199,20 +199,20 @@ export class ExecutionContext {
|
|
|
199
199
|
return component;
|
|
200
200
|
}
|
|
201
201
|
printPoint(extra = '') {
|
|
202
|
-
let
|
|
202
|
+
let netString = NoNetText;
|
|
203
203
|
if (this.scope.currentComponent === null || this.scope.currentPin === null) {
|
|
204
204
|
this.log((extra !== '' ? (extra + ' ') : '') + 'point is null');
|
|
205
205
|
return;
|
|
206
206
|
}
|
|
207
207
|
if (this.scope.hasNet(this.scope.currentComponent, this.scope.currentPin)) {
|
|
208
|
-
|
|
208
|
+
netString = this.scope
|
|
209
209
|
.getNet(this.scope.currentComponent, this.scope.currentPin)
|
|
210
210
|
.toString();
|
|
211
211
|
}
|
|
212
212
|
this.log((extra !== '' ? (extra + ' ') : '') + 'point: ' +
|
|
213
213
|
this.scope.currentComponent.instanceName +
|
|
214
214
|
' ' +
|
|
215
|
-
this.scope.currentPin + ' ' +
|
|
215
|
+
this.scope.currentPin + ' ' + netString);
|
|
216
216
|
}
|
|
217
217
|
addComponentExisting(component, pin) {
|
|
218
218
|
const startPin = pin;
|
|
@@ -466,34 +466,34 @@ export class ExecutionContext {
|
|
|
466
466
|
for (let i = 0; i < reversed.length; i++) {
|
|
467
467
|
const context = reversed[i];
|
|
468
468
|
if (context.hasFunction(idName)) {
|
|
469
|
-
return {
|
|
469
|
+
return new DeclaredReference({
|
|
470
470
|
found: true,
|
|
471
471
|
value: context.getFunction(idName),
|
|
472
472
|
type: ReferenceTypes.function,
|
|
473
473
|
name: idName,
|
|
474
|
-
};
|
|
474
|
+
});
|
|
475
475
|
}
|
|
476
476
|
else if (context.scope.variables.has(idName)) {
|
|
477
|
-
return {
|
|
477
|
+
return new DeclaredReference({
|
|
478
478
|
found: true,
|
|
479
479
|
value: context.scope.variables.get(idName),
|
|
480
480
|
type: ReferenceTypes.variable,
|
|
481
481
|
name: idName,
|
|
482
|
-
};
|
|
482
|
+
});
|
|
483
483
|
}
|
|
484
484
|
else if (context.scope.instances.has(idName)) {
|
|
485
|
-
return {
|
|
485
|
+
return new DeclaredReference({
|
|
486
486
|
found: true,
|
|
487
487
|
value: context.scope.instances.get(idName),
|
|
488
488
|
type: ReferenceTypes.instance,
|
|
489
489
|
name: idName,
|
|
490
|
-
};
|
|
490
|
+
});
|
|
491
491
|
}
|
|
492
492
|
}
|
|
493
|
-
return {
|
|
493
|
+
return new DeclaredReference({
|
|
494
494
|
found: false,
|
|
495
495
|
name: idName,
|
|
496
|
-
};
|
|
496
|
+
});
|
|
497
497
|
}
|
|
498
498
|
callFunction(functionName, functionParams, executionStack, netNamespace) {
|
|
499
499
|
let __runFunc = null;
|
|
@@ -520,6 +520,7 @@ export class ExecutionContext {
|
|
|
520
520
|
}
|
|
521
521
|
if (__runFunc !== null) {
|
|
522
522
|
this.log(`call function '${functionName}'`);
|
|
523
|
+
this.log(`net namespace: ${netNamespace}`);
|
|
523
524
|
const functionResult = __runFunc(functionParams, { netNamespace });
|
|
524
525
|
this.log(`done call function '${functionName}'`);
|
|
525
526
|
return functionResult;
|
|
@@ -652,6 +653,10 @@ export class ExecutionContext {
|
|
|
652
653
|
this.scope.setActive(ActiveObject.Wire, wireId);
|
|
653
654
|
this.scope.sequence.push([SequenceAction.Wire, wireId, tmp]);
|
|
654
655
|
this.scope.currentComponent.pinWires.set(this.scope.currentPin, tmp);
|
|
656
|
+
if (!this.scope.currentComponent.didSetWireOrientationAngle) {
|
|
657
|
+
this.applyComponentAngleFromWire(this.scope.currentComponent, this.scope.currentPin, true);
|
|
658
|
+
this.scope.currentComponent.didSetWireOrientationAngle = true;
|
|
659
|
+
}
|
|
655
660
|
}
|
|
656
661
|
addPoint(pointId, userDefined = true) {
|
|
657
662
|
if (this.scope.instances.has(pointId)) {
|
|
@@ -702,18 +707,37 @@ export class ExecutionContext {
|
|
|
702
707
|
this.scope.currentComponent.styles[key] = styles[key];
|
|
703
708
|
}
|
|
704
709
|
}
|
|
705
|
-
applyComponentAngleFromWire(component, pin) {
|
|
710
|
+
applyComponentAngleFromWire(component, pin, opposite = false) {
|
|
706
711
|
if (this.componentAngleFollowsWire
|
|
707
712
|
&& component.followWireOrientationProp
|
|
708
713
|
&& component.useWireOrientationAngle
|
|
714
|
+
&& !component.didSetWireOrientationAngle
|
|
709
715
|
&& this.scope.currentWireId !== -1) {
|
|
710
716
|
const currentWire = this.scope.wires[this.scope.currentWireId];
|
|
711
|
-
|
|
717
|
+
let useSegment = currentWire.path[currentWire.path.length - 1];
|
|
718
|
+
if (opposite) {
|
|
719
|
+
useSegment = currentWire.path[0];
|
|
720
|
+
}
|
|
712
721
|
const pinPositions = CalculatePinPositions(component);
|
|
713
722
|
if (pinPositions.has(pin)) {
|
|
714
723
|
const connectedPinPos = pinPositions.get(pin);
|
|
715
724
|
let targetAngle = null;
|
|
716
|
-
|
|
725
|
+
let useDirection = useSegment.direction;
|
|
726
|
+
if (opposite) {
|
|
727
|
+
if (useDirection === Direction.Down) {
|
|
728
|
+
useDirection = Direction.Up;
|
|
729
|
+
}
|
|
730
|
+
else if (useDirection === Direction.Up) {
|
|
731
|
+
useDirection = Direction.Down;
|
|
732
|
+
}
|
|
733
|
+
else if (useDirection === Direction.Right) {
|
|
734
|
+
useDirection = Direction.Left;
|
|
735
|
+
}
|
|
736
|
+
else if (useDirection === Direction.Left) {
|
|
737
|
+
useDirection = Direction.Right;
|
|
738
|
+
}
|
|
739
|
+
}
|
|
740
|
+
switch (useDirection) {
|
|
717
741
|
case Direction.Down:
|
|
718
742
|
targetAngle = 90;
|
|
719
743
|
break;
|
|
@@ -752,6 +776,7 @@ export class ExecutionContext {
|
|
|
752
776
|
component.setParam('angle', 270);
|
|
753
777
|
}
|
|
754
778
|
component.wireOrientationAngle = useAngle;
|
|
779
|
+
component.didSetWireOrientationAngle = true;
|
|
755
780
|
}
|
|
756
781
|
}
|
|
757
782
|
}
|
package/dist/esm/geometry.mjs
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import Flatten from '@flatten-js/core';
|
|
2
2
|
import { measureTextSize2 } from './sizing.mjs';
|
|
3
|
-
import { defaultFont } from './globals.mjs';
|
|
3
|
+
import { defaultFont, fontDisplayScale, PortArrowSize, PortPaddingHorizontal, PortPaddingVertical } from './globals.mjs';
|
|
4
4
|
import { NumericValue } from './objects/ParamDefinition.mjs';
|
|
5
|
+
import { AllPinTypes, PinTypes } from './objects/PinTypes.mjs';
|
|
6
|
+
import { roundValue } from './utils.mjs';
|
|
5
7
|
export class Textbox extends Flatten.Polygon {
|
|
6
8
|
id;
|
|
7
9
|
text;
|
|
@@ -41,32 +43,90 @@ export class Textbox extends Flatten.Polygon {
|
|
|
41
43
|
else {
|
|
42
44
|
throw 'Invalid string passed into textbox';
|
|
43
45
|
}
|
|
44
|
-
const { fontSize = 10, anchor = HorizontalAlign.Left, vanchor = VerticalAlign.Bottom, fontWeight = 'regular', } = style ?? {};
|
|
45
|
-
const { width, height, box } = measureTextSize2(useText, defaultFont, fontSize, fontWeight, anchor, vanchor);
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
[
|
|
51
|
-
|
|
52
|
-
|
|
46
|
+
const { fontSize = 10, anchor = HorizontalAlign.Left, vanchor = VerticalAlign.Bottom, fontWeight = 'regular', portType = null, } = style ?? {};
|
|
47
|
+
const { width, height, box } = measureTextSize2(useText, defaultFont, fontSize * fontDisplayScale, fontWeight, anchor, vanchor);
|
|
48
|
+
let polygonCoords = [];
|
|
49
|
+
let anchorOffsetX = 0;
|
|
50
|
+
let anchorOffsetY = 0;
|
|
51
|
+
if (portType === null) {
|
|
52
|
+
polygonCoords = [
|
|
53
|
+
[box.x, box.y],
|
|
54
|
+
[box.x2, box.y],
|
|
55
|
+
[box.x2, box.y2],
|
|
56
|
+
[box.x, box.y2],
|
|
57
|
+
[box.x, box.y],
|
|
58
|
+
];
|
|
59
|
+
}
|
|
60
|
+
else if (AllPinTypes.indexOf(portType) !== -1) {
|
|
61
|
+
const paddingHorizontal = PortPaddingHorizontal;
|
|
62
|
+
const paddingVert = PortPaddingVertical;
|
|
63
|
+
if (portType === PinTypes.Input) {
|
|
64
|
+
polygonCoords = [
|
|
65
|
+
[box.x - paddingHorizontal - PortArrowSize, box.y - paddingVert],
|
|
66
|
+
[box.x2 + paddingHorizontal, box.y - paddingVert],
|
|
67
|
+
[box.x2 + paddingHorizontal, box.y2 + paddingVert],
|
|
68
|
+
[box.x - paddingHorizontal - PortArrowSize, box.y2 + paddingVert],
|
|
69
|
+
[box.x - paddingHorizontal - PortArrowSize, box.y - paddingVert],
|
|
70
|
+
];
|
|
71
|
+
anchorOffsetX += (PortArrowSize + paddingHorizontal);
|
|
72
|
+
}
|
|
73
|
+
else if (portType === PinTypes.Output) {
|
|
74
|
+
polygonCoords = [
|
|
75
|
+
[box.x - paddingHorizontal, box.y - paddingVert],
|
|
76
|
+
[box.x2 + paddingHorizontal + PortArrowSize, box.y - paddingVert],
|
|
77
|
+
[box.x2 + paddingHorizontal + PortArrowSize, box.y2 + paddingVert],
|
|
78
|
+
[box.x - paddingHorizontal, box.y2 + paddingVert],
|
|
79
|
+
[box.x - paddingHorizontal, box.y - paddingVert],
|
|
80
|
+
];
|
|
81
|
+
anchorOffsetX += paddingHorizontal;
|
|
82
|
+
}
|
|
83
|
+
else if (portType === PinTypes.IO) {
|
|
84
|
+
polygonCoords = [
|
|
85
|
+
[box.x - paddingHorizontal - PortArrowSize, box.y - paddingVert],
|
|
86
|
+
[box.x2 + paddingHorizontal + PortArrowSize, box.y - paddingVert],
|
|
87
|
+
[box.x2 + paddingHorizontal + PortArrowSize, box.y2 + paddingVert],
|
|
88
|
+
[box.x - paddingHorizontal - PortArrowSize, box.y2 + paddingVert],
|
|
89
|
+
[box.x - paddingHorizontal - PortArrowSize, box.y - paddingVert],
|
|
90
|
+
];
|
|
91
|
+
anchorOffsetX += paddingHorizontal + PortArrowSize;
|
|
92
|
+
}
|
|
93
|
+
else if (portType === PinTypes.Any) {
|
|
94
|
+
polygonCoords = [
|
|
95
|
+
[box.x - paddingHorizontal, box.y - paddingVert],
|
|
96
|
+
[box.x2 + paddingHorizontal, box.y - paddingVert],
|
|
97
|
+
[box.x2 + paddingHorizontal, box.y2 + paddingVert],
|
|
98
|
+
[box.x - paddingHorizontal, box.y2 + paddingVert],
|
|
99
|
+
[box.x - paddingHorizontal, box.y - paddingVert],
|
|
100
|
+
];
|
|
101
|
+
anchorOffsetX += paddingHorizontal;
|
|
102
|
+
}
|
|
103
|
+
anchorOffsetY += paddingVert / 2;
|
|
104
|
+
}
|
|
53
105
|
const polygon = new Flatten.Polygon(polygonCoords);
|
|
54
|
-
return new Textbox(id, useText, [x, y], polygon, style, box, label);
|
|
106
|
+
return new Textbox(id, useText, [x + anchorOffsetX, y + anchorOffsetY], polygon, style, box, label);
|
|
55
107
|
}
|
|
56
108
|
rotate(angle, origin) {
|
|
57
109
|
const feature = super.rotate(angle, origin);
|
|
58
|
-
|
|
110
|
+
const newAnchorPoint = this.transformAnchorPoint(segment => segment.rotate(angle, origin));
|
|
111
|
+
return new Textbox(this.id, this.text, newAnchorPoint, feature, this.style, this.textMeasurementBounds, this.label);
|
|
59
112
|
}
|
|
60
113
|
transform(matrix) {
|
|
61
114
|
const feature = super.transform(matrix);
|
|
62
|
-
|
|
115
|
+
const newAnchorPoint = this.transformAnchorPoint(segment => segment.transform(matrix));
|
|
116
|
+
return new Textbox(this.id, this.text, newAnchorPoint, feature, this.style, this.textMeasurementBounds, this.label);
|
|
117
|
+
}
|
|
118
|
+
transformAnchorPoint(callback) {
|
|
119
|
+
const anchorPointSegment = new Flatten.Segment(new Flatten.Point(0, 0), new Flatten.Point(this.anchorPoint));
|
|
120
|
+
const newSegment = callback(anchorPointSegment);
|
|
121
|
+
const lastPoint = newSegment.vertices[newSegment.vertices.length - 1];
|
|
122
|
+
return [
|
|
123
|
+
lastPoint.x, lastPoint.y
|
|
124
|
+
];
|
|
63
125
|
}
|
|
64
126
|
getLabelPosition() {
|
|
65
127
|
return this.anchorPoint;
|
|
66
128
|
}
|
|
67
129
|
}
|
|
68
|
-
export class Label extends Textbox {
|
|
69
|
-
}
|
|
70
130
|
export class GeometryProp {
|
|
71
131
|
name;
|
|
72
132
|
value;
|
|
@@ -150,7 +210,7 @@ export class Geometry {
|
|
|
150
210
|
&& feature.text.trim().length === 0) {
|
|
151
211
|
return;
|
|
152
212
|
}
|
|
153
|
-
if (feature instanceof Textbox
|
|
213
|
+
if (feature instanceof Textbox) {
|
|
154
214
|
const [x, y] = feature.anchorPoint;
|
|
155
215
|
box = {
|
|
156
216
|
xmin: box.xmin + x,
|
|
@@ -247,7 +307,9 @@ export class Geometry {
|
|
|
247
307
|
const existingSegments = [];
|
|
248
308
|
wirePoints.forEach(points => {
|
|
249
309
|
const tmpPoints = points.map(pt => {
|
|
250
|
-
|
|
310
|
+
const roundedX = roundValue(pt.x);
|
|
311
|
+
const roundedY = roundValue(pt.y);
|
|
312
|
+
return new Flatten.Point(roundedX, roundedY);
|
|
251
313
|
});
|
|
252
314
|
for (let i = 0; i < tmpPoints.length - 1; i++) {
|
|
253
315
|
const pt1 = tmpPoints[i];
|
package/dist/esm/globals.mjs
CHANGED
|
@@ -23,15 +23,49 @@ export var SymbolPinSide;
|
|
|
23
23
|
SymbolPinSide["Left"] = "left";
|
|
24
24
|
SymbolPinSide["Right"] = "right";
|
|
25
25
|
})(SymbolPinSide || (SymbolPinSide = {}));
|
|
26
|
+
export var LengthUnit;
|
|
27
|
+
(function (LengthUnit) {
|
|
28
|
+
LengthUnit["mm"] = "mm";
|
|
29
|
+
LengthUnit["mils"] = "mils";
|
|
30
|
+
LengthUnit["px"] = "px";
|
|
31
|
+
})(LengthUnit || (LengthUnit = {}));
|
|
32
|
+
export var WireAutoDirection;
|
|
33
|
+
(function (WireAutoDirection) {
|
|
34
|
+
WireAutoDirection["Auto"] = "auto";
|
|
35
|
+
WireAutoDirection["Auto_"] = "auto_";
|
|
36
|
+
})(WireAutoDirection || (WireAutoDirection = {}));
|
|
37
|
+
export const MilsToMM = 0.0254;
|
|
38
|
+
export const MMToPx = 3.779276;
|
|
39
|
+
export const PxToMM = 0.2645833;
|
|
26
40
|
export const portWidth = 20;
|
|
27
41
|
export const portHeight = 2;
|
|
28
|
-
export const
|
|
29
|
-
export const
|
|
42
|
+
export const defaultGridSizeUnits = MilsToMM * 100;
|
|
43
|
+
export const defaultZoomScale = 2.5;
|
|
44
|
+
export const fontDisplayScale = 0.032;
|
|
45
|
+
export const defaultSymbolLineWidth = MilsToMM * 6;
|
|
46
|
+
export const defaultWireLineWidth = MilsToMM * 6;
|
|
47
|
+
export const defaultPinNameTextSize = 40;
|
|
48
|
+
export const defaultPinIdTextSize = 30;
|
|
49
|
+
export const CustomSymbolPinTextSize = defaultPinNameTextSize;
|
|
50
|
+
export const CustomSymbolPinIdSize = defaultPinIdTextSize;
|
|
51
|
+
export const CustomSymbolRefDesSize = 50;
|
|
52
|
+
export const CustomSymbolParamTextSize = 40;
|
|
53
|
+
export const defaultFrameTitleTextSize = 60;
|
|
54
|
+
export const displayUnits = LengthUnit.mils;
|
|
55
|
+
export const defaultFont = 'Arial';
|
|
56
|
+
export const defaultFontBold = 'Arial';
|
|
30
57
|
export const defaultFontSize = 10;
|
|
31
|
-
export const
|
|
32
|
-
export const
|
|
33
|
-
export const
|
|
34
|
-
export const
|
|
58
|
+
export const junctionSize = MilsToMM * 20;
|
|
59
|
+
export const PortArrowSize = MilsToMM * 50;
|
|
60
|
+
export const PortPaddingHorizontal = MilsToMM * 10;
|
|
61
|
+
export const PortPaddingVertical = MilsToMM * 10;
|
|
62
|
+
export const ColorScheme = {
|
|
63
|
+
BodyColor: 'rgb(255, 255, 194)',
|
|
64
|
+
JunctionColor: 'rgba(0, 132, 0)',
|
|
65
|
+
WireColor: 'rgb(0, 132, 0)',
|
|
66
|
+
PinLineColor: '#333',
|
|
67
|
+
PinNameColor: '#333',
|
|
68
|
+
};
|
|
35
69
|
export var ComponentTypes;
|
|
36
70
|
(function (ComponentTypes) {
|
|
37
71
|
ComponentTypes["gnd"] = "gnd";
|
package/dist/esm/helpers.mjs
CHANGED
|
@@ -13,6 +13,7 @@ import { MainLexer } from "./lexer.mjs";
|
|
|
13
13
|
import { CircuitScriptParser } from "./antlr/CircuitScriptParser.mjs";
|
|
14
14
|
import { prepareTokens, SemanticTokensVisitor } from "./SemanticTokenVisitor.mjs";
|
|
15
15
|
import path from "path";
|
|
16
|
+
import { LengthUnit, MilsToMM, PxToMM } from "./globals.mjs";
|
|
16
17
|
export var JSModuleType;
|
|
17
18
|
(function (JSModuleType) {
|
|
18
19
|
JSModuleType["CommonJs"] = "cjs";
|
|
@@ -163,7 +164,10 @@ export function renderScript(scriptData, outputPath, options) {
|
|
|
163
164
|
const { tree, parser, hasParseError, hasError, parserTimeTaken, lexerTimeTaken } = parseFileWithVisitor(visitor, scriptData);
|
|
164
165
|
showStats && console.log('Lexing took:', lexerTimeTaken);
|
|
165
166
|
showStats && console.log('Parsing took:', parserTimeTaken);
|
|
166
|
-
|
|
167
|
+
if (dumpNets) {
|
|
168
|
+
const nets = visitor.dumpNets();
|
|
169
|
+
console.log(nets);
|
|
170
|
+
}
|
|
167
171
|
dumpData && writeFileSync('dump/tree.lisp', tree.toStringTree(null, parser));
|
|
168
172
|
dumpData && writeFileSync('dump/raw-parser.txt', visitor.logger.dump());
|
|
169
173
|
if (hasError || hasParseError) {
|
|
@@ -254,3 +258,36 @@ export function getPackageVersion() {
|
|
|
254
258
|
const { version } = packageJson;
|
|
255
259
|
return version;
|
|
256
260
|
}
|
|
261
|
+
export class UnitDimension {
|
|
262
|
+
type;
|
|
263
|
+
value;
|
|
264
|
+
constructor(value, type = LengthUnit.mils) {
|
|
265
|
+
this.value = value;
|
|
266
|
+
this.type = type;
|
|
267
|
+
}
|
|
268
|
+
getMM() {
|
|
269
|
+
switch (this.type) {
|
|
270
|
+
case LengthUnit.mm:
|
|
271
|
+
return this.value;
|
|
272
|
+
case LengthUnit.mils:
|
|
273
|
+
return this.value * MilsToMM;
|
|
274
|
+
case LengthUnit.px:
|
|
275
|
+
return this.value * PxToMM;
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
static mm(value) {
|
|
279
|
+
return new UnitDimension(value, LengthUnit.mm);
|
|
280
|
+
}
|
|
281
|
+
static mils(value) {
|
|
282
|
+
return new UnitDimension(value, LengthUnit.mils);
|
|
283
|
+
}
|
|
284
|
+
static px(value) {
|
|
285
|
+
return new UnitDimension(value, LengthUnit.px);
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
export function milsToMM(value) {
|
|
289
|
+
return value * MilsToMM;
|
|
290
|
+
}
|
|
291
|
+
export function pxToMM(value) {
|
|
292
|
+
return value * PxToMM;
|
|
293
|
+
}
|
package/dist/esm/layout.mjs
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import { Graph, alg } from '@dagrejs/graphlib';
|
|
2
|
-
import { SymbolCustom, SymbolDrawing, SymbolFactory, SymbolPlaceholder, SymbolText } from "./draw_symbols.mjs";
|
|
2
|
+
import { SymbolCustom, SymbolDrawing, SymbolFactory, SymbolCustomModule, SymbolPlaceholder, SymbolText } from "./draw_symbols.mjs";
|
|
3
3
|
import { FrameAction, SequenceAction } from "./objects/ExecutionScope.mjs";
|
|
4
|
-
import { GlobalNames, ParamKeys } from './globals.mjs';
|
|
4
|
+
import { defaultFrameTitleTextSize, defaultGridSizeUnits, GlobalNames, ParamKeys, WireAutoDirection } from './globals.mjs';
|
|
5
5
|
import { NumericValue } from './objects/ParamDefinition.mjs';
|
|
6
6
|
import { Geometry } from './geometry.mjs';
|
|
7
7
|
import { Logger } from './logger.mjs';
|
|
8
8
|
import { Frame, FrameParamKeys, FramePlotDirection } from './objects/Frame.mjs';
|
|
9
|
-
import { getBoundsSize, printBounds, resizeBounds, resizeToNearestGrid, toNearestGrid } from './utils.mjs';
|
|
9
|
+
import { getBoundsSize, printBounds, resizeBounds, resizeToNearestGrid, roundValue, toNearestGrid } from './utils.mjs';
|
|
10
10
|
import { Direction } from './objects/types.mjs';
|
|
11
|
+
import { milsToMM, UnitDimension } from './helpers.mjs';
|
|
11
12
|
export class LayoutEngine {
|
|
12
13
|
logger;
|
|
13
14
|
placeSubgraphVersion = 2;
|
|
@@ -184,7 +185,7 @@ export class LayoutEngine {
|
|
|
184
185
|
}
|
|
185
186
|
placeAndSizeFrame(frame, level = 0) {
|
|
186
187
|
const innerFrames = frame.innerItems;
|
|
187
|
-
const gridSize =
|
|
188
|
+
const gridSize = defaultGridSizeUnits;
|
|
188
189
|
let accumX = 0;
|
|
189
190
|
let accumY = 0;
|
|
190
191
|
const boundPoints = [];
|
|
@@ -324,7 +325,7 @@ export class LayoutEngine {
|
|
|
324
325
|
tmpFrame.containsTitle = true;
|
|
325
326
|
tmpFrame.subgraphId = title.replace(/\s/g, "_");
|
|
326
327
|
const textObject = new RenderText(title);
|
|
327
|
-
textObject.fontSize =
|
|
328
|
+
textObject.fontSize = defaultFrameTitleTextSize;
|
|
328
329
|
textObject.fontWeight = 'bold';
|
|
329
330
|
textObject.symbol.refreshDrawing();
|
|
330
331
|
tmpFrame.innerItems.push(textObject);
|
|
@@ -386,7 +387,12 @@ export class LayoutEngine {
|
|
|
386
387
|
}
|
|
387
388
|
else {
|
|
388
389
|
const symbolPinDefinitions = generateLayoutPinDefinition(component);
|
|
389
|
-
|
|
390
|
+
if (component.typeProp === 'module') {
|
|
391
|
+
tmpSymbol = new SymbolCustomModule(symbolPinDefinitions);
|
|
392
|
+
}
|
|
393
|
+
else {
|
|
394
|
+
tmpSymbol = new SymbolCustom(symbolPinDefinitions);
|
|
395
|
+
}
|
|
390
396
|
}
|
|
391
397
|
applyComponentParamsToSymbol(typeProp, component, tmpSymbol);
|
|
392
398
|
let didSetAngle = false;
|
|
@@ -403,7 +409,7 @@ export class LayoutEngine {
|
|
|
403
409
|
component.parameters.get('flipY');
|
|
404
410
|
}
|
|
405
411
|
if (tmpSymbol instanceof SymbolCustom && widthProp) {
|
|
406
|
-
tmpSymbol.bodyWidth = widthProp;
|
|
412
|
+
tmpSymbol.bodyWidth = milsToMM(widthProp);
|
|
407
413
|
}
|
|
408
414
|
if (!didSetAngle && component.parameters.has('_addDirection')) {
|
|
409
415
|
tmpSymbol.refreshDrawing(false);
|
|
@@ -584,6 +590,10 @@ export class LayoutEngine {
|
|
|
584
590
|
this.placeNodeAtPosition(0, 0, node1, 1);
|
|
585
591
|
return;
|
|
586
592
|
}
|
|
593
|
+
let fixedNode;
|
|
594
|
+
let fixedNodePin;
|
|
595
|
+
let floatingNode;
|
|
596
|
+
let floatingNodePin;
|
|
587
597
|
subgraphEdges.forEach(edge => {
|
|
588
598
|
const [nodeId1, pin1, nodeId2, pin2] = graph.edge(edge);
|
|
589
599
|
const [, node1] = graph.node(nodeId1);
|
|
@@ -596,10 +606,6 @@ export class LayoutEngine {
|
|
|
596
606
|
originNodes.push(node1);
|
|
597
607
|
originNodeGroups.set(node1.toString(), [node1]);
|
|
598
608
|
}
|
|
599
|
-
let fixedNode;
|
|
600
|
-
let fixedNodePin;
|
|
601
|
-
let floatingNode;
|
|
602
|
-
let floatingNodePin;
|
|
603
609
|
this.print('edge:', '[', node1, pin1, node1.isFloating, ']', '[', node2, pin2, node2.isFloating, ']');
|
|
604
610
|
if (!node1.isFloating && node2.isFloating) {
|
|
605
611
|
fixedNode = node1;
|
|
@@ -655,12 +661,17 @@ export class LayoutEngine {
|
|
|
655
661
|
}
|
|
656
662
|
[node1, node2].forEach(item => {
|
|
657
663
|
if (item instanceof RenderWire && item.isEndAutoLength()) {
|
|
658
|
-
this.print('auto length wire', item);
|
|
659
664
|
const [instance, pin] = item.getEndAuto();
|
|
660
665
|
const [, targetNode] = graph.node(instance.instanceName);
|
|
666
|
+
this.print('wire auto length to target:', instance, pin);
|
|
661
667
|
if (targetNode.isFloating) {
|
|
662
668
|
throw "Cannot create auto wire with floating node! Wire id: " + item.id + " to node " + instance + " pin " + pin;
|
|
663
669
|
}
|
|
670
|
+
const targetOriginNode = findOriginNode(targetNode);
|
|
671
|
+
const itemOriginNode = findOriginNode(item);
|
|
672
|
+
if (targetOriginNode !== itemOriginNode) {
|
|
673
|
+
throw "Wire auto length failed. Please specify a fixed wire length.";
|
|
674
|
+
}
|
|
664
675
|
const [untilX, untilY] = getNodePositionAtPin(targetNode, pin);
|
|
665
676
|
item.setEndAuto(untilX, untilY);
|
|
666
677
|
}
|
|
@@ -824,25 +835,27 @@ export class LayoutEngine {
|
|
|
824
835
|
}
|
|
825
836
|
}
|
|
826
837
|
function getNodePositionAtPin(item, pin) {
|
|
838
|
+
let x = 0;
|
|
839
|
+
let y = 0;
|
|
827
840
|
if (item instanceof RenderComponent) {
|
|
828
841
|
const pinPosition = item.symbol.pinPosition(pin);
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
item.y + pinPosition.y
|
|
832
|
-
];
|
|
842
|
+
x = item.x + pinPosition.x;
|
|
843
|
+
y = item.y + pinPosition.y;
|
|
833
844
|
}
|
|
834
845
|
else if (item instanceof RenderWire) {
|
|
835
846
|
if (pin === 0) {
|
|
836
|
-
|
|
847
|
+
x = item.x;
|
|
848
|
+
y = item.y;
|
|
837
849
|
}
|
|
838
850
|
else {
|
|
839
851
|
const wireEnd = item.getWireEnd();
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
item.y + wireEnd.y
|
|
843
|
-
];
|
|
852
|
+
x = item.x + wireEnd.x;
|
|
853
|
+
y = item.y + wireEnd.y;
|
|
844
854
|
}
|
|
845
855
|
}
|
|
856
|
+
return [
|
|
857
|
+
roundValue(x), roundValue(y)
|
|
858
|
+
];
|
|
846
859
|
}
|
|
847
860
|
function getNeighbours(graph, nodeIds) {
|
|
848
861
|
return nodeIds.reduce((accum, nodeId) => {
|
|
@@ -868,11 +881,13 @@ function generateLayoutPinDefinition(component) {
|
|
|
868
881
|
if (component.arrangeProps === null) {
|
|
869
882
|
for (let i = 0; i < existingPinIds.length; i++) {
|
|
870
883
|
const pinPosition = Math.floor(i / 2);
|
|
884
|
+
const pin = pins.get(existingPinIds[i]);
|
|
871
885
|
symbolPinDefinitions.push({
|
|
872
886
|
side: (i % 2 === 0) ? "left" : "right",
|
|
873
887
|
pinId: existingPinIds[i],
|
|
874
|
-
text:
|
|
888
|
+
text: pin.name,
|
|
875
889
|
position: pinPosition,
|
|
890
|
+
pinType: pin.pinType,
|
|
876
891
|
});
|
|
877
892
|
}
|
|
878
893
|
}
|
|
@@ -888,11 +903,13 @@ function generateLayoutPinDefinition(component) {
|
|
|
888
903
|
}
|
|
889
904
|
useItems.forEach(pinId => {
|
|
890
905
|
if (existingPinIds.indexOf(pinId) !== -1) {
|
|
906
|
+
const pin = pins.get(pinId);
|
|
891
907
|
symbolPinDefinitions.push({
|
|
892
908
|
side: key,
|
|
893
909
|
pinId: pinId,
|
|
894
|
-
text:
|
|
895
|
-
position:
|
|
910
|
+
text: pin.name,
|
|
911
|
+
position: pin.position,
|
|
912
|
+
pinType: pin.pinType,
|
|
896
913
|
});
|
|
897
914
|
addedPins.push(pinId);
|
|
898
915
|
}
|
|
@@ -1013,19 +1030,26 @@ export class RenderWire extends RenderObject {
|
|
|
1013
1030
|
this.segments.forEach(segment => {
|
|
1014
1031
|
const { direction, value } = segment;
|
|
1015
1032
|
let didAddPoint = false;
|
|
1033
|
+
let useValue;
|
|
1034
|
+
if (value instanceof UnitDimension) {
|
|
1035
|
+
useValue = value.getMM();
|
|
1036
|
+
}
|
|
1037
|
+
else {
|
|
1038
|
+
useValue = value;
|
|
1039
|
+
}
|
|
1016
1040
|
if (direction === Direction.Down) {
|
|
1017
|
-
tmpY +=
|
|
1041
|
+
tmpY += useValue;
|
|
1018
1042
|
}
|
|
1019
1043
|
else if (direction === Direction.Up) {
|
|
1020
|
-
tmpY -=
|
|
1044
|
+
tmpY -= useValue;
|
|
1021
1045
|
}
|
|
1022
1046
|
else if (direction === Direction.Left) {
|
|
1023
|
-
tmpX -=
|
|
1047
|
+
tmpX -= useValue;
|
|
1024
1048
|
}
|
|
1025
1049
|
else if (direction === Direction.Right) {
|
|
1026
|
-
tmpX +=
|
|
1050
|
+
tmpX += useValue;
|
|
1027
1051
|
}
|
|
1028
|
-
else if (direction ===
|
|
1052
|
+
else if (direction === WireAutoDirection.Auto || direction === WireAutoDirection.Auto_) {
|
|
1029
1053
|
const { valueXY = [0, 0] } = segment;
|
|
1030
1054
|
const tmpPoints = this.getAutoPoints(valueXY, direction);
|
|
1031
1055
|
tmpPoints.forEach(point => {
|
|
@@ -1044,9 +1068,11 @@ export class RenderWire extends RenderObject {
|
|
|
1044
1068
|
this.points = points;
|
|
1045
1069
|
}
|
|
1046
1070
|
getAutoPoints(value, direction) {
|
|
1047
|
-
const
|
|
1048
|
-
const
|
|
1049
|
-
|
|
1071
|
+
const valueX = roundValue(value[0]);
|
|
1072
|
+
const valueY = roundValue(value[1]);
|
|
1073
|
+
const inQuadrant = Geometry.getQuadrant(valueX, valueY);
|
|
1074
|
+
const [dx, dy] = [valueX, valueY];
|
|
1075
|
+
if (direction === WireAutoDirection.Auto) {
|
|
1050
1076
|
switch (inQuadrant) {
|
|
1051
1077
|
case 0:
|
|
1052
1078
|
case 2:
|
|
@@ -1056,7 +1082,7 @@ export class RenderWire extends RenderObject {
|
|
|
1056
1082
|
return [[0, dy], [dx, 0]];
|
|
1057
1083
|
}
|
|
1058
1084
|
}
|
|
1059
|
-
else if (direction ===
|
|
1085
|
+
else if (direction === WireAutoDirection.Auto_) {
|
|
1060
1086
|
switch (inQuadrant) {
|
|
1061
1087
|
case 0:
|
|
1062
1088
|
case 2:
|
|
@@ -1091,17 +1117,24 @@ export class RenderWire extends RenderObject {
|
|
|
1091
1117
|
let tmpY = this.y;
|
|
1092
1118
|
excludeLastSegment.forEach(segment => {
|
|
1093
1119
|
const { direction, value } = segment;
|
|
1120
|
+
let useValue;
|
|
1121
|
+
if (value instanceof UnitDimension) {
|
|
1122
|
+
useValue = value.getMM();
|
|
1123
|
+
}
|
|
1124
|
+
else {
|
|
1125
|
+
useValue = value;
|
|
1126
|
+
}
|
|
1094
1127
|
if (direction === Direction.Down) {
|
|
1095
|
-
tmpY +=
|
|
1128
|
+
tmpY += useValue;
|
|
1096
1129
|
}
|
|
1097
1130
|
else if (direction === Direction.Up) {
|
|
1098
|
-
tmpY -=
|
|
1131
|
+
tmpY -= useValue;
|
|
1099
1132
|
}
|
|
1100
1133
|
else if (direction === Direction.Left) {
|
|
1101
|
-
tmpX -=
|
|
1134
|
+
tmpX -= useValue;
|
|
1102
1135
|
}
|
|
1103
1136
|
else if (direction === Direction.Right) {
|
|
1104
|
-
tmpX +=
|
|
1137
|
+
tmpX += useValue;
|
|
1105
1138
|
}
|
|
1106
1139
|
});
|
|
1107
1140
|
let useValue = null;
|
|
@@ -1120,8 +1153,8 @@ export class RenderWire extends RenderObject {
|
|
|
1120
1153
|
case Direction.Down:
|
|
1121
1154
|
useValue = tmpY - untilY;
|
|
1122
1155
|
break;
|
|
1123
|
-
case
|
|
1124
|
-
case
|
|
1156
|
+
case WireAutoDirection.Auto:
|
|
1157
|
+
case WireAutoDirection.Auto_:
|
|
1125
1158
|
valueXY = [
|
|
1126
1159
|
untilX - tmpX,
|
|
1127
1160
|
untilY - tmpY,
|
|
@@ -1189,10 +1222,10 @@ export class RenderFrame extends RenderObject {
|
|
|
1189
1222
|
innerItems = [];
|
|
1190
1223
|
translateX = 0;
|
|
1191
1224
|
translateY = 0;
|
|
1192
|
-
padding =
|
|
1193
|
-
gap =
|
|
1225
|
+
padding = milsToMM(100);
|
|
1226
|
+
gap = milsToMM(100);
|
|
1194
1227
|
direction = FramePlotDirection.Column;
|
|
1195
|
-
borderWidth =
|
|
1228
|
+
borderWidth = 5;
|
|
1196
1229
|
subgraphId = "";
|
|
1197
1230
|
type;
|
|
1198
1231
|
containsTitle = false;
|