circuitscript 0.5.7 → 0.6.1
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 +1 -0
- package/dist/cjs/annotate/ComponentAnnotater.js +6 -12
- package/dist/cjs/annotate/RefdesAnnotationVisitor.js +1 -3
- package/dist/cjs/antlr/CircuitScriptParser.js +1105 -845
- package/dist/cjs/cache/serializer.js +1 -1
- package/dist/cjs/errors.js +6 -3
- package/dist/cjs/execute.js +16 -10
- package/dist/cjs/objects/BlockTypes.js +1 -0
- package/dist/cjs/objects/ClassComponent.js +3 -3
- package/dist/cjs/objects/Frame.js +4 -0
- package/dist/cjs/regenerate-tests.js +4 -1
- package/dist/cjs/render/draw_symbols.js +51 -12
- package/dist/cjs/render/geometry.js +2 -2
- package/dist/cjs/render/layout.js +26 -2
- package/dist/cjs/sizing.js +3 -2
- package/dist/cjs/visitor.js +126 -32
- package/dist/esm/BaseVisitor.js +1 -0
- package/dist/esm/annotate/ComponentAnnotater.js +6 -12
- package/dist/esm/annotate/RefdesAnnotationVisitor.js +1 -3
- package/dist/esm/antlr/CircuitScriptParser.js +1098 -840
- package/dist/esm/antlr/CircuitScriptParserVisitor.js +2 -0
- package/dist/esm/cache/serializer.js +1 -1
- package/dist/esm/errors.js +6 -3
- package/dist/esm/execute.js +16 -10
- package/dist/esm/objects/BlockTypes.js +1 -0
- package/dist/esm/objects/ClassComponent.js +3 -3
- package/dist/esm/objects/Frame.js +4 -0
- package/dist/esm/regenerate-tests.js +4 -1
- package/dist/esm/render/draw_symbols.js +51 -12
- package/dist/esm/render/geometry.js +2 -2
- package/dist/esm/render/layout.js +26 -2
- package/dist/esm/sizing.js +3 -2
- package/dist/esm/visitor.js +127 -33
- package/dist/libs/std.cst +518 -15
- package/dist/types/BaseVisitor.d.ts +2 -2
- package/dist/types/antlr/CircuitScriptParser.d.ts +86 -64
- package/dist/types/antlr/CircuitScriptParserVisitor.d.ts +4 -0
- package/dist/types/execute.d.ts +2 -1
- package/dist/types/objects/BlockTypes.d.ts +2 -1
- package/dist/types/objects/ClassComponent.d.ts +1 -1
- package/dist/types/objects/Frame.d.ts +4 -0
- package/dist/types/render/draw_symbols.d.ts +5 -3
- package/dist/types/render/geometry.d.ts +1 -0
- package/dist/types/render/layout.d.ts +6 -0
- package/dist/types/sizing.d.ts +1 -1
- package/dist/types/visitor.d.ts +2 -1
- package/libs/std.cst +518 -15
- package/package.json +1 -1
|
@@ -2,6 +2,7 @@ import { AbstractParseTreeVisitor } from "antlr4ng";
|
|
|
2
2
|
export class CircuitScriptParserVisitor extends AbstractParseTreeVisitor {
|
|
3
3
|
visitScript;
|
|
4
4
|
visitExpression;
|
|
5
|
+
visitNon_newline_expression;
|
|
5
6
|
visitFlow_expressions;
|
|
6
7
|
visitGraph_expressions;
|
|
7
8
|
visitExpressions_block;
|
|
@@ -17,6 +18,7 @@ export class CircuitScriptParserVisitor extends AbstractParseTreeVisitor {
|
|
|
17
18
|
visitAt_block_header;
|
|
18
19
|
visitAt_block;
|
|
19
20
|
visitAt_block_expressions;
|
|
21
|
+
visitAt_block_expressions_inner;
|
|
20
22
|
visitAt_block_pin_expr;
|
|
21
23
|
visitKeyword_assignment_expr;
|
|
22
24
|
visitParameters;
|
|
@@ -62,7 +62,7 @@ export function serializeLibraryScope(importedLib, contentHash) {
|
|
|
62
62
|
prevStopLine = null;
|
|
63
63
|
};
|
|
64
64
|
for (const exprCtx of tree.expression()) {
|
|
65
|
-
if (exprCtx.function_def_expr() !== null) {
|
|
65
|
+
if (exprCtx.non_newline_expression()?.function_def_expr() !== null) {
|
|
66
66
|
flushGroup();
|
|
67
67
|
continue;
|
|
68
68
|
}
|
package/dist/esm/errors.js
CHANGED
|
@@ -111,9 +111,12 @@ export function collectErrorChain(error) {
|
|
|
111
111
|
return items;
|
|
112
112
|
}
|
|
113
113
|
export function printErrorChain(error) {
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
114
|
+
let useErrors = collectErrorChain(error);
|
|
115
|
+
if (useErrors.length === 0) {
|
|
116
|
+
useErrors = [error];
|
|
117
|
+
}
|
|
118
|
+
useErrors.reverse();
|
|
119
|
+
for (const err of useErrors) {
|
|
117
120
|
console.log(" " + err.toString());
|
|
118
121
|
}
|
|
119
122
|
}
|
package/dist/esm/execute.js
CHANGED
|
@@ -553,9 +553,7 @@ export class ExecutionContext {
|
|
|
553
553
|
}
|
|
554
554
|
else if (blockType === BlockTypes.Join || blockType === BlockTypes.Parallel) {
|
|
555
555
|
if (blockIndex === 0) {
|
|
556
|
-
|
|
557
|
-
this.addPoint(`${pointIdName}.${this.name}.${this.tmpPointId}`, false);
|
|
558
|
-
this.tmpPointId += 1;
|
|
556
|
+
this.addPointForBlockType(blockType);
|
|
559
557
|
stackRef.end_point = [
|
|
560
558
|
this.scope.currentComponent,
|
|
561
559
|
this.scope.currentPin,
|
|
@@ -569,6 +567,11 @@ export class ExecutionContext {
|
|
|
569
567
|
}
|
|
570
568
|
}
|
|
571
569
|
}
|
|
570
|
+
addPointForBlockType(blockType) {
|
|
571
|
+
const pointIdName = `${Delimiter1}${getBlockTypeString(blockType)}`;
|
|
572
|
+
this.addPoint(`${pointIdName}.${this.name}.${this.tmpPointId}`, false);
|
|
573
|
+
this.tmpPointId += 1;
|
|
574
|
+
}
|
|
572
575
|
atPointBlock() {
|
|
573
576
|
const [component, pin,] = this.getPointBlockLocation();
|
|
574
577
|
this.atComponent(component, pin, {
|
|
@@ -585,10 +588,12 @@ export class ExecutionContext {
|
|
|
585
588
|
this.log('get block point');
|
|
586
589
|
for (let i = 0; i < this.scope.scopeLevel; i++) {
|
|
587
590
|
const stackRef = this.scope.blockStack.get(this.scope.scopeLevel - 1 - i);
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
591
|
+
if (stackRef) {
|
|
592
|
+
const { start_point } = stackRef;
|
|
593
|
+
const component = start_point[0];
|
|
594
|
+
if (component.instanceName.startsWith(`${Delimiter1}point.`)) {
|
|
595
|
+
return start_point;
|
|
596
|
+
}
|
|
592
597
|
}
|
|
593
598
|
}
|
|
594
599
|
this.log('did not find block point');
|
|
@@ -1023,7 +1028,8 @@ export class ExecutionContext {
|
|
|
1023
1028
|
});
|
|
1024
1029
|
}
|
|
1025
1030
|
applyComponentAngleFromWire(component, pin, opposite = false) {
|
|
1026
|
-
const
|
|
1031
|
+
const usePin = component.getPin(pin);
|
|
1032
|
+
const targetUnit = component.getUnitForPin(usePin);
|
|
1027
1033
|
if (this.componentAngleFollowsWire
|
|
1028
1034
|
&& targetUnit.followWireOrientationProp
|
|
1029
1035
|
&& targetUnit.useWireOrientationAngle
|
|
@@ -1035,8 +1041,8 @@ export class ExecutionContext {
|
|
|
1035
1041
|
useSegment = currentWire.path[0];
|
|
1036
1042
|
}
|
|
1037
1043
|
const pinPositions = CalculatePinPositions(targetUnit);
|
|
1038
|
-
if (pinPositions.has(
|
|
1039
|
-
const connectedPinPos = pinPositions.get(
|
|
1044
|
+
if (pinPositions.has(usePin)) {
|
|
1045
|
+
const connectedPinPos = pinPositions.get(usePin);
|
|
1040
1046
|
let targetAngle = null;
|
|
1041
1047
|
let useDirection = useSegment.direction;
|
|
1042
1048
|
if (opposite) {
|
|
@@ -196,10 +196,10 @@ export class ClassComponent {
|
|
|
196
196
|
}
|
|
197
197
|
throw new RuntimeExecutionError(`Could not find pin '${pinId}' on component '${this.instanceName}'`);
|
|
198
198
|
}
|
|
199
|
-
getNextPinAfter(
|
|
199
|
+
getNextPinAfter(pinId) {
|
|
200
200
|
const pins = Array.from(this.pins.keys());
|
|
201
|
-
|
|
202
|
-
const index = pins.findIndex(tmp => tmp.equals(
|
|
201
|
+
const foundPin = this.getPin(pinId);
|
|
202
|
+
const index = pins.findIndex(tmp => tmp.equals(foundPin));
|
|
203
203
|
if (index + 1 < pins.length) {
|
|
204
204
|
return pins[index + 1];
|
|
205
205
|
}
|
|
@@ -35,6 +35,10 @@ export var FrameParamKeys;
|
|
|
35
35
|
FrameParamKeys["TitleAlign"] = "title_align";
|
|
36
36
|
FrameParamKeys["HorizontalAlign"] = "align";
|
|
37
37
|
FrameParamKeys["VerticalAlign"] = "valign";
|
|
38
|
+
FrameParamKeys["FontSize"] = "font_size";
|
|
39
|
+
FrameParamKeys["Bold"] = "bold";
|
|
40
|
+
FrameParamKeys["Italic"] = "italic";
|
|
41
|
+
FrameParamKeys["Color"] = "color";
|
|
38
42
|
FrameParamKeys["SheetNumber"] = "sheet_number";
|
|
39
43
|
FrameParamKeys["SheetTotal"] = "sheet_total";
|
|
40
44
|
})(FrameParamKeys || (FrameParamKeys = {}));
|
|
@@ -22,13 +22,16 @@ async function regenerateTests(extra = "", fileList = []) {
|
|
|
22
22
|
const outputPath = mainDir + 'svgs/' + file + extra + '.svg';
|
|
23
23
|
env.setModuleDirectory(mainDir);
|
|
24
24
|
env.setDefaultLibsPath(mainDir + '../../../libs/');
|
|
25
|
-
await renderScript(scriptData, outputPath, {
|
|
25
|
+
const { errors } = await renderScript(scriptData, outputPath, {
|
|
26
26
|
inputPath,
|
|
27
27
|
dumpNets: false,
|
|
28
28
|
dumpData: false,
|
|
29
29
|
showStats: false,
|
|
30
30
|
environment: env,
|
|
31
31
|
});
|
|
32
|
+
if (errors.length > 0) {
|
|
33
|
+
console.log(errors);
|
|
34
|
+
}
|
|
32
35
|
}
|
|
33
36
|
return cstFiles;
|
|
34
37
|
}
|
|
@@ -139,7 +139,7 @@ export class SymbolGraphic {
|
|
|
139
139
|
const labels = this.drawing.getLabels();
|
|
140
140
|
for (const label of labels) {
|
|
141
141
|
const tmpLabel = label;
|
|
142
|
-
const { fontSize = numeric(50), anchor = HorizontalAlign.Left, vanchor = VerticalAlign.Bottom, fontWeight = 'regular', angle: tmpLabelAngle = numeric(0), textColor = "#333", } = tmpLabel.style ?? {};
|
|
142
|
+
const { fontSize = numeric(50), anchor = HorizontalAlign.Left, vanchor = VerticalAlign.Bottom, fontWeight = 'regular', fontStyle = 'normal', angle: tmpLabelAngle = numeric(0), textColor = "#333", } = tmpLabel.style ?? {};
|
|
143
143
|
let anchorStyle = 'start';
|
|
144
144
|
let dominantBaseline = 'auto';
|
|
145
145
|
let useAnchor = anchor;
|
|
@@ -293,15 +293,19 @@ export class SymbolGraphic {
|
|
|
293
293
|
if (isRotation180) {
|
|
294
294
|
useLabelAngle = (labelAngle + 180) % 360;
|
|
295
295
|
}
|
|
296
|
-
|
|
297
|
-
.fill(textColor)
|
|
298
|
-
.font({
|
|
296
|
+
const fontProperties = {
|
|
299
297
|
family: useFont,
|
|
300
298
|
size: fontSize.toNumber() * fontDisplayScale,
|
|
301
299
|
anchor: anchorStyle,
|
|
302
300
|
'dominant-baseline': dominantBaseline,
|
|
303
301
|
weight: fontWeight,
|
|
304
|
-
}
|
|
302
|
+
};
|
|
303
|
+
if (fontStyle !== 'normal') {
|
|
304
|
+
fontProperties.style = fontStyle;
|
|
305
|
+
}
|
|
306
|
+
textContainer.text(tmpLabel.text)
|
|
307
|
+
.fill(textColor)
|
|
308
|
+
.font(fontProperties)
|
|
305
309
|
.attr("xml:space", "preserve")
|
|
306
310
|
.rotate(useLabelAngle, 0, 0);
|
|
307
311
|
const { a, b, c, d, e, f } = textContainer.matrix();
|
|
@@ -349,6 +353,8 @@ export class SymbolText extends SymbolGraphic {
|
|
|
349
353
|
text;
|
|
350
354
|
fontSize = numeric(40);
|
|
351
355
|
fontWeight = 'regular';
|
|
356
|
+
fontStyle = 'normal';
|
|
357
|
+
color = undefined;
|
|
352
358
|
constructor(text) {
|
|
353
359
|
super();
|
|
354
360
|
this.text = text;
|
|
@@ -360,6 +366,8 @@ export class SymbolText extends SymbolGraphic {
|
|
|
360
366
|
fontSize: this.fontSize,
|
|
361
367
|
anchor: HorizontalAlign.Center,
|
|
362
368
|
fontWeight: this.fontWeight,
|
|
369
|
+
fontStyle: this.fontStyle,
|
|
370
|
+
textColor: this.color
|
|
363
371
|
});
|
|
364
372
|
this.drawing = drawing;
|
|
365
373
|
}
|
|
@@ -447,6 +455,9 @@ export class SymbolPlaceholder extends SymbolGraphic {
|
|
|
447
455
|
case PlaceHolderCommands.triangle:
|
|
448
456
|
drawing.addTriangle(...positionParams);
|
|
449
457
|
break;
|
|
458
|
+
case PlaceHolderCommands.arrow:
|
|
459
|
+
drawing.addArrow(...positionParams);
|
|
460
|
+
break;
|
|
450
461
|
case PlaceHolderCommands.pin:
|
|
451
462
|
case PlaceHolderCommands.hpin:
|
|
452
463
|
case PlaceHolderCommands.vpin:
|
|
@@ -504,18 +515,16 @@ export class SymbolPlaceholder extends SymbolGraphic {
|
|
|
504
515
|
}
|
|
505
516
|
parseLabelStyle(keywordParams) {
|
|
506
517
|
const keywords = ['fontSize', 'anchor', 'vanchor',
|
|
507
|
-
'angle', 'textColor', 'portType', 'bold'];
|
|
518
|
+
'angle', 'textColor', 'portType', 'bold', 'italic'];
|
|
508
519
|
const style = {};
|
|
509
520
|
keywords.forEach(item => {
|
|
510
521
|
if (keywordParams.has(item)) {
|
|
511
522
|
style[item] = keywordParams.get(item);
|
|
512
523
|
if (item === 'bold') {
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
style['fontWeight'] = 'normal';
|
|
518
|
-
}
|
|
524
|
+
style.fontWeight = keywordParams.get(item) === true ? 'bold' : 'regular';
|
|
525
|
+
}
|
|
526
|
+
else if (item === 'italic') {
|
|
527
|
+
style.fontStyle = keywordParams.get(item) === true ? 'italic' : 'normal';
|
|
519
528
|
}
|
|
520
529
|
}
|
|
521
530
|
});
|
|
@@ -675,6 +684,7 @@ export var PlaceHolderCommands;
|
|
|
675
684
|
PlaceHolderCommands["rect"] = "rect";
|
|
676
685
|
PlaceHolderCommands["crect"] = "crect";
|
|
677
686
|
PlaceHolderCommands["triangle"] = "triangle";
|
|
687
|
+
PlaceHolderCommands["arrow"] = "arrow";
|
|
678
688
|
PlaceHolderCommands["pin"] = "pin";
|
|
679
689
|
PlaceHolderCommands["hpin"] = "hpin";
|
|
680
690
|
PlaceHolderCommands["vpin"] = "vpin";
|
|
@@ -1042,6 +1052,35 @@ export class SymbolDrawing {
|
|
|
1042
1052
|
]));
|
|
1043
1053
|
return this;
|
|
1044
1054
|
}
|
|
1055
|
+
addArrow(startX, startY, endX, endY, arrowLength = numeric(25), arrowWidth = numeric(25)) {
|
|
1056
|
+
startX = milsToMM(startX);
|
|
1057
|
+
startY = milsToMM(startY);
|
|
1058
|
+
endX = milsToMM(endX);
|
|
1059
|
+
endY = milsToMM(endY);
|
|
1060
|
+
arrowLength = milsToMM(arrowLength);
|
|
1061
|
+
arrowWidth = milsToMM(arrowWidth);
|
|
1062
|
+
const dxNum = endX.sub(startX).toNumber();
|
|
1063
|
+
const dyNum = endY.sub(startY).toNumber();
|
|
1064
|
+
const len = Math.sqrt(dxNum * dxNum + dyNum * dyNum);
|
|
1065
|
+
const unitDx = numeric(dxNum / len);
|
|
1066
|
+
const unitDy = numeric(dyNum / len);
|
|
1067
|
+
const arrowBaseX = endX.sub(unitDx.mul(arrowLength));
|
|
1068
|
+
const arrowBaseY = endY.sub(unitDy.mul(arrowLength));
|
|
1069
|
+
this.items.push(Geometry.segment([startX, startY], [arrowBaseX, arrowBaseY]));
|
|
1070
|
+
const perpX = numeric(-unitDy.toNumber());
|
|
1071
|
+
const perpY = numeric(unitDx.toNumber());
|
|
1072
|
+
const dx1 = perpX.mul(arrowWidth).half();
|
|
1073
|
+
const dy1 = perpY.mul(arrowWidth).half();
|
|
1074
|
+
const dx2 = perpX.mul(arrowWidth.neg()).half();
|
|
1075
|
+
const dy2 = perpY.mul(arrowWidth.neg()).half();
|
|
1076
|
+
this.items.push(Geometry.polygon([
|
|
1077
|
+
[dx1.add(arrowBaseX), dy1.add(arrowBaseY)],
|
|
1078
|
+
[dx2.add(arrowBaseX), dy2.add(arrowBaseY)],
|
|
1079
|
+
[endX, endY],
|
|
1080
|
+
[dx1.add(arrowBaseX), dy1.add(arrowBaseY)],
|
|
1081
|
+
]));
|
|
1082
|
+
return this;
|
|
1083
|
+
}
|
|
1045
1084
|
addLabel(x, y, textValue, style) {
|
|
1046
1085
|
this.items.push(Geometry.label(null, x, y, textValue, style));
|
|
1047
1086
|
return this;
|
|
@@ -44,8 +44,8 @@ export class Textbox extends Flatten.Polygon {
|
|
|
44
44
|
else {
|
|
45
45
|
throw 'Invalid string passed into textbox';
|
|
46
46
|
}
|
|
47
|
-
const { fontSize = numeric(50), anchor = HorizontalAlign.Left, vanchor = VerticalAlign.Bottom, fontWeight = 'regular', portType = null, } = style ?? {};
|
|
48
|
-
const { box } = measureTextSize2(useText, defaultFont, fontSize.mul(fontDisplayScale).toNumber(), fontWeight, anchor, vanchor);
|
|
47
|
+
const { fontSize = numeric(50), anchor = HorizontalAlign.Left, vanchor = VerticalAlign.Bottom, fontWeight = 'regular', fontStyle = 'normal', portType = null, } = style ?? {};
|
|
48
|
+
const { box } = measureTextSize2(useText, defaultFont, fontSize.mul(fontDisplayScale).toNumber(), fontWeight, fontStyle, anchor, vanchor);
|
|
49
49
|
let polygonCoords = [];
|
|
50
50
|
let anchorOffsetX = 0;
|
|
51
51
|
let anchorOffsetY = 0;
|
|
@@ -551,12 +551,20 @@ export class LayoutEngine {
|
|
|
551
551
|
const isSheetFrame = frameObject.frameType === FrameType.Sheet;
|
|
552
552
|
if (frameParams.has(FrameParamKeys.Title) && !isSheetFrame) {
|
|
553
553
|
const title = frameParams.get(FrameParamKeys.Title);
|
|
554
|
+
const fontSize = frameParams.get(FrameParamKeys.FontSize) ?? numeric(defaultFrameTitleTextSize);
|
|
555
|
+
const isBold = frameParams.get(FrameParamKeys.Bold) ?? true;
|
|
556
|
+
const isItalic = frameParams.get(FrameParamKeys.Italic) ?? false;
|
|
557
|
+
const titleColor = frameParams.get(FrameParamKeys.Color) ?? null;
|
|
554
558
|
const titleFrame = new RenderFrame(new Frame(FixedFrameIds.FrameIdNotUsed), RenderFrameType.Elements);
|
|
555
559
|
titleFrame.containsTitle = true;
|
|
556
560
|
titleFrame.subgraphId = title.replace(/\s/g, "_");
|
|
557
561
|
const textObject = new RenderText(title);
|
|
558
|
-
textObject.fontSize =
|
|
559
|
-
textObject.fontWeight = 'bold';
|
|
562
|
+
textObject.fontSize = fontSize;
|
|
563
|
+
textObject.fontWeight = isBold ? 'bold' : 'regular';
|
|
564
|
+
textObject.fontStyle = isItalic ? 'italic' : 'normal';
|
|
565
|
+
if (titleColor !== null) {
|
|
566
|
+
textObject.color = titleColor;
|
|
567
|
+
}
|
|
560
568
|
textObject.x = numeric(0);
|
|
561
569
|
textObject.y = numeric(0);
|
|
562
570
|
textObject.symbol.refreshDrawing();
|
|
@@ -1212,6 +1220,8 @@ export class RenderText extends RenderObject {
|
|
|
1212
1220
|
symbol;
|
|
1213
1221
|
_fontSize = numeric(12);
|
|
1214
1222
|
_fontWeight = 'regular';
|
|
1223
|
+
_fontStyle = 'normal';
|
|
1224
|
+
_color = undefined;
|
|
1215
1225
|
get fontSize() {
|
|
1216
1226
|
return this._fontSize;
|
|
1217
1227
|
}
|
|
@@ -1226,6 +1236,20 @@ export class RenderText extends RenderObject {
|
|
|
1226
1236
|
this._fontWeight = value;
|
|
1227
1237
|
this.symbol.fontWeight = value;
|
|
1228
1238
|
}
|
|
1239
|
+
get fontStyle() {
|
|
1240
|
+
return this._fontStyle;
|
|
1241
|
+
}
|
|
1242
|
+
set fontStyle(value) {
|
|
1243
|
+
this._fontStyle = value;
|
|
1244
|
+
this.symbol.fontStyle = value;
|
|
1245
|
+
}
|
|
1246
|
+
get color() {
|
|
1247
|
+
return this._color;
|
|
1248
|
+
}
|
|
1249
|
+
set color(value) {
|
|
1250
|
+
this._color = value;
|
|
1251
|
+
this.symbol.color = value;
|
|
1252
|
+
}
|
|
1229
1253
|
constructor(text) {
|
|
1230
1254
|
super();
|
|
1231
1255
|
this.symbol = new SymbolText(text);
|
package/dist/esm/sizing.js
CHANGED
|
@@ -6,10 +6,10 @@ export function applyFontsToSVG(canvas) {
|
|
|
6
6
|
}
|
|
7
7
|
const measureTextSizeCache = {};
|
|
8
8
|
const measureTextSizeCacheHits = {};
|
|
9
|
-
export function measureTextSize2(text, fontFamily, fontSize, fontWeight = 'regular', anchor = HorizontalAlign.Left, vanchor = VerticalAlign.Bottom) {
|
|
9
|
+
export function measureTextSize2(text, fontFamily, fontSize, fontWeight = 'regular', fontStyle = 'normal', anchor = HorizontalAlign.Left, vanchor = VerticalAlign.Bottom) {
|
|
10
10
|
const environment = NodeScriptEnvironment.getInstance();
|
|
11
11
|
const mainCanvas = environment.getCanvasWindow();
|
|
12
|
-
const key = `${text}-${fontFamily}-${fontSize}-${fontWeight}-${anchor}-${vanchor}`;
|
|
12
|
+
const key = `${text}-${fontFamily}-${fontSize}-${fontWeight}-${fontStyle}-${anchor}-${vanchor}`;
|
|
13
13
|
if (measureTextSizeCache[key] === undefined) {
|
|
14
14
|
let dominantBaseline = VerticalAlignProp.Hanging;
|
|
15
15
|
switch (vanchor) {
|
|
@@ -42,6 +42,7 @@ export function measureTextSize2(text, fontFamily, fontSize, fontWeight = 'regul
|
|
|
42
42
|
anchor: useAnchor,
|
|
43
43
|
'dominant-baseline': dominantBaseline,
|
|
44
44
|
weight: fontWeight,
|
|
45
|
+
style: fontStyle,
|
|
45
46
|
})
|
|
46
47
|
.attr("xml:space", "preserve")
|
|
47
48
|
.fill('#333');
|
package/dist/esm/visitor.js
CHANGED
|
@@ -4,7 +4,7 @@ import { ParamDefinition } from "./objects/ParamDefinition.js";
|
|
|
4
4
|
import { numeric } from "./objects/NumericValue.js";
|
|
5
5
|
import { PinDefinition, PinId, PinIdType } from './objects/PinDefinition.js';
|
|
6
6
|
import { PinTypes } from './objects/PinTypes.js';
|
|
7
|
-
import { AnyReference, DeclaredReference, UndeclaredReference } from './objects/types.js';
|
|
7
|
+
import { AnyReference, DeclaredReference, Direction, UndeclaredReference } from './objects/types.js';
|
|
8
8
|
import { ComponentTypes, Delimiter1, FrameType, GlobalDocumentName, ModuleContainsKeyword, NoNetText, ParamKeys, RefdesFileSuffix, ReferenceTypes, SymbolPinSide, ValidPinSides, WireAutoDirection } from './globals.js';
|
|
9
9
|
import { BlockTypes } from "./objects/BlockTypes.js";
|
|
10
10
|
import { unwrapValue } from "./utils.js";
|
|
@@ -80,7 +80,7 @@ export class ParserVisitor extends BaseVisitor {
|
|
|
80
80
|
return this.getExecutor().getCurrentPoint();
|
|
81
81
|
};
|
|
82
82
|
visitTo_component_expr = (ctx) => {
|
|
83
|
-
ctx.component_select_expr()
|
|
83
|
+
for (const item of ctx.component_select_expr()) {
|
|
84
84
|
let refComponent;
|
|
85
85
|
const creationFlag = this.trackNewComponentCreated(() => {
|
|
86
86
|
const [component, pin] = this.visitResult(item);
|
|
@@ -95,7 +95,7 @@ export class ParserVisitor extends BaseVisitor {
|
|
|
95
95
|
}
|
|
96
96
|
});
|
|
97
97
|
this.linkComponentToCtx(item, refComponent, creationFlag);
|
|
98
|
-
}
|
|
98
|
+
}
|
|
99
99
|
return this.getExecutor().getCurrentPoint();
|
|
100
100
|
};
|
|
101
101
|
visitComponent_select_expr = (ctx) => {
|
|
@@ -154,7 +154,18 @@ export class ParserVisitor extends BaseVisitor {
|
|
|
154
154
|
const blockStackEntry = scope.blockStack.get(scopeLevel);
|
|
155
155
|
const { current_index } = blockStackEntry;
|
|
156
156
|
executor.enterBlock(current_index);
|
|
157
|
-
|
|
157
|
+
const ctxNonNewlineExpressions = ctx.non_newline_expression();
|
|
158
|
+
const ctxExpressionsBlock = ctx.expressions_block();
|
|
159
|
+
const ctxAtBlockExpressions = ctx.at_block_expressions();
|
|
160
|
+
if (ctxNonNewlineExpressions.length > 0) {
|
|
161
|
+
this.runExpressions(executor, ctxNonNewlineExpressions);
|
|
162
|
+
}
|
|
163
|
+
else if (ctxExpressionsBlock) {
|
|
164
|
+
this.visit(ctxExpressionsBlock);
|
|
165
|
+
}
|
|
166
|
+
else if (ctxAtBlockExpressions) {
|
|
167
|
+
this.visit(ctxAtBlockExpressions);
|
|
168
|
+
}
|
|
158
169
|
executor.exitBlock(current_index);
|
|
159
170
|
blockStackEntry.current_index++;
|
|
160
171
|
};
|
|
@@ -226,6 +237,7 @@ export class ParserVisitor extends BaseVisitor {
|
|
|
226
237
|
const suffix = properties.get('suffix') ?? null;
|
|
227
238
|
let pins = [];
|
|
228
239
|
if (display !== null && arrange === null && typeProp !== ComponentTypes.graphic) {
|
|
240
|
+
display.variables = properties.get('params') ?? new Map();
|
|
229
241
|
const drawCommands = display.getCommands();
|
|
230
242
|
drawCommands.forEach(command => {
|
|
231
243
|
const [commandValue,] = command;
|
|
@@ -233,9 +245,11 @@ export class ParserVisitor extends BaseVisitor {
|
|
|
233
245
|
|| commandValue === PlaceHolderCommands.hpin
|
|
234
246
|
|| commandValue === PlaceHolderCommands.pin) {
|
|
235
247
|
const id = PinId.from(command[1][0]);
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
248
|
+
let pinName = id.toString();
|
|
249
|
+
if (typeof command[1][1] === 'string') {
|
|
250
|
+
pinName = command[1][1];
|
|
251
|
+
}
|
|
252
|
+
pins.push(new PinDefinition(id, id.getType(), pinName, PinTypes.Any));
|
|
239
253
|
}
|
|
240
254
|
});
|
|
241
255
|
}
|
|
@@ -689,14 +703,17 @@ export class ParserVisitor extends BaseVisitor {
|
|
|
689
703
|
let shouldIgnoreWireOrientation = false;
|
|
690
704
|
if (modifierText === ParamKeys.flip) {
|
|
691
705
|
const flipValue = result.name;
|
|
706
|
+
let didSetX = false;
|
|
707
|
+
let didSetY = false;
|
|
692
708
|
if (flipValue.indexOf('x') !== -1) {
|
|
693
709
|
defaultUnit.setParam(ParamKeys.flipX, numeric(1));
|
|
694
|
-
|
|
710
|
+
didSetX = true;
|
|
695
711
|
}
|
|
696
712
|
if (flipValue.indexOf('y') !== -1) {
|
|
697
713
|
defaultUnit.setParam(ParamKeys.flipY, numeric(1));
|
|
698
|
-
|
|
714
|
+
didSetY = true;
|
|
699
715
|
}
|
|
716
|
+
shouldIgnoreWireOrientation = didSetX && didSetY;
|
|
700
717
|
}
|
|
701
718
|
else if (modifierText === ParamKeys.angle) {
|
|
702
719
|
defaultUnit.setParam(ParamKeys.angle, result);
|
|
@@ -705,6 +722,9 @@ export class ParserVisitor extends BaseVisitor {
|
|
|
705
722
|
else if (modifierText === 'anchor') {
|
|
706
723
|
dataResult.setParam('anchor', result.name);
|
|
707
724
|
}
|
|
725
|
+
else {
|
|
726
|
+
dataResult.setParam(modifierText, result);
|
|
727
|
+
}
|
|
708
728
|
if (shouldIgnoreWireOrientation) {
|
|
709
729
|
defaultUnit.useWireOrientationAngle = false;
|
|
710
730
|
}
|
|
@@ -959,24 +979,63 @@ export class ParserVisitor extends BaseVisitor {
|
|
|
959
979
|
};
|
|
960
980
|
visitAt_block_pin_expr = (ctx) => {
|
|
961
981
|
const executor = this.getExecutor();
|
|
962
|
-
const
|
|
982
|
+
const scope = this.getScope();
|
|
983
|
+
const scopeLevel = scope.scopeLevel;
|
|
984
|
+
const params = this.getResult(ctx);
|
|
985
|
+
const blockIndex = params.index;
|
|
986
|
+
let useComponent;
|
|
987
|
+
for (let i = scopeLevel - 1; i >= 0; i--) {
|
|
988
|
+
const blockStackEntry = scope.blockStack.get(i);
|
|
989
|
+
if (blockStackEntry.type === BlockTypes.AtBlock) {
|
|
990
|
+
useComponent = blockStackEntry.start_point[0];
|
|
991
|
+
break;
|
|
992
|
+
}
|
|
993
|
+
}
|
|
963
994
|
executor.closeOpenPathBlocks();
|
|
964
995
|
const propKey = this.visitResult(ctx.property_key_expr());
|
|
965
996
|
const atPin = new PinId(propKey);
|
|
966
|
-
executor.atComponent(
|
|
997
|
+
executor.atComponent(useComponent, atPin, {
|
|
967
998
|
addSequence: true
|
|
968
999
|
});
|
|
969
|
-
executor.log(
|
|
970
|
-
const ctxExpression = ctx.
|
|
1000
|
+
executor.log(`at block pin expressions, pin id: ${atPin}`);
|
|
1001
|
+
const ctxExpression = ctx.non_newline_expression();
|
|
971
1002
|
const ctxExpressionsBlock = ctx.expressions_block();
|
|
972
|
-
if (ctxExpression) {
|
|
973
|
-
this.
|
|
1003
|
+
if (ctxExpression.length > 0) {
|
|
1004
|
+
this.runExpressions(executor, ctxExpression);
|
|
974
1005
|
}
|
|
975
1006
|
else if (ctxExpressionsBlock) {
|
|
976
1007
|
this.visit(ctxExpressionsBlock);
|
|
977
1008
|
}
|
|
978
|
-
|
|
979
|
-
|
|
1009
|
+
const parentBlockStackEntry = scope.blockStack.get(scopeLevel - 1);
|
|
1010
|
+
if (parentBlockStackEntry.type === BlockTypes.Join) {
|
|
1011
|
+
if (blockIndex === 0 && parentBlockStackEntry.current_index === 0) {
|
|
1012
|
+
executor.addPointForBlockType(BlockTypes.Join);
|
|
1013
|
+
parentBlockStackEntry.end_point = [
|
|
1014
|
+
scope.currentComponent,
|
|
1015
|
+
scope.currentPin,
|
|
1016
|
+
scope.currentWireId
|
|
1017
|
+
];
|
|
1018
|
+
}
|
|
1019
|
+
else {
|
|
1020
|
+
const { end_point: finalPoint } = parentBlockStackEntry;
|
|
1021
|
+
const [component, pin] = finalPoint;
|
|
1022
|
+
executor.toComponent(component, pin, { addSequence: true });
|
|
1023
|
+
}
|
|
1024
|
+
}
|
|
1025
|
+
};
|
|
1026
|
+
visitAt_block_expressions = (ctx) => {
|
|
1027
|
+
let atBlockPinIndex = 0;
|
|
1028
|
+
for (const tmpCtx of ctx.at_block_expressions_inner()) {
|
|
1029
|
+
const ctxAtBlockPin = tmpCtx.at_block_pin_expr();
|
|
1030
|
+
if (ctxAtBlockPin) {
|
|
1031
|
+
this.setResult(ctxAtBlockPin, { index: atBlockPinIndex });
|
|
1032
|
+
atBlockPinIndex++;
|
|
1033
|
+
this.visit(ctxAtBlockPin);
|
|
1034
|
+
}
|
|
1035
|
+
else {
|
|
1036
|
+
this.visit(tmpCtx.expression());
|
|
1037
|
+
}
|
|
1038
|
+
}
|
|
980
1039
|
};
|
|
981
1040
|
visitAt_block_header = (ctx) => {
|
|
982
1041
|
const ctxAtComponent = ctx.at_component_expr();
|
|
@@ -990,33 +1049,65 @@ export class ParserVisitor extends BaseVisitor {
|
|
|
990
1049
|
};
|
|
991
1050
|
visitAt_block = (ctx) => {
|
|
992
1051
|
const executor = this.getExecutor();
|
|
993
|
-
|
|
1052
|
+
const scope = this.getScope();
|
|
1053
|
+
const scopeLevel = scope.scopeLevel;
|
|
1054
|
+
if (scope.blockStack.has(scopeLevel)) {
|
|
1055
|
+
executor.exitBlocks();
|
|
1056
|
+
}
|
|
994
1057
|
const ctxAtBlockComponent = ctx.at_block_header();
|
|
995
1058
|
this.visit(ctxAtBlockComponent);
|
|
996
1059
|
const [currentComponent, currentPin] = executor.getCurrentPoint();
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1060
|
+
scope.blockStack.set(scopeLevel, {
|
|
1061
|
+
start_point: [
|
|
1062
|
+
scope.currentComponent,
|
|
1063
|
+
scope.currentPin,
|
|
1064
|
+
scope.currentWireId
|
|
1065
|
+
],
|
|
1066
|
+
end_point: null,
|
|
1067
|
+
current_index: 0,
|
|
1068
|
+
type: BlockTypes.AtBlock,
|
|
1000
1069
|
});
|
|
1070
|
+
executor.log('entering at block');
|
|
1071
|
+
executor.scope.scopeLevel += 1;
|
|
1072
|
+
this.visit(ctx.at_block_expressions());
|
|
1001
1073
|
executor.scope.scopeLevel -= 1;
|
|
1002
1074
|
executor.scope.setCurrent(currentComponent, currentPin);
|
|
1075
|
+
scope.blockStack.delete(scopeLevel);
|
|
1003
1076
|
executor.log('leaving at block');
|
|
1004
1077
|
};
|
|
1005
1078
|
visitWire_expr = (ctx) => {
|
|
1006
1079
|
const segments = [];
|
|
1007
1080
|
ctx.ID().forEach((ctxId, index) => {
|
|
1008
|
-
const
|
|
1081
|
+
const valueText = ctxId.getText();
|
|
1009
1082
|
const ctxDataExpr = ctx.data_expr(index);
|
|
1010
|
-
|
|
1011
|
-
|
|
1083
|
+
let value = null;
|
|
1084
|
+
switch (valueText) {
|
|
1085
|
+
case 'right':
|
|
1086
|
+
case 'rg':
|
|
1087
|
+
case 'r':
|
|
1088
|
+
value = Direction.Right;
|
|
1089
|
+
break;
|
|
1090
|
+
case 'left':
|
|
1091
|
+
case 'lf':
|
|
1092
|
+
case 'l':
|
|
1093
|
+
value = Direction.Left;
|
|
1094
|
+
break;
|
|
1095
|
+
case 'up':
|
|
1096
|
+
case 'u':
|
|
1097
|
+
value = Direction.Up;
|
|
1098
|
+
break;
|
|
1099
|
+
case 'down':
|
|
1100
|
+
case 'dw':
|
|
1101
|
+
case 'd':
|
|
1102
|
+
value = Direction.Down;
|
|
1103
|
+
break;
|
|
1104
|
+
}
|
|
1105
|
+
if ((valueText === WireAutoDirection.Auto || valueText === WireAutoDirection.Auto_) && ctxDataExpr === null) {
|
|
1106
|
+
segments.push([valueText]);
|
|
1012
1107
|
}
|
|
1013
1108
|
else if (this.acceptedDirections.indexOf(value) !== -1 && ctxDataExpr) {
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
if (useValue instanceof NumericValue) {
|
|
1017
|
-
useValue = useValue.toNumber();
|
|
1018
|
-
}
|
|
1019
|
-
segments.push([value, new UnitDimension(useValue)]);
|
|
1109
|
+
const useValue = this.visitResult(ctxDataExpr);
|
|
1110
|
+
segments.push([value, new UnitDimension(useValue.toNumber())]);
|
|
1020
1111
|
}
|
|
1021
1112
|
else {
|
|
1022
1113
|
this.throwWithContext(ctx, "Invalid wire expression");
|
|
@@ -1072,9 +1163,12 @@ export class ParserVisitor extends BaseVisitor {
|
|
|
1072
1163
|
if (ctx.Sheet()) {
|
|
1073
1164
|
frameType = FrameType.Sheet;
|
|
1074
1165
|
}
|
|
1075
|
-
const
|
|
1076
|
-
|
|
1077
|
-
|
|
1166
|
+
const ctxExpressionsBlock = ctx.expressions_block();
|
|
1167
|
+
if (ctxExpressionsBlock) {
|
|
1168
|
+
const frameId = this.getExecutor().enterFrame(frameType);
|
|
1169
|
+
this.visit(ctxExpressionsBlock);
|
|
1170
|
+
this.getExecutor().exitFrame(frameId);
|
|
1171
|
+
}
|
|
1078
1172
|
};
|
|
1079
1173
|
visitNet_namespace_expr = (ctx) => {
|
|
1080
1174
|
let dataValue;
|