circuitscript 0.0.14 → 0.0.16
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/.gitlab-ci.yml +24 -19
- package/__tests__/helpers.ts +12 -0
- package/__tests__/renderData/script1.cst.svg +1 -1
- package/__tests__/renderData/script2.cst.svg +1 -1
- package/__tests__/renderData/script3.cst.svg +1 -1
- package/__tests__/renderData/script4.cst +27 -5
- package/__tests__/renderData/script4.cst.svg +1 -1
- package/__tests__/renderData/script5.cst.svg +1 -1
- package/__tests__/testParse.ts +37 -2
- package/build/src/draw_symbols.js +207 -63
- package/build/src/geometry.js +35 -4
- package/build/src/helpers.js +7 -3
- package/build/src/layout.js +30 -17
- package/build/src/regenerate-tests.js +1 -1
- package/build/src/visitor.js +12 -4
- package/examples/example_arduino_uno.cst +390 -120
- package/examples/lib.cst +25 -28
- package/libs/lib.cst +23 -28
- package/package.json +1 -1
- package/src/draw_symbols.ts +270 -64
- package/src/geometry.ts +46 -5
- package/src/helpers.ts +8 -5
- package/src/layout.ts +42 -21
- package/src/regenerate-tests.ts +1 -1
- package/src/visitor.ts +16 -4
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { SymbolPinSide,
|
|
1
|
+
import { SymbolPinSide, defaultFont } from "./globals.js";
|
|
2
2
|
import { Geometry, GeometryProp, HorizontalAlign, Label, VerticalAlign } from "./geometry.js";
|
|
3
3
|
const defaultSymbolLineColor = '#333';
|
|
4
4
|
const defaultSymbolLineWidth = 2;
|
|
@@ -98,7 +98,7 @@ export class SymbolGraphic {
|
|
|
98
98
|
const labels = this.drawing.getLabels();
|
|
99
99
|
labels.forEach(label => {
|
|
100
100
|
const tmpLabel = label;
|
|
101
|
-
const { fontSize = 10, anchor = HorizontalAlign.Left, vanchor = VerticalAlign.Bottom, fontWeight = 'regular', } = tmpLabel.style ?? {};
|
|
101
|
+
const { fontSize = 10, anchor = HorizontalAlign.Left, vanchor = VerticalAlign.Bottom, fontWeight = 'regular', angle: labelAngle = 0, } = tmpLabel.style ?? {};
|
|
102
102
|
let anchorStyle = 'start';
|
|
103
103
|
let dominantBaseline = 'auto';
|
|
104
104
|
let useAnchor = anchor;
|
|
@@ -130,7 +130,8 @@ export class SymbolGraphic {
|
|
|
130
130
|
}
|
|
131
131
|
const position = tmpLabel.getLabelPosition();
|
|
132
132
|
const useFont = defaultFont;
|
|
133
|
-
const
|
|
133
|
+
const textContainer = group.group();
|
|
134
|
+
const text = textContainer.text(tmpLabel.text)
|
|
134
135
|
.fill('#333')
|
|
135
136
|
.font({
|
|
136
137
|
family: useFont,
|
|
@@ -139,13 +140,21 @@ export class SymbolGraphic {
|
|
|
139
140
|
'dominant-baseline': dominantBaseline,
|
|
140
141
|
weight: fontWeight,
|
|
141
142
|
});
|
|
143
|
+
let translateX, translateY;
|
|
144
|
+
let useRotateAngle = 0;
|
|
142
145
|
if (isRotation180) {
|
|
143
|
-
|
|
146
|
+
translateX = -position[0];
|
|
147
|
+
translateY = position[1];
|
|
148
|
+
useRotateAngle = 0;
|
|
144
149
|
}
|
|
145
150
|
else {
|
|
146
|
-
|
|
147
|
-
|
|
151
|
+
translateX = position[0];
|
|
152
|
+
translateY = position[1];
|
|
153
|
+
useRotateAngle = this.angle;
|
|
148
154
|
}
|
|
155
|
+
text.rotate(labelAngle);
|
|
156
|
+
textContainer.translate(translateX, translateY)
|
|
157
|
+
.rotate(useRotateAngle, -translateX, -translateY);
|
|
149
158
|
});
|
|
150
159
|
}
|
|
151
160
|
flipTextAnchor(value) {
|
|
@@ -206,67 +215,183 @@ export class SymbolPlaceholder extends SymbolGraphic {
|
|
|
206
215
|
drawing.clear();
|
|
207
216
|
drawing.angle = this._angle;
|
|
208
217
|
const commands = drawing.getCommands();
|
|
209
|
-
drawing.log(drawing.id, 'angle: ', this._angle, "commands:", commands.length);
|
|
218
|
+
drawing.log('id: ', drawing.id, 'angle: ', this._angle, "commands:", commands.length);
|
|
210
219
|
commands.forEach(([commandName, positionParams, keywordParams]) => {
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
220
|
+
switch (commandName) {
|
|
221
|
+
case PlaceHolderCommands.rect:
|
|
222
|
+
drawing.log('add rect', ...positionParams);
|
|
223
|
+
drawing.addRect(...positionParams);
|
|
224
|
+
break;
|
|
225
|
+
case PlaceHolderCommands.hline:
|
|
226
|
+
drawing.log('add hline', ...positionParams);
|
|
227
|
+
drawing.addHLine(...positionParams);
|
|
228
|
+
break;
|
|
229
|
+
case PlaceHolderCommands.vline:
|
|
230
|
+
drawing.log('add vline', ...positionParams);
|
|
231
|
+
drawing.addVLine(...positionParams);
|
|
232
|
+
break;
|
|
233
|
+
case PlaceHolderCommands.line:
|
|
234
|
+
drawing.log('add line', ...positionParams);
|
|
235
|
+
drawing.addLine(...positionParams);
|
|
236
|
+
break;
|
|
237
|
+
case PlaceHolderCommands.path:
|
|
238
|
+
drawing.addPath(...positionParams);
|
|
239
|
+
break;
|
|
240
|
+
case PlaceHolderCommands.lineWidth:
|
|
241
|
+
drawing.addSetLineWidth(...positionParams);
|
|
242
|
+
break;
|
|
243
|
+
case PlaceHolderCommands.fill:
|
|
244
|
+
drawing.addSetFillColor(...positionParams);
|
|
245
|
+
break;
|
|
246
|
+
case PlaceHolderCommands.lineColor:
|
|
247
|
+
drawing.addSetLineColor(...positionParams);
|
|
248
|
+
break;
|
|
249
|
+
case PlaceHolderCommands.arc:
|
|
250
|
+
drawing.addArc(...positionParams);
|
|
251
|
+
break;
|
|
252
|
+
case PlaceHolderCommands.circle:
|
|
253
|
+
drawing.addArc(...positionParams, 0, 360);
|
|
254
|
+
break;
|
|
255
|
+
case PlaceHolderCommands.triangle:
|
|
256
|
+
drawing.addTriangle(...positionParams);
|
|
257
|
+
break;
|
|
258
|
+
case PlaceHolderCommands.pin:
|
|
259
|
+
case PlaceHolderCommands.hpin:
|
|
260
|
+
case PlaceHolderCommands.vpin:
|
|
261
|
+
{
|
|
262
|
+
this.drawPinParams(drawing, commandName, keywordParams, positionParams);
|
|
263
|
+
break;
|
|
237
264
|
}
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
}
|
|
259
|
-
else if (commandName === 'arc') {
|
|
260
|
-
drawing.addArc(...positionParams);
|
|
265
|
+
case PlaceHolderCommands.label: {
|
|
266
|
+
const keywords = ['fontSize', 'anchor', 'vanchor', 'angle'];
|
|
267
|
+
const style = {};
|
|
268
|
+
keywords.forEach(item => {
|
|
269
|
+
if (keywordParams.has(item)) {
|
|
270
|
+
style[item] = keywordParams.get(item);
|
|
271
|
+
}
|
|
272
|
+
});
|
|
273
|
+
positionParams = [...positionParams];
|
|
274
|
+
positionParams.push(style);
|
|
275
|
+
const labelId = positionParams[0];
|
|
276
|
+
const tmpPositionParams = [...positionParams];
|
|
277
|
+
const tmpLabelValue = this.getLabelValue(labelId);
|
|
278
|
+
if (tmpLabelValue !== undefined) {
|
|
279
|
+
tmpPositionParams[3] = tmpLabelValue;
|
|
280
|
+
}
|
|
281
|
+
drawing.log('add label', JSON.stringify(tmpPositionParams));
|
|
282
|
+
drawing.addLabelId(...tmpPositionParams);
|
|
283
|
+
break;
|
|
284
|
+
}
|
|
261
285
|
}
|
|
262
286
|
});
|
|
263
287
|
drawing.log("=== end generate drawing ===");
|
|
264
288
|
}
|
|
289
|
+
drawPinParams(drawing, commandName, keywordParams, positionParams) {
|
|
290
|
+
drawing.log('add pin', ...positionParams);
|
|
291
|
+
const keywordDisplayPinId = 'display_pin_id';
|
|
292
|
+
let displayPinId = true;
|
|
293
|
+
if (keywordParams.has(keywordDisplayPinId)) {
|
|
294
|
+
if (keywordParams.get(keywordDisplayPinId) === 0) {
|
|
295
|
+
displayPinId = false;
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
let pinNameParam = null;
|
|
299
|
+
if (typeof positionParams[1] === 'string') {
|
|
300
|
+
pinNameParam = positionParams[1];
|
|
301
|
+
positionParams = [positionParams[0], ...positionParams.slice(2)];
|
|
302
|
+
}
|
|
303
|
+
const startX = positionParams[1];
|
|
304
|
+
const startY = positionParams[2];
|
|
305
|
+
if (commandName === PlaceHolderCommands.vpin) {
|
|
306
|
+
const magnitude = positionParams[3];
|
|
307
|
+
positionParams = [
|
|
308
|
+
positionParams[0],
|
|
309
|
+
startX,
|
|
310
|
+
startY,
|
|
311
|
+
startX,
|
|
312
|
+
startY + magnitude
|
|
313
|
+
];
|
|
314
|
+
}
|
|
315
|
+
else if (commandName === PlaceHolderCommands.hpin) {
|
|
316
|
+
const magnitude = positionParams[3];
|
|
317
|
+
positionParams = [
|
|
318
|
+
positionParams[0],
|
|
319
|
+
startX,
|
|
320
|
+
startY,
|
|
321
|
+
startX + magnitude,
|
|
322
|
+
startY
|
|
323
|
+
];
|
|
324
|
+
}
|
|
325
|
+
drawing.addPin(...positionParams);
|
|
326
|
+
const latestPin = this.drawing.pins[this.drawing.pins.length - 1];
|
|
327
|
+
const [pinId, , angle] = latestPin;
|
|
328
|
+
const [, , , endX, endY] = positionParams;
|
|
329
|
+
let pinNameAlignment = HorizontalAlign.Left;
|
|
330
|
+
let pinNameOffsetX = 4;
|
|
331
|
+
let pinIdOffsetX = 0;
|
|
332
|
+
let pinIdAlignment = HorizontalAlign.Left;
|
|
333
|
+
let pinIdVAlignment = VerticalAlign.Bottom;
|
|
334
|
+
let pinIdOffsetY = -2;
|
|
335
|
+
switch (angle) {
|
|
336
|
+
case 0:
|
|
337
|
+
pinNameAlignment = HorizontalAlign.Left;
|
|
338
|
+
pinNameOffsetX = 4;
|
|
339
|
+
pinIdAlignment = HorizontalAlign.Right;
|
|
340
|
+
pinIdOffsetX = -2;
|
|
341
|
+
break;
|
|
342
|
+
case 90:
|
|
343
|
+
case 180:
|
|
344
|
+
pinNameAlignment = HorizontalAlign.Right;
|
|
345
|
+
pinNameOffsetX = -4;
|
|
346
|
+
pinIdAlignment = HorizontalAlign.Left;
|
|
347
|
+
pinIdOffsetX = 2;
|
|
348
|
+
break;
|
|
349
|
+
case 270:
|
|
350
|
+
pinNameAlignment = HorizontalAlign.Left;
|
|
351
|
+
pinNameOffsetX = 4;
|
|
352
|
+
pinIdAlignment = HorizontalAlign.Left;
|
|
353
|
+
pinIdOffsetX = 2;
|
|
354
|
+
pinIdOffsetY = 2;
|
|
355
|
+
pinIdVAlignment = VerticalAlign.Top;
|
|
356
|
+
break;
|
|
357
|
+
}
|
|
358
|
+
if (angle === 0 || angle === 90 || angle === 180 || angle === 270) {
|
|
359
|
+
const usePinName = pinNameParam ?? "";
|
|
360
|
+
usePinName !== "" && drawing.addLabel(endX + pinNameOffsetX, endY, usePinName, {
|
|
361
|
+
fontSize: 10,
|
|
362
|
+
anchor: pinNameAlignment,
|
|
363
|
+
vanchor: VerticalAlign.Middle,
|
|
364
|
+
});
|
|
365
|
+
displayPinId && drawing.addLabel(endX + pinIdOffsetX, endY + pinIdOffsetY, pinId.toString(), {
|
|
366
|
+
fontSize: 8,
|
|
367
|
+
anchor: pinIdAlignment,
|
|
368
|
+
vanchor: pinIdVAlignment,
|
|
369
|
+
});
|
|
370
|
+
}
|
|
371
|
+
}
|
|
265
372
|
constructor(drawing) {
|
|
266
373
|
super();
|
|
267
374
|
this.drawing = drawing;
|
|
268
375
|
}
|
|
269
376
|
}
|
|
377
|
+
export var PlaceHolderCommands;
|
|
378
|
+
(function (PlaceHolderCommands) {
|
|
379
|
+
PlaceHolderCommands["arc"] = "arc";
|
|
380
|
+
PlaceHolderCommands["circle"] = "circle";
|
|
381
|
+
PlaceHolderCommands["rect"] = "rect";
|
|
382
|
+
PlaceHolderCommands["triangle"] = "triangle";
|
|
383
|
+
PlaceHolderCommands["pin"] = "pin";
|
|
384
|
+
PlaceHolderCommands["hpin"] = "hpin";
|
|
385
|
+
PlaceHolderCommands["vpin"] = "vpin";
|
|
386
|
+
PlaceHolderCommands["hline"] = "hline";
|
|
387
|
+
PlaceHolderCommands["vline"] = "vline";
|
|
388
|
+
PlaceHolderCommands["line"] = "line";
|
|
389
|
+
PlaceHolderCommands["label"] = "label";
|
|
390
|
+
PlaceHolderCommands["path"] = "path";
|
|
391
|
+
PlaceHolderCommands["lineWidth"] = "lineWidth";
|
|
392
|
+
PlaceHolderCommands["fill"] = "fill";
|
|
393
|
+
PlaceHolderCommands["lineColor"] = "lineColor";
|
|
394
|
+
})(PlaceHolderCommands || (PlaceHolderCommands = {}));
|
|
270
395
|
export class SymbolCustom extends SymbolGraphic {
|
|
271
396
|
pinDefinition = [];
|
|
272
397
|
bodyWidth = 100;
|
|
@@ -295,7 +420,6 @@ export class SymbolCustom extends SymbolGraphic {
|
|
|
295
420
|
drawing.angle = this._angle;
|
|
296
421
|
const bodyWidth = this.bodyWidth;
|
|
297
422
|
const bodyHeight = (1 + Math.max(maxLeftPins, maxRightPins)) * this.pinSpacing;
|
|
298
|
-
drawing.addSetFillColor(bodyColor);
|
|
299
423
|
drawing.addRect(0, 0, bodyWidth, bodyHeight);
|
|
300
424
|
const leftPinStart = -bodyWidth / 2;
|
|
301
425
|
const rightPinStart = bodyWidth / 2;
|
|
@@ -331,15 +455,20 @@ export class SymbolCustom extends SymbolGraphic {
|
|
|
331
455
|
});
|
|
332
456
|
});
|
|
333
457
|
const instanceName = this.getLabelValue("refdes");
|
|
334
|
-
const MPN = this.getLabelValue("MPN");
|
|
335
458
|
instanceName && drawing.addLabel(-bodyWidth / 2, -bodyHeight / 2 - 4, instanceName, {
|
|
336
459
|
fontSize: 10,
|
|
337
460
|
anchor: HorizontalAlign.Left,
|
|
338
461
|
});
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
462
|
+
const acceptedMPNKeys = ['MPN', 'mpn', 'manufacturer_pn'];
|
|
463
|
+
acceptedMPNKeys.some(key => {
|
|
464
|
+
const labelValue = this.getLabelValue(key);
|
|
465
|
+
if (labelValue !== undefined) {
|
|
466
|
+
drawing.addLabel(-bodyWidth / 2, bodyHeight / 2 + 4, labelValue, {
|
|
467
|
+
fontSize: 10,
|
|
468
|
+
anchor: HorizontalAlign.Left,
|
|
469
|
+
vanchor: VerticalAlign.Top,
|
|
470
|
+
});
|
|
471
|
+
}
|
|
343
472
|
});
|
|
344
473
|
this.drawing = drawing;
|
|
345
474
|
this._cacheLeftPins = leftPins;
|
|
@@ -412,6 +541,21 @@ export class SymbolDrawing {
|
|
|
412
541
|
]));
|
|
413
542
|
return this;
|
|
414
543
|
}
|
|
544
|
+
addTriangle(startX, startY, endX, endY, width) {
|
|
545
|
+
const line = Geometry.line(startX, startY, endX, endY);
|
|
546
|
+
const normLine = line.norm;
|
|
547
|
+
const dx1 = normLine.x * width / 2;
|
|
548
|
+
const dy1 = normLine.y * width / 2;
|
|
549
|
+
const dx2 = normLine.x * -width / 2;
|
|
550
|
+
const dy2 = normLine.y * -width / 2;
|
|
551
|
+
this.items.push(Geometry.polygon([
|
|
552
|
+
[dx1 + startX, dy1 + startY],
|
|
553
|
+
[dx2 + startX, dy2 + startY],
|
|
554
|
+
[endX, endY],
|
|
555
|
+
[dx1 + startX, dy1 + startY],
|
|
556
|
+
]));
|
|
557
|
+
return this;
|
|
558
|
+
}
|
|
415
559
|
addRect2(x, y, x2, y2) {
|
|
416
560
|
this.items.push(Geometry.polygon([
|
|
417
561
|
[x, y],
|
|
@@ -587,7 +731,7 @@ export class SymbolDrawingCommands extends SymbolDrawing {
|
|
|
587
731
|
}
|
|
588
732
|
clone() {
|
|
589
733
|
const tmpCommands = this.commands.map(item => {
|
|
590
|
-
if (item[0] ===
|
|
734
|
+
if (item[0] === PlaceHolderCommands.label) {
|
|
591
735
|
const commandName = item[0];
|
|
592
736
|
const positionParams = item[1];
|
|
593
737
|
const keywordParams = item[2];
|
package/build/src/geometry.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import Flatten from '@flatten-js/core';
|
|
2
2
|
import { measureTextSize2 } from './sizing.js';
|
|
3
3
|
import { defaultFont } from './globals.js';
|
|
4
|
+
import { NumericValue } from './objects/ParamDefinition.js';
|
|
4
5
|
export class Label extends Flatten.Polygon {
|
|
5
6
|
id;
|
|
6
7
|
text;
|
|
@@ -24,8 +25,22 @@ export class Label extends Flatten.Polygon {
|
|
|
24
25
|
this.textMeasurementBounds = bounds;
|
|
25
26
|
}
|
|
26
27
|
static fromPoint(id, x, y, text, style) {
|
|
28
|
+
let useText;
|
|
29
|
+
if (typeof text === 'number') {
|
|
30
|
+
useText = text.toString();
|
|
31
|
+
}
|
|
32
|
+
else if (typeof text === 'object'
|
|
33
|
+
&& text instanceof NumericValue) {
|
|
34
|
+
useText = text.toDisplayString();
|
|
35
|
+
}
|
|
36
|
+
else if (typeof text === 'string') {
|
|
37
|
+
useText = text;
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
throw 'Invalid string passed into label';
|
|
41
|
+
}
|
|
27
42
|
const { fontSize = 10, anchor = HorizontalAlign.Left, vanchor = VerticalAlign.Bottom, fontWeight = 'regular', } = style ?? {};
|
|
28
|
-
const { width, height, box } = measureTextSize2(
|
|
43
|
+
const { width, height, box } = measureTextSize2(useText, defaultFont, fontSize, fontWeight, anchor, vanchor);
|
|
29
44
|
const polygonCoords = [
|
|
30
45
|
[box.x, box.y],
|
|
31
46
|
[box.x2, box.y],
|
|
@@ -34,7 +49,7 @@ export class Label extends Flatten.Polygon {
|
|
|
34
49
|
[box.x, box.y],
|
|
35
50
|
];
|
|
36
51
|
const polygon = new Flatten.Polygon(polygonCoords);
|
|
37
|
-
return new Label(id,
|
|
52
|
+
return new Label(id, useText, [x, y], polygon, style, box);
|
|
38
53
|
}
|
|
39
54
|
rotate(angle, origin) {
|
|
40
55
|
const polygonRotate = super.rotate(angle, origin);
|
|
@@ -56,6 +71,9 @@ export class Geometry {
|
|
|
56
71
|
static point(x, y) {
|
|
57
72
|
return new Flatten.Point(x, y);
|
|
58
73
|
}
|
|
74
|
+
static line(x1, y1, x2, y2) {
|
|
75
|
+
return new Flatten.Line(Geometry.point(x1, y1), Geometry.point(x2, y2));
|
|
76
|
+
}
|
|
59
77
|
static label(id, x, y, text, style) {
|
|
60
78
|
return Label.fromPoint(id, x, y, text, style);
|
|
61
79
|
}
|
|
@@ -99,6 +117,11 @@ export class Geometry {
|
|
|
99
117
|
let maxY = Number.NEGATIVE_INFINITY;
|
|
100
118
|
features.forEach(feature => {
|
|
101
119
|
const box = feature.box;
|
|
120
|
+
if (feature instanceof Label
|
|
121
|
+
&& typeof feature.text === 'string'
|
|
122
|
+
&& feature.text.trim().length === 0) {
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
102
125
|
if (box.xmin === undefined) {
|
|
103
126
|
throw "Invalid box!";
|
|
104
127
|
}
|
|
@@ -126,6 +149,7 @@ export class Geometry {
|
|
|
126
149
|
}
|
|
127
150
|
console.log('unknown type', feature);
|
|
128
151
|
}
|
|
152
|
+
static FullCircleRadians = 2 * Math.PI;
|
|
129
153
|
static featuresToPath(items) {
|
|
130
154
|
const paths = [];
|
|
131
155
|
let isClosedPolygon = false;
|
|
@@ -138,11 +162,18 @@ export class Geometry {
|
|
|
138
162
|
const x = item.center.x;
|
|
139
163
|
const y = item.center.y;
|
|
140
164
|
const radius = item.r;
|
|
165
|
+
let useEndAngle = item.endAngle;
|
|
166
|
+
let extraEnd = '';
|
|
167
|
+
if (item.startAngle === 0 && item.endAngle === Geometry.FullCircleRadians) {
|
|
168
|
+
useEndAngle = 359.9999 * Math.PI / 180;
|
|
169
|
+
isClosedPolygon = true;
|
|
170
|
+
extraEnd = ' Z';
|
|
171
|
+
}
|
|
141
172
|
const startPoint = getArcPointRadians(x, y, radius, item.startAngle);
|
|
142
|
-
const endPoint = getArcPointRadians(x, y, radius,
|
|
173
|
+
const endPoint = getArcPointRadians(x, y, radius, useEndAngle);
|
|
143
174
|
paths.push('M ' + startPoint[0] + ' ' + startPoint[1]
|
|
144
175
|
+ 'A ' + radius + ' ' + radius + ' 0 1 1 '
|
|
145
|
-
+ endPoint[0] + ' ' + endPoint[1]);
|
|
176
|
+
+ endPoint[0] + ' ' + endPoint[1] + extraEnd);
|
|
146
177
|
}
|
|
147
178
|
else {
|
|
148
179
|
const coords = Geometry.getCoords(item);
|
package/build/src/helpers.js
CHANGED
|
@@ -22,7 +22,12 @@ export function renderScript(scriptData, outputPath, options) {
|
|
|
22
22
|
console.log('Error while parsing');
|
|
23
23
|
return null;
|
|
24
24
|
}
|
|
25
|
-
|
|
25
|
+
try {
|
|
26
|
+
visitor.annotateComponents();
|
|
27
|
+
}
|
|
28
|
+
catch (err) {
|
|
29
|
+
console.log('Error during annotation: ', err);
|
|
30
|
+
}
|
|
26
31
|
if (kicadNetlistPath) {
|
|
27
32
|
const kicadNetList = generateKiCADNetList(visitor.getNetList());
|
|
28
33
|
writeFileSync(kicadNetlistPath, kicadNetList);
|
|
@@ -62,8 +67,7 @@ export function renderScript(scriptData, outputPath, options) {
|
|
|
62
67
|
}
|
|
63
68
|
}
|
|
64
69
|
catch (err) {
|
|
65
|
-
console.log('
|
|
66
|
-
console.log(err);
|
|
70
|
+
console.log('Error during render: ', err);
|
|
67
71
|
}
|
|
68
72
|
return svgOutput;
|
|
69
73
|
}
|
package/build/src/layout.js
CHANGED
|
@@ -389,9 +389,6 @@ export class LayoutEngine {
|
|
|
389
389
|
if (tmpSymbol instanceof SymbolCustom && widthProp) {
|
|
390
390
|
tmpSymbol.bodyWidth = widthProp;
|
|
391
391
|
}
|
|
392
|
-
if (component.assignedRefDes !== null) {
|
|
393
|
-
tmpSymbol.setLabelValue("refdes", component.assignedRefDes);
|
|
394
|
-
}
|
|
395
392
|
if (!didSetAngle && component.parameters.has('_addDirection')) {
|
|
396
393
|
tmpSymbol.refreshDrawing(false);
|
|
397
394
|
tmpSymbol.angle = calculateSymbolAngle(tmpSymbol, component.parameters.get('_addPin'), component.parameters.get('_addDirection'));
|
|
@@ -433,7 +430,20 @@ export class LayoutEngine {
|
|
|
433
430
|
graph.setEdge(previousNode, wireName, makeEdgeValue(previousNode, previousPin, wireName, 0, i));
|
|
434
431
|
previousNode = wireName;
|
|
435
432
|
previousPin = 1;
|
|
436
|
-
|
|
433
|
+
const wireSegmentsInfo = wireSegments.map(item => {
|
|
434
|
+
const tmp = {
|
|
435
|
+
direction: item.direction,
|
|
436
|
+
value: item.value,
|
|
437
|
+
};
|
|
438
|
+
if (item.valueXY) {
|
|
439
|
+
tmp.valueXY = item.valueXY;
|
|
440
|
+
}
|
|
441
|
+
if (item.until) {
|
|
442
|
+
tmp.until = [item.until[0].toString(), item.until[1]];
|
|
443
|
+
}
|
|
444
|
+
return tmp;
|
|
445
|
+
});
|
|
446
|
+
this.print(SequenceAction.Wire, wireId, JSON.stringify(wireSegmentsInfo));
|
|
437
447
|
}
|
|
438
448
|
else if (action === SequenceAction.WireJump) {
|
|
439
449
|
this.print(...sequence[i]);
|
|
@@ -881,20 +891,23 @@ function applyComponentParamsToSymbol(typeProp, component, symbol) {
|
|
|
881
891
|
if (typeProp === 'net') {
|
|
882
892
|
symbol.setLabelValue("net_name", component.parameters.get(ParamKeys.net_name));
|
|
883
893
|
}
|
|
884
|
-
if (component.
|
|
885
|
-
|
|
886
|
-
const tmpValue = component.parameters.get('value');
|
|
887
|
-
if (typeof tmpValue == 'object' && (tmpValue instanceof NumericValue)) {
|
|
888
|
-
displayString = tmpValue.toDisplayString();
|
|
889
|
-
}
|
|
890
|
-
else {
|
|
891
|
-
displayString = tmpValue;
|
|
892
|
-
}
|
|
893
|
-
symbol.setLabelValue('value', displayString);
|
|
894
|
+
if (component.assignedRefDes !== null) {
|
|
895
|
+
symbol.setLabelValue("refdes", component.assignedRefDes);
|
|
894
896
|
}
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
897
|
+
for (const [key, value] of component.parameters) {
|
|
898
|
+
if (key !== 'refdes' && key !== 'net_name') {
|
|
899
|
+
let useValue;
|
|
900
|
+
if (typeof value == 'object' && (value instanceof NumericValue)) {
|
|
901
|
+
useValue = value.toDisplayString();
|
|
902
|
+
}
|
|
903
|
+
else if (typeof value === 'number') {
|
|
904
|
+
useValue = value.toString();
|
|
905
|
+
}
|
|
906
|
+
else if (typeof value === 'string') {
|
|
907
|
+
useValue = value;
|
|
908
|
+
}
|
|
909
|
+
symbol.setLabelValue(key, useValue);
|
|
910
|
+
}
|
|
898
911
|
}
|
|
899
912
|
}
|
|
900
913
|
function calculateSymbolAngle(symbol, pin, direction) {
|
|
@@ -14,5 +14,5 @@ cstFiles.forEach(file => {
|
|
|
14
14
|
const scriptData = fs.readFileSync(inputPath, { encoding: 'utf-8' });
|
|
15
15
|
const outputPath = inputPath + '.svg';
|
|
16
16
|
renderScript(scriptData, outputPath, { currentDirectory: useCurrentDir });
|
|
17
|
-
console.log('generated ',
|
|
17
|
+
console.log('generated ', outputPath);
|
|
18
18
|
});
|
package/build/src/visitor.js
CHANGED
|
@@ -914,8 +914,8 @@ export class MainVisitor extends ParseTreeVisitor {
|
|
|
914
914
|
continue;
|
|
915
915
|
}
|
|
916
916
|
if (instance.typeProp === null) {
|
|
917
|
-
this.print('Instance has no type:', instance.instanceName);
|
|
918
|
-
|
|
917
|
+
this.print('Instance has no type:', instance.instanceName, ' assuming connector');
|
|
918
|
+
instance.typeProp = 'conn';
|
|
919
919
|
}
|
|
920
920
|
if (instance.parameters.has('refdes')) {
|
|
921
921
|
const refdes = instance.parameters.get('refdes');
|
|
@@ -1065,8 +1065,16 @@ class ComponentAnnotater {
|
|
|
1065
1065
|
this.counter['?'] = 1;
|
|
1066
1066
|
}
|
|
1067
1067
|
getAnnotation(type) {
|
|
1068
|
-
if (this.counter[type] === undefined) {
|
|
1069
|
-
|
|
1068
|
+
if (this.counter[type] === undefined && type.length <= 2) {
|
|
1069
|
+
for (const [, value] of Object.entries(ComponentRefDesPrefixes)) {
|
|
1070
|
+
if (value === type) {
|
|
1071
|
+
throw "Refdes prefix is already in use!";
|
|
1072
|
+
}
|
|
1073
|
+
}
|
|
1074
|
+
if (ComponentRefDesPrefixes[type] === undefined) {
|
|
1075
|
+
ComponentRefDesPrefixes[type] = type;
|
|
1076
|
+
this.counter[type] = 1;
|
|
1077
|
+
}
|
|
1070
1078
|
}
|
|
1071
1079
|
let attempts = 100;
|
|
1072
1080
|
let proposedName;
|