circuitscript 0.0.22 → 0.0.25
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 +487 -0
- package/dist/cjs/SemanticTokenVisitor.js +218 -0
- package/dist/cjs/SymbolValidatorVisitor.js +233 -0
- package/dist/cjs/antlr/CircuitScriptLexer.js +302 -0
- package/dist/cjs/antlr/CircuitScriptParser.js +5128 -0
- package/dist/cjs/antlr/CircuitScriptVisitor.js +7 -0
- package/dist/cjs/draw_symbols.js +819 -0
- package/dist/cjs/execute.js +778 -0
- package/{src/export.ts → dist/cjs/export.js} +34 -56
- package/dist/cjs/fonts.js +4 -0
- package/dist/cjs/geometry.js +450 -0
- package/dist/cjs/globals.js +60 -0
- package/dist/cjs/helpers.js +269 -0
- package/dist/cjs/index.js +31 -0
- package/{src/layout.ts → dist/cjs/layout.js} +421 -1002
- package/dist/cjs/lexer.js +111 -0
- package/dist/cjs/logger.js +17 -0
- package/dist/cjs/main.js +82 -0
- package/dist/cjs/objects/ClassComponent.js +145 -0
- package/dist/cjs/objects/ExecutionScope.js +135 -0
- package/dist/cjs/objects/Frame.js +22 -0
- package/{src/objects/Net.ts → dist/cjs/objects/Net.js} +9 -24
- package/dist/cjs/objects/ParamDefinition.js +42 -0
- package/dist/cjs/objects/PinDefinition.js +31 -0
- package/dist/cjs/objects/PinTypes.js +11 -0
- package/dist/cjs/objects/Wire.js +9 -0
- package/dist/cjs/objects/types.js +15 -0
- package/dist/cjs/parser.js +70 -0
- package/dist/cjs/regenerate-tests.js +23 -0
- package/dist/cjs/render.js +155 -0
- package/{src/server.ts → dist/cjs/server.js} +15 -21
- package/dist/cjs/sizing.js +105 -0
- package/{src/utils.ts → dist/cjs/utils.js} +25 -35
- package/dist/cjs/validate.js +81 -0
- package/dist/cjs/visitor.js +844 -0
- package/dist/esm/BaseVisitor.mjs +488 -0
- package/dist/esm/SemanticTokenVisitor.mjs +215 -0
- package/dist/esm/SymbolValidatorVisitor.mjs +222 -0
- package/dist/esm/antlr/CircuitScriptLexer.mjs +276 -0
- package/dist/esm/antlr/CircuitScriptParser.mjs +5038 -0
- package/{build/src/antlr/CircuitScriptVisitor.js → dist/esm/antlr/CircuitScriptVisitor.mjs} +8 -3
- package/{build/src/draw_symbols.js → dist/esm/draw_symbols.mjs} +78 -33
- package/{build/src/execute.js → dist/esm/execute.mjs} +59 -60
- package/{build/src/export.js → dist/esm/export.mjs} +2 -2
- package/{build/src/geometry.js → dist/esm/geometry.mjs} +31 -15
- package/dist/esm/helpers.mjs +252 -0
- package/dist/esm/index.mjs +15 -0
- package/{build/src/layout.js → dist/esm/layout.mjs} +19 -11
- package/{build/src/lexer.js → dist/esm/lexer.mjs} +10 -10
- package/{build/src/main.js → dist/esm/main.mjs} +9 -14
- package/{build/src/objects/ClassComponent.js → dist/esm/objects/ClassComponent.mjs} +6 -3
- package/{build/src/objects/ExecutionScope.js → dist/esm/objects/ExecutionScope.mjs} +1 -0
- package/{build/src/objects/PinDefinition.js → dist/esm/objects/PinDefinition.mjs} +1 -1
- package/dist/esm/objects/types.mjs +12 -0
- package/dist/esm/parser.mjs +64 -0
- package/{build/src/regenerate-tests.js → dist/esm/regenerate-tests.mjs} +1 -1
- package/{build/src/render.js → dist/esm/render.mjs} +7 -24
- package/{build/src/sizing.js → dist/esm/sizing.mjs} +22 -8
- package/{src/main.ts → dist/esm/validate.mjs} +31 -62
- package/dist/esm/visitor.mjs +838 -0
- package/dist/types/BaseVisitor.d.ts +69 -0
- package/dist/types/SemanticTokenVisitor.d.ts +36 -0
- package/dist/types/SymbolValidatorVisitor.d.ts +61 -0
- package/{build/src → dist/types}/antlr/CircuitScriptLexer.d.ts +28 -27
- package/dist/types/antlr/CircuitScriptParser.d.ts +719 -0
- package/{build/src → dist/types}/antlr/CircuitScriptVisitor.d.ts +69 -59
- package/{build/src → dist/types}/draw_symbols.d.ts +11 -2
- package/{build/src → dist/types}/execute.d.ts +6 -9
- package/{build/src → dist/types}/geometry.d.ts +5 -1
- package/dist/types/helpers.d.ts +40 -0
- package/dist/types/index.d.ts +15 -0
- package/{build/src → dist/types}/layout.d.ts +10 -10
- package/{build/src → dist/types}/lexer.d.ts +2 -2
- package/{build/src → dist/types}/objects/ClassComponent.d.ts +2 -2
- package/{build/src → dist/types}/objects/ExecutionScope.d.ts +4 -1
- package/{build/src → dist/types}/objects/PinDefinition.d.ts +1 -1
- package/{build/src → dist/types}/objects/types.d.ts +5 -0
- package/dist/types/parser.d.ts +25 -0
- package/{build/src → dist/types}/render.d.ts +1 -1
- package/{build/src → dist/types}/sizing.d.ts +3 -1
- package/dist/types/validate.d.ts +2 -0
- package/dist/types/visitor.d.ts +80 -0
- package/libs/lib.cst +0 -2
- package/package.json +38 -15
- package/.editorconfig +0 -15
- package/.eslintignore +0 -1
- package/.eslintrc.json +0 -27
- package/.gitlab-ci.yml +0 -81
- package/.prettierignore +0 -8
- package/.prettierrc +0 -16
- package/__tests__/expectedResults.ts +0 -657
- package/__tests__/helpers.ts +0 -82
- package/__tests__/parseScripts.ts +0 -593
- package/__tests__/renderData/script1.cst +0 -58
- package/__tests__/renderData/script1.cst.svg +0 -1
- package/__tests__/renderData/script2.cst +0 -16
- package/__tests__/renderData/script2.cst.svg +0 -1
- package/__tests__/renderData/script3.cst +0 -30
- package/__tests__/renderData/script3.cst.svg +0 -1
- package/__tests__/renderData/script4.cst +0 -54
- package/__tests__/renderData/script4.cst.svg +0 -1
- package/__tests__/renderData/script5.cst +0 -23
- package/__tests__/renderData/script5.cst.svg +0 -1
- package/__tests__/renderData/script6.cst +0 -28
- package/__tests__/renderData/script6.cst.svg +0 -1
- package/__tests__/renderData/script7.cst +0 -26
- package/__tests__/renderData/script7.cst.svg +0 -1
- package/__tests__/renderData/script8.cst +0 -37
- package/__tests__/renderData/script8.cst.svg +0 -1
- package/__tests__/testCLI.ts +0 -68
- package/__tests__/testMathOps.ts +0 -36
- package/__tests__/testMergeWires.ts +0 -141
- package/__tests__/testParse.ts +0 -263
- package/__tests__/testRender.ts +0 -38
- package/build/src/antlr/CircuitScriptLexer.js +0 -287
- package/build/src/antlr/CircuitScriptParser.d.ts +0 -674
- package/build/src/antlr/CircuitScriptParser.js +0 -4841
- package/build/src/helpers.d.ts +0 -1
- package/build/src/helpers.js +0 -73
- package/build/src/objects/types.js +0 -6
- package/build/src/parser.js +0 -69
- package/build/src/visitor.d.ts +0 -133
- package/build/src/visitor.js +0 -1154
- package/documentation.md +0 -238
- package/examples/example_arduino_uno.cst +0 -1146
- package/examples/example_garden_pump.cst +0 -567
- package/examples/lib.cst +0 -185
- package/jest.config.js +0 -23
- package/refresh.html +0 -42
- package/server.cjs +0 -50
- package/src/antlr/CircuitScript.g4 +0 -209
- package/src/antlr/CircuitScriptLexer.ts +0 -317
- package/src/antlr/CircuitScriptParser.ts +0 -4979
- package/src/antlr/CircuitScriptVisitor.ts +0 -420
- package/src/draw_symbols.ts +0 -1085
- package/src/execute.ts +0 -1227
- package/src/fonts.ts +0 -1
- package/src/geometry.ts +0 -638
- package/src/globals.ts +0 -67
- package/src/helpers.ts +0 -114
- package/src/lexer.ts +0 -151
- package/src/logger.ts +0 -17
- package/src/objects/ClassComponent.ts +0 -223
- package/src/objects/ExecutionScope.ts +0 -201
- package/src/objects/Frame.ts +0 -20
- package/src/objects/ParamDefinition.ts +0 -49
- package/src/objects/PinDefinition.ts +0 -49
- package/src/objects/PinTypes.ts +0 -7
- package/src/objects/Wire.ts +0 -19
- package/src/objects/types.ts +0 -66
- package/src/parser.ts +0 -106
- package/src/regenerate-tests.ts +0 -25
- package/src/render.ts +0 -260
- package/src/sizing.ts +0 -96
- package/src/visitor.ts +0 -1691
- package/tsconfig.json +0 -27
- package/tsconfig.release.json +0 -8
- /package/{build/src/fonts.js → dist/esm/fonts.mjs} +0 -0
- /package/{build/src/globals.js → dist/esm/globals.mjs} +0 -0
- /package/{build/src/logger.js → dist/esm/logger.mjs} +0 -0
- /package/{build/src/objects/Frame.js → dist/esm/objects/Frame.mjs} +0 -0
- /package/{build/src/objects/Net.js → dist/esm/objects/Net.mjs} +0 -0
- /package/{build/src/objects/ParamDefinition.js → dist/esm/objects/ParamDefinition.mjs} +0 -0
- /package/{build/src/objects/PinTypes.js → dist/esm/objects/PinTypes.mjs} +0 -0
- /package/{build/src/objects/Wire.js → dist/esm/objects/Wire.mjs} +0 -0
- /package/{build/src/server.js → dist/esm/server.mjs} +0 -0
- /package/{build/src/utils.js → dist/esm/utils.mjs} +0 -0
- /package/{build/src → dist/types}/export.d.ts +0 -0
- /package/{build/src → dist/types}/fonts.d.ts +0 -0
- /package/{build/src → dist/types}/globals.d.ts +0 -0
- /package/{build/src → dist/types}/logger.d.ts +0 -0
- /package/{build/src → dist/types}/main.d.ts +0 -0
- /package/{build/src → dist/types}/objects/Frame.d.ts +0 -0
- /package/{build/src → dist/types}/objects/Net.d.ts +0 -0
- /package/{build/src → dist/types}/objects/ParamDefinition.d.ts +0 -0
- /package/{build/src → dist/types}/objects/PinTypes.d.ts +0 -0
- /package/{build/src → dist/types}/objects/Wire.d.ts +0 -0
- /package/{build/src → dist/types}/regenerate-tests.d.ts +0 -0
- /package/{build/src → dist/types}/server.d.ts +0 -0
- /package/{build/src → dist/types}/utils.d.ts +0 -0
package/src/geometry.ts
DELETED
|
@@ -1,638 +0,0 @@
|
|
|
1
|
-
import Flatten from '@flatten-js/core'
|
|
2
|
-
import { measureTextSize2 } from './sizing.js';
|
|
3
|
-
import { defaultFont } from './globals.js';
|
|
4
|
-
import { Box } from '@svgdotjs/svg.js';
|
|
5
|
-
import { NumericValue } from './objects/ParamDefinition.js';
|
|
6
|
-
|
|
7
|
-
export type Segment = Flatten.Segment;
|
|
8
|
-
export type Polygon = Flatten.Polygon;
|
|
9
|
-
export type Multiline = Flatten.Multiline;
|
|
10
|
-
export type Line = Flatten.Line;
|
|
11
|
-
|
|
12
|
-
export type Arc = Flatten.Arc;
|
|
13
|
-
|
|
14
|
-
export type Feature = Segment | Polygon | Label | Arc | Multiline;
|
|
15
|
-
|
|
16
|
-
export type LabelStyle = {
|
|
17
|
-
font?: string,
|
|
18
|
-
fontSize?: number,
|
|
19
|
-
fontWeight?: string,
|
|
20
|
-
angle?: number,
|
|
21
|
-
|
|
22
|
-
anchor?: HorizontalAlign.Left | HorizontalAlign.Middle | HorizontalAlign.Right, // Horizontal anchor
|
|
23
|
-
vanchor?: VerticalAlign.Top | VerticalAlign.Middle | VerticalAlign.Bottom, // Vertical anchor
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export class Label extends Flatten.Polygon {
|
|
27
|
-
|
|
28
|
-
id: string;
|
|
29
|
-
|
|
30
|
-
text: string;
|
|
31
|
-
|
|
32
|
-
anchorPoint: [number, number] = [0, 0];
|
|
33
|
-
|
|
34
|
-
boundingBox: { width: number, height: number } = { width: -1, height: -1 };
|
|
35
|
-
polygon: Polygon;
|
|
36
|
-
|
|
37
|
-
font = 'default';
|
|
38
|
-
|
|
39
|
-
style: LabelStyle;
|
|
40
|
-
|
|
41
|
-
textMeasurementBounds: Box;
|
|
42
|
-
|
|
43
|
-
get box() {
|
|
44
|
-
return this.polygon.box;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
constructor(id: string, text: string, anchorPoint: [number, number],
|
|
48
|
-
polygon: Flatten.Polygon, style: LabelStyle, bounds: Box) {
|
|
49
|
-
|
|
50
|
-
super(polygon.vertices);
|
|
51
|
-
|
|
52
|
-
this.id = id;
|
|
53
|
-
|
|
54
|
-
this.text = text;
|
|
55
|
-
this.anchorPoint = anchorPoint;
|
|
56
|
-
|
|
57
|
-
this.style = style;
|
|
58
|
-
|
|
59
|
-
this.boundingBox = polygon.box;
|
|
60
|
-
this.polygon = polygon;
|
|
61
|
-
|
|
62
|
-
this.textMeasurementBounds = bounds;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
static fromPoint(id: string, x: number, y: number,
|
|
66
|
-
text: string, style: LabelStyle): Label {
|
|
67
|
-
|
|
68
|
-
let useText: string;
|
|
69
|
-
if (typeof text === 'number'){
|
|
70
|
-
useText = (text as number).toString();
|
|
71
|
-
} else if (typeof text === 'object'
|
|
72
|
-
&& text instanceof NumericValue) {
|
|
73
|
-
useText = (text as NumericValue).toDisplayString();
|
|
74
|
-
} else if (typeof text === 'string'){
|
|
75
|
-
useText = text;
|
|
76
|
-
} else {
|
|
77
|
-
throw 'Invalid string passed into label';
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
const { fontSize = 10,
|
|
81
|
-
anchor = HorizontalAlign.Left,
|
|
82
|
-
vanchor = VerticalAlign.Bottom,
|
|
83
|
-
fontWeight = 'regular',
|
|
84
|
-
} = style ?? {};
|
|
85
|
-
|
|
86
|
-
// Determine the size of the text, this is needed to determine the
|
|
87
|
-
// bounding box of the text for layout purposes.
|
|
88
|
-
const { width, height, box } =
|
|
89
|
-
measureTextSize2(useText, defaultFont, fontSize, fontWeight,
|
|
90
|
-
anchor, vanchor);
|
|
91
|
-
|
|
92
|
-
// const polygonCoords =
|
|
93
|
-
// labelPolygonForAnchors(x, y, width, height, anchor, vanchor);
|
|
94
|
-
|
|
95
|
-
const polygonCoords = [
|
|
96
|
-
[box.x, box.y],
|
|
97
|
-
[box.x2, box.y],
|
|
98
|
-
[box.x2, box.y2],
|
|
99
|
-
[box.x, box.y2],
|
|
100
|
-
[box.x, box.y],
|
|
101
|
-
] as [x: number, y: number][];
|
|
102
|
-
|
|
103
|
-
const polygon = new Flatten.Polygon(polygonCoords);
|
|
104
|
-
|
|
105
|
-
// Create the bounds of the label
|
|
106
|
-
return new Label(id, useText, [x, y], polygon, style, box);
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
rotate(angle: number, origin: Flatten.Point): Label {
|
|
110
|
-
const polygonRotate = super.rotate(angle, origin);
|
|
111
|
-
return new Label(this.id, this.text, this.anchorPoint, polygonRotate,
|
|
112
|
-
this.style, this.textMeasurementBounds);
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
getLabelPosition(): [number, number] {
|
|
116
|
-
return this.anchorPoint;
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
export class GeometryProp {
|
|
121
|
-
name: string;
|
|
122
|
-
value: string | number;
|
|
123
|
-
constructor(name, value) {
|
|
124
|
-
this.name = name;
|
|
125
|
-
this.value = value;
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
export class Geometry {
|
|
130
|
-
|
|
131
|
-
static point(x: number, y: number): Flatten.Point {
|
|
132
|
-
return new Flatten.Point(x, y);
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
static line(x1: number, y1: number, x2: number, y2: number): Flatten.Line {
|
|
136
|
-
return new Flatten.Line(
|
|
137
|
-
Geometry.point(x1, y1),
|
|
138
|
-
Geometry.point(x2, y2)
|
|
139
|
-
)
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
static label(id: string, x: number, y: number, text: string, style: LabelStyle): Label {
|
|
143
|
-
return Label.fromPoint(id, x, y, text, style);
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
static segment(start: [number, number], end: [number, number]): Segment {
|
|
147
|
-
return new Flatten.Segment(
|
|
148
|
-
Geometry.point(start[0], start[1]),
|
|
149
|
-
Geometry.point(end[0], end[1])
|
|
150
|
-
);
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
static polygon(coords: [number, number][]): Polygon {
|
|
154
|
-
return new Flatten.Polygon(coords);
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
static multiline(coords: [number, number][]): Multiline {
|
|
158
|
-
const segments: Flatten.Segment[] = [];
|
|
159
|
-
|
|
160
|
-
// Create the segments
|
|
161
|
-
for (let i = 0; i < coords.length - 1; i++) {
|
|
162
|
-
segments.push(new Flatten.Segment(
|
|
163
|
-
Geometry.point(coords[i][0], coords[i][1]),
|
|
164
|
-
Geometry.point(coords[i + 1][0], coords[i + 1][1])
|
|
165
|
-
))
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
return new Flatten.Multiline(segments);
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
static arc(center: [x: number, y: number], radius: number,
|
|
172
|
-
startAngle: number, endAngle: number, sweepDirection: boolean): Arc {
|
|
173
|
-
// Angle should be in radians for Flatten library.
|
|
174
|
-
return new Flatten.Arc(Geometry.point(center[0], center[1]),
|
|
175
|
-
radius, startAngle, endAngle, sweepDirection);
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
static getCoords(item: Feature): [number, number][] {
|
|
179
|
-
const points = item.vertices.map(vertex => {
|
|
180
|
-
return [vertex.x, vertex.y];
|
|
181
|
-
}) as [number, number][];
|
|
182
|
-
|
|
183
|
-
return points;
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
static rotateDegs(feature: Feature, angleDegrees: number, center: [number, number]): Feature {
|
|
187
|
-
const angleRads = angleDegrees * Math.PI / 180;
|
|
188
|
-
return feature.rotate(angleRads, Geometry.point(center[0], center[1]));
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
static groupRotate(features: Feature[], angle: number, center: [number, number]): Feature[] {
|
|
192
|
-
const angleRads = angle * Math.PI / 180;
|
|
193
|
-
const rotateAboutPoint = Geometry.point(center[0], center[1]);
|
|
194
|
-
|
|
195
|
-
return features.map(feature => {
|
|
196
|
-
return feature.rotate(angleRads, rotateAboutPoint);
|
|
197
|
-
});
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
static groupBounds(features: Feature[]): {
|
|
201
|
-
start: [number, number], end: [number, number],
|
|
202
|
-
width: number, height: number
|
|
203
|
-
} {
|
|
204
|
-
|
|
205
|
-
let minX = Number.POSITIVE_INFINITY;
|
|
206
|
-
let minY = Number.POSITIVE_INFINITY;
|
|
207
|
-
|
|
208
|
-
let maxX = Number.NEGATIVE_INFINITY;
|
|
209
|
-
let maxY = Number.NEGATIVE_INFINITY;
|
|
210
|
-
|
|
211
|
-
features.forEach(feature => {
|
|
212
|
-
const box = feature.box;
|
|
213
|
-
|
|
214
|
-
if (feature instanceof Label
|
|
215
|
-
&& typeof feature.text === 'string'
|
|
216
|
-
&& feature.text.trim().length === 0) {
|
|
217
|
-
return;
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
if (box.xmin === undefined) {
|
|
221
|
-
throw "Invalid box!";
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
minX = Math.min(minX, box.xmin);
|
|
225
|
-
minY = Math.min(minY, box.ymin);
|
|
226
|
-
|
|
227
|
-
maxX = Math.max(maxX, box.xmax);
|
|
228
|
-
maxY = Math.max(maxY, box.ymax);
|
|
229
|
-
});
|
|
230
|
-
|
|
231
|
-
return {
|
|
232
|
-
start: [minX, minY],
|
|
233
|
-
end: [maxX, maxY],
|
|
234
|
-
width: maxX - minX,
|
|
235
|
-
height: maxY - minY,
|
|
236
|
-
}
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
static getType(feature: Feature): string {
|
|
240
|
-
if (feature instanceof Label) {
|
|
241
|
-
return 'label';
|
|
242
|
-
} else if (feature instanceof Flatten.Polygon) {
|
|
243
|
-
return 'polygon';
|
|
244
|
-
} else if (feature instanceof Flatten.Segment) {
|
|
245
|
-
return 'segment';
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
console.log('unknown type', feature);
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
static FullCircleRadians = 2 * Math.PI;
|
|
252
|
-
|
|
253
|
-
static featuresToPath(items: Feature[]):
|
|
254
|
-
{ path: string, isClosedPolygon: boolean } {
|
|
255
|
-
|
|
256
|
-
const paths = [];
|
|
257
|
-
let isClosedPolygon = false;
|
|
258
|
-
|
|
259
|
-
items.forEach(item => {
|
|
260
|
-
// Do not draw labels here
|
|
261
|
-
if (item instanceof Label) {
|
|
262
|
-
return;
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
const path = [];
|
|
266
|
-
|
|
267
|
-
if (item instanceof Flatten.Arc){
|
|
268
|
-
const x = item.center.x;
|
|
269
|
-
const y = item.center.y;
|
|
270
|
-
const radius = item.r as number;
|
|
271
|
-
|
|
272
|
-
let useEndAngle = item.endAngle;
|
|
273
|
-
let extraEnd = '';
|
|
274
|
-
if (item.startAngle === 0 && item.endAngle === Geometry.FullCircleRadians){
|
|
275
|
-
// detect as a circle and close the polygon
|
|
276
|
-
useEndAngle = 359.9999 * Math.PI/ 180;
|
|
277
|
-
isClosedPolygon = true;
|
|
278
|
-
extraEnd = ' Z'; // close the circle
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
// Assume angle is clockwise for now
|
|
282
|
-
const startPoint = getArcPointRadians(x, y, radius,
|
|
283
|
-
item.startAngle);
|
|
284
|
-
|
|
285
|
-
const endPoint = getArcPointRadians(x, y, radius,
|
|
286
|
-
useEndAngle);
|
|
287
|
-
|
|
288
|
-
paths.push('M ' + startPoint[0] + ' ' + startPoint[1]
|
|
289
|
-
+ 'A ' + radius + ' ' + radius + ' 0 1 1 '
|
|
290
|
-
+ endPoint[0] + ' ' + endPoint[1] + extraEnd);
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
} else {
|
|
294
|
-
const coords = Geometry.getCoords(item);
|
|
295
|
-
|
|
296
|
-
if (item instanceof Flatten.Polygon) {
|
|
297
|
-
isClosedPolygon = true;
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
for (let i = 0; i < coords.length; i++) {
|
|
301
|
-
const [x, y] = coords[i];
|
|
302
|
-
const command = (i === 0) ? 'M' : 'L';
|
|
303
|
-
path.push(`${command} ${x} ${y}`);
|
|
304
|
-
}
|
|
305
|
-
|
|
306
|
-
if (isClosedPolygon){
|
|
307
|
-
path.push('Z');
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
paths.push(path.join(' '));
|
|
311
|
-
}
|
|
312
|
-
});
|
|
313
|
-
|
|
314
|
-
return {
|
|
315
|
-
path: paths.join(" "),
|
|
316
|
-
isClosedPolygon,
|
|
317
|
-
}
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
static angle(dx: number, dy: number): number {
|
|
321
|
-
// Angle is relative to the x-axis going clockwise
|
|
322
|
-
const line = new Flatten.Segment(new Flatten.Point(0, 0), new Flatten.Point(dx, dy));
|
|
323
|
-
return line.slope * 180 / Math.PI;
|
|
324
|
-
}
|
|
325
|
-
|
|
326
|
-
static getQuadrant(dx: number, dy: number): number {
|
|
327
|
-
const angle = Geometry.angle(dx, dy);
|
|
328
|
-
return Number(Math.floor(angle/90));
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
static mergeWires(wirePoints: { x: number, y: number }[][]): {
|
|
332
|
-
intersectPoints: WirePointCount[],
|
|
333
|
-
segments: [x: number, y: number][][]
|
|
334
|
-
} {
|
|
335
|
-
// Merge wire segments to reduce overlaps and minimize segments
|
|
336
|
-
|
|
337
|
-
// This array stores segments that only intersect
|
|
338
|
-
// at the endpoints.
|
|
339
|
-
const existingSegments: Flatten.Segment[] = [];
|
|
340
|
-
|
|
341
|
-
wirePoints.forEach(points => {
|
|
342
|
-
|
|
343
|
-
const tmpPoints = points.map(pt => {
|
|
344
|
-
return new Flatten.Point(pt.x, pt.y);
|
|
345
|
-
});
|
|
346
|
-
|
|
347
|
-
// Generate segments from the points
|
|
348
|
-
for (let i = 0; i < tmpPoints.length - 1; i++) {
|
|
349
|
-
const pt1 = tmpPoints[i];
|
|
350
|
-
const pt2 = tmpPoints[i + 1];
|
|
351
|
-
|
|
352
|
-
// Array stores segments to be added to existing segments.
|
|
353
|
-
// The initial segment may be split into small segments,
|
|
354
|
-
// so this is maintained in a array
|
|
355
|
-
const newSegments = [
|
|
356
|
-
new Flatten.Segment(pt1, pt2)
|
|
357
|
-
];
|
|
358
|
-
|
|
359
|
-
// Check if the new segment overlaps other existing segments
|
|
360
|
-
for (let j = 0; j < existingSegments.length; j++) {
|
|
361
|
-
const currentSegment = existingSegments[j];
|
|
362
|
-
|
|
363
|
-
for (let k = 0; k < newSegments.length; k++) {
|
|
364
|
-
const newSegment = newSegments[k];
|
|
365
|
-
|
|
366
|
-
// Check if segments are equivalent
|
|
367
|
-
const segmentsAreSame = newSegment.equalTo(currentSegment) || newSegment.reverse().equalTo(currentSegment);
|
|
368
|
-
|
|
369
|
-
if (segmentsAreSame){
|
|
370
|
-
// remove segment from new segments
|
|
371
|
-
newSegments.splice(k, 1);
|
|
372
|
-
j = Math.max(0, j-1);
|
|
373
|
-
break;
|
|
374
|
-
}
|
|
375
|
-
|
|
376
|
-
const intersectPoints = currentSegment.intersect(newSegment);
|
|
377
|
-
if (intersectPoints.length > 0) {
|
|
378
|
-
|
|
379
|
-
// There should only be one possible intersection between two
|
|
380
|
-
// segments (that are not parallel).
|
|
381
|
-
|
|
382
|
-
// If they are parallel and overlapping, then there will be
|
|
383
|
-
// two intersection points
|
|
384
|
-
|
|
385
|
-
const endToEndIntersect = intersectPoints.length === 1 &&
|
|
386
|
-
(
|
|
387
|
-
currentSegment.end.equalTo(newSegment.start) || currentSegment.end.equalTo(newSegment.end) ||
|
|
388
|
-
currentSegment.start.equalTo(newSegment.start) || currentSegment.start.equalTo(newSegment.end)
|
|
389
|
-
);
|
|
390
|
-
|
|
391
|
-
if (endToEndIntersect) {
|
|
392
|
-
// If end to end intersect, then do nothing and continue
|
|
393
|
-
continue;
|
|
394
|
-
}
|
|
395
|
-
|
|
396
|
-
// There will be a max of 4 segments in this array.
|
|
397
|
-
const splitSegments: Flatten.Segment[] = [];
|
|
398
|
-
|
|
399
|
-
intersectPoints.forEach(intersectPoint => {
|
|
400
|
-
const splitResult1 = currentSegment.split(intersectPoint);
|
|
401
|
-
const splitResult2 = newSegment.split(intersectPoint);
|
|
402
|
-
|
|
403
|
-
// Merge all segments into same array
|
|
404
|
-
[...splitResult1, ...splitResult2].forEach(segment => {
|
|
405
|
-
if (segment !== null) {
|
|
406
|
-
|
|
407
|
-
const matchingSegmentIndex = splitSegments.findIndex(item => {
|
|
408
|
-
return item.equalTo(segment);
|
|
409
|
-
});
|
|
410
|
-
|
|
411
|
-
// Make sure segment does not already exist, to prevent duplicates.
|
|
412
|
-
// Ensure that segment does not match the current segment or new segment,
|
|
413
|
-
// this only ensures that segments that have been split are added!
|
|
414
|
-
if (matchingSegmentIndex === -1 &&
|
|
415
|
-
!segment.equalTo(currentSegment) && !segment.equalTo(newSegment)) {
|
|
416
|
-
splitSegments.push(segment);
|
|
417
|
-
}
|
|
418
|
-
}
|
|
419
|
-
});
|
|
420
|
-
});
|
|
421
|
-
|
|
422
|
-
// Find split segments that are part of currentSegment
|
|
423
|
-
const splitCurrentSegments: Flatten.Segment[] = [];
|
|
424
|
-
|
|
425
|
-
// Find split segments that are part of new segment
|
|
426
|
-
const splitNewSegments: Flatten.Segment[] = [];
|
|
427
|
-
|
|
428
|
-
splitSegments.forEach(segment => {
|
|
429
|
-
// Priority is given to current segment, since it is already in the existing
|
|
430
|
-
// segments array.
|
|
431
|
-
if (currentSegment.contains(segment.start) && currentSegment.contains(segment.end)) {
|
|
432
|
-
splitCurrentSegments.push(segment);
|
|
433
|
-
} else {
|
|
434
|
-
// If split segments not part of current segment, they must
|
|
435
|
-
// belong to the new segment!
|
|
436
|
-
splitNewSegments.push(segment);
|
|
437
|
-
}
|
|
438
|
-
});
|
|
439
|
-
|
|
440
|
-
replaceSegments(existingSegments, j, splitCurrentSegments);
|
|
441
|
-
replaceSegments(newSegments, k, splitNewSegments);
|
|
442
|
-
|
|
443
|
-
// Decrement j, so that the segment is parsed again
|
|
444
|
-
j = Math.max(0, j-1);
|
|
445
|
-
}
|
|
446
|
-
}
|
|
447
|
-
}
|
|
448
|
-
|
|
449
|
-
newSegments.forEach(segment => {
|
|
450
|
-
existingSegments.push(segment);
|
|
451
|
-
});
|
|
452
|
-
}
|
|
453
|
-
});
|
|
454
|
-
|
|
455
|
-
const trackWirePoints: [x: number, y: number][] = [];
|
|
456
|
-
|
|
457
|
-
existingSegments.forEach(segment => {
|
|
458
|
-
trackWirePoints.push([segment.start.x, segment.start.y]);
|
|
459
|
-
trackWirePoints.push([segment.end.x, segment.end.y]);
|
|
460
|
-
});
|
|
461
|
-
|
|
462
|
-
// Determine intersection points by going through each segment start
|
|
463
|
-
// and end points and accumulating on overlapping points.
|
|
464
|
-
const accumPoints = trackWirePoints.reduce((accum, point) => {
|
|
465
|
-
const found = accum.find(item => {
|
|
466
|
-
return item[0] === point[0] && item[1] === point[1]
|
|
467
|
-
});
|
|
468
|
-
|
|
469
|
-
if (found) {
|
|
470
|
-
found[2]++;
|
|
471
|
-
} else {
|
|
472
|
-
accum.push([point[0], point[1], 1]);
|
|
473
|
-
}
|
|
474
|
-
return accum;
|
|
475
|
-
|
|
476
|
-
}, [] as WirePointCount[]);
|
|
477
|
-
|
|
478
|
-
// Filter out points that have less than 3 intersections
|
|
479
|
-
const intersectPoints = accumPoints.reduce((accum, entry) => {
|
|
480
|
-
if (entry[2] > 2){
|
|
481
|
-
accum.push(entry);
|
|
482
|
-
}
|
|
483
|
-
return accum;
|
|
484
|
-
}, [] as WirePointCount[]);
|
|
485
|
-
|
|
486
|
-
// Convert to just a simple array
|
|
487
|
-
const segments:[x: number, y:number][][] = existingSegments.map(segment => {
|
|
488
|
-
return [
|
|
489
|
-
[segment.start.x, segment.start.y],
|
|
490
|
-
[segment.end.x, segment.end.y]
|
|
491
|
-
]
|
|
492
|
-
});
|
|
493
|
-
|
|
494
|
-
return {
|
|
495
|
-
intersectPoints,
|
|
496
|
-
segments,
|
|
497
|
-
}
|
|
498
|
-
}
|
|
499
|
-
}
|
|
500
|
-
|
|
501
|
-
function replaceSegments(segments: Flatten.Segment[], index: number, replacedSegments: Flatten.Segment[]): number {
|
|
502
|
-
// Remove the original segment at position
|
|
503
|
-
if (replacedSegments.length > 0){
|
|
504
|
-
segments.splice(index, 1);
|
|
505
|
-
}
|
|
506
|
-
|
|
507
|
-
// Update the split sections back into the original existing
|
|
508
|
-
// segments array
|
|
509
|
-
let counter = 0;
|
|
510
|
-
replacedSegments.forEach(item => {
|
|
511
|
-
if (item !== null) {
|
|
512
|
-
segments.splice(index + counter, 0, item);
|
|
513
|
-
counter++;
|
|
514
|
-
}
|
|
515
|
-
});
|
|
516
|
-
|
|
517
|
-
return counter;
|
|
518
|
-
}
|
|
519
|
-
|
|
520
|
-
function labelPolygonForAnchors(x: number, y: number, width: number, height: number,
|
|
521
|
-
hAnchor: HorizontalAlign, vAnchor: VerticalAlign): [x: number, y: number][]{
|
|
522
|
-
|
|
523
|
-
// Vectors in terms of width and height, with respect
|
|
524
|
-
// to the anchor point (both hAnchor and vAnchor)
|
|
525
|
-
let coordVectors = [];
|
|
526
|
-
|
|
527
|
-
if (hAnchor === HorizontalAlign.Left){
|
|
528
|
-
if (vAnchor === VerticalAlign.Bottom){
|
|
529
|
-
coordVectors = [
|
|
530
|
-
[0, 0],
|
|
531
|
-
[0, -1],
|
|
532
|
-
[1, -1],
|
|
533
|
-
[1, 1],
|
|
534
|
-
];
|
|
535
|
-
} else if (vAnchor === VerticalAlign.Middle){
|
|
536
|
-
coordVectors = [
|
|
537
|
-
[0, -0.5],
|
|
538
|
-
[0, 0.5],
|
|
539
|
-
[1, 0.5],
|
|
540
|
-
[1, -0.5],
|
|
541
|
-
];
|
|
542
|
-
} else if (vAnchor === VerticalAlign.Top){
|
|
543
|
-
coordVectors = [
|
|
544
|
-
[0, 0],
|
|
545
|
-
[1, 0],
|
|
546
|
-
[1, 1],
|
|
547
|
-
[0, 1],
|
|
548
|
-
];
|
|
549
|
-
}
|
|
550
|
-
} else if (hAnchor === HorizontalAlign.Right){
|
|
551
|
-
if (vAnchor === VerticalAlign.Bottom){
|
|
552
|
-
coordVectors = [
|
|
553
|
-
[0, 0],
|
|
554
|
-
[-1, 0],
|
|
555
|
-
[-1, -1],
|
|
556
|
-
[0, -1],
|
|
557
|
-
];
|
|
558
|
-
} else if (vAnchor === VerticalAlign.Middle){
|
|
559
|
-
coordVectors = [
|
|
560
|
-
[0, -0.5],
|
|
561
|
-
[0, 0.5],
|
|
562
|
-
[-1, 0.5],
|
|
563
|
-
[-1, -0.5],
|
|
564
|
-
];
|
|
565
|
-
} else if (vAnchor === VerticalAlign.Top){
|
|
566
|
-
coordVectors = [
|
|
567
|
-
[0, 0],
|
|
568
|
-
[0, 1],
|
|
569
|
-
[-1, 1],
|
|
570
|
-
[-1, 0]
|
|
571
|
-
];
|
|
572
|
-
}
|
|
573
|
-
}
|
|
574
|
-
else if (hAnchor === HorizontalAlign.Middle){
|
|
575
|
-
if (vAnchor === VerticalAlign.Bottom){
|
|
576
|
-
coordVectors = [
|
|
577
|
-
[-0.5, 0],
|
|
578
|
-
[-0.5, -1],
|
|
579
|
-
[0.5, -1],
|
|
580
|
-
[0.5, 0]
|
|
581
|
-
];
|
|
582
|
-
} else if (vAnchor === VerticalAlign.Middle){
|
|
583
|
-
coordVectors = [
|
|
584
|
-
[-0.5, 0.5],
|
|
585
|
-
[-0.5, -0.5],
|
|
586
|
-
[0.5, -0.5],
|
|
587
|
-
[0.5, 0.5],
|
|
588
|
-
];
|
|
589
|
-
} else if (vAnchor === VerticalAlign.Top){
|
|
590
|
-
coordVectors = [
|
|
591
|
-
[0.5, 0],
|
|
592
|
-
[0.5, 1],
|
|
593
|
-
[-0.5, 1],
|
|
594
|
-
[-0.5, 0]
|
|
595
|
-
];
|
|
596
|
-
}
|
|
597
|
-
}
|
|
598
|
-
|
|
599
|
-
return coordVectors.map(([vx, vy]) => {
|
|
600
|
-
return [
|
|
601
|
-
x + vx * width,
|
|
602
|
-
y + vy * height
|
|
603
|
-
]
|
|
604
|
-
});
|
|
605
|
-
}
|
|
606
|
-
|
|
607
|
-
type WirePointCount = [x: number, y: number, count: number];
|
|
608
|
-
|
|
609
|
-
export enum HorizontalAlign {
|
|
610
|
-
Left = 'left',
|
|
611
|
-
Middle = 'middle',
|
|
612
|
-
Right = 'right',
|
|
613
|
-
}
|
|
614
|
-
|
|
615
|
-
export enum VerticalAlign {
|
|
616
|
-
Top = 'top',
|
|
617
|
-
Middle = 'middle',
|
|
618
|
-
Bottom = 'bottom',
|
|
619
|
-
}
|
|
620
|
-
|
|
621
|
-
function getArcPoint(centerX: number, centerY: number, radius: number,
|
|
622
|
-
angleDegrees: number): [x: number, y: number] {
|
|
623
|
-
const angleRads = angleDegrees * Math.PI / 180;
|
|
624
|
-
return getArcPointRadians(centerX, centerY, radius, angleRads);
|
|
625
|
-
}
|
|
626
|
-
|
|
627
|
-
function getArcPointRadians(centerX: number, centerY: number,
|
|
628
|
-
radius: number, angleRads: number): [x: number, y: number] {
|
|
629
|
-
|
|
630
|
-
// X-axis is 0 degree and rotation clockwise is positive.
|
|
631
|
-
const dx = Math.cos(angleRads);
|
|
632
|
-
const dy = Math.sin(angleRads);
|
|
633
|
-
|
|
634
|
-
return [
|
|
635
|
-
centerX + dx * radius,
|
|
636
|
-
centerY + dy * radius
|
|
637
|
-
];
|
|
638
|
-
}
|
package/src/globals.ts
DELETED
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
export enum GlobalNames {
|
|
2
|
-
__root = '__root',
|
|
3
|
-
gnd = 'gnd',
|
|
4
|
-
|
|
5
|
-
DefaultResistor = 'res',
|
|
6
|
-
DefaultCapacitor = 'cap',
|
|
7
|
-
DefaultInductor = 'ind',
|
|
8
|
-
|
|
9
|
-
symbol = 'symbol',
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export const NoNetText = 'NO_NET';
|
|
13
|
-
|
|
14
|
-
export enum ParamKeys {
|
|
15
|
-
|
|
16
|
-
// If this is set to 1 (number), then use the component as a net.
|
|
17
|
-
__is_net = '__is_net',
|
|
18
|
-
__is_label = '__is_label',
|
|
19
|
-
|
|
20
|
-
priority = 'priority',
|
|
21
|
-
net_name = 'net_name',
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export enum LayoutDirection {
|
|
25
|
-
RIGHT = "RIGHT", // A --> B
|
|
26
|
-
LEFT = "LEFT", // B <-- A
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
export enum SymbolPinSide {
|
|
30
|
-
Left = "left",
|
|
31
|
-
Right = "right"
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
export const portWidth = 20;
|
|
35
|
-
export const portHeight = 2;
|
|
36
|
-
|
|
37
|
-
export const defaultFont = 'Open Sans-Regular, Arial';
|
|
38
|
-
export const defaultFontBold = 'Open Sans-Bold, Arial-Bold, Arial';
|
|
39
|
-
|
|
40
|
-
export const defaultFontSize = 10;
|
|
41
|
-
|
|
42
|
-
export const bodyColor = '#FFFEAF';
|
|
43
|
-
export const junctionSize = 5;
|
|
44
|
-
export const junctionColor = 'rgb(0, 132, 0)';
|
|
45
|
-
export const wireColor = 'rgb(0, 132, 0)';
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
export enum ComponentTypes {
|
|
49
|
-
gnd = 'gnd',
|
|
50
|
-
net = 'net',
|
|
51
|
-
label = 'label',
|
|
52
|
-
point = 'point'
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
export enum ReferenceTypes {
|
|
56
|
-
function = 'function',
|
|
57
|
-
value = 'value',
|
|
58
|
-
variable = 'variable',
|
|
59
|
-
instance = 'instance',
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
export enum BlockTypes {
|
|
63
|
-
Branch = 1, // split off circuit paths, same starting insertion point
|
|
64
|
-
Join = 2, // join circuit paths, same ending insertion point
|
|
65
|
-
Parallel = 3, // same starting and ending points for the circuit paths
|
|
66
|
-
Point = 4, // to this point
|
|
67
|
-
}
|