circuitscript 0.0.31 → 0.0.32

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.
@@ -779,6 +779,7 @@ class ExecutionContext {
779
779
  enterFrame() {
780
780
  const frameId = this.scope.frames.length + 1;
781
781
  const frameObject = new Frame_js_1.Frame(frameId);
782
+ this.log('Enter frame', frameId);
782
783
  this.scope.frames.push(frameObject);
783
784
  this.scope.sequence.push([ExecutionScope_js_1.SequenceAction.Frame,
784
785
  frameObject, ExecutionScope_js_1.FrameAction.Enter]);
@@ -790,6 +791,7 @@ class ExecutionContext {
790
791
  const frame = this.scope.frames[frameId - 1];
791
792
  this.scope.sequence.push([ExecutionScope_js_1.SequenceAction.Frame,
792
793
  frame, ExecutionScope_js_1.FrameAction.Exit]);
794
+ this.log('Leave frame', frameId);
793
795
  }
794
796
  }
795
797
  exports.ExecutionContext = ExecutionContext;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.BlockTypes = exports.ReferenceTypes = exports.ComponentTypes = exports.ColorScheme = exports.PortPaddingVertical = exports.PortPaddingHorizontal = exports.PortArrowSize = exports.junctionSize = exports.defaultFontSize = exports.defaultFontBold = exports.defaultFont = exports.displayUnits = exports.defaultFrameTitleTextSize = exports.CustomSymbolParamTextSize = exports.CustomSymbolRefDesSize = exports.CustomSymbolPinIdSize = exports.CustomSymbolPinTextSize = exports.defaultPinIdTextSize = exports.defaultPinNameTextSize = exports.defaultWireLineWidth = exports.defaultSymbolLineWidth = exports.fontDisplayScale = exports.defaultZoomScale = exports.defaultGridSizeUnits = exports.portHeight = exports.portWidth = exports.PxToMM = exports.MMToPx = exports.MilsToMM = exports.WireAutoDirection = exports.LengthUnit = exports.SymbolPinSide = exports.LayoutDirection = exports.ParamKeys = exports.NoNetText = exports.GlobalNames = void 0;
3
+ exports.BlockTypes = exports.ReferenceTypes = exports.ComponentTypes = exports.ColorScheme = exports.PortPaddingVertical = exports.PortPaddingHorizontal = exports.PortArrowSize = exports.junctionSize = exports.defaultFontSize = exports.defaultFontBold = exports.defaultFont = exports.displayUnits = exports.defaultFrameTitleTextSize = exports.CustomSymbolParamTextSize = exports.CustomSymbolRefDesSize = exports.CustomSymbolPinIdSize = exports.CustomSymbolPinTextSize = exports.defaultPinIdTextSize = exports.defaultPinNameTextSize = exports.defaultWireLineWidth = exports.defaultSymbolLineWidth = exports.fontDisplayScale = exports.defaultZoomScale = exports.defaultGridSizeUnits = exports.portHeight = exports.portWidth = exports.PxToMM = exports.MMToPt = exports.MMToPx = exports.MilsToMM = exports.WireAutoDirection = exports.LengthUnit = exports.SymbolPinSide = exports.LayoutDirection = exports.ParamKeys = exports.NoNetText = exports.GlobalNames = void 0;
4
4
  var GlobalNames;
5
5
  (function (GlobalNames) {
6
6
  GlobalNames["__root"] = "__root";
@@ -39,6 +39,7 @@ var WireAutoDirection;
39
39
  })(WireAutoDirection || (exports.WireAutoDirection = WireAutoDirection = {}));
40
40
  exports.MilsToMM = 0.0254;
41
41
  exports.MMToPx = 3.779276;
42
+ exports.MMToPt = 2.8346456693;
42
43
  exports.PxToMM = 0.2645833;
43
44
  exports.portWidth = 20;
44
45
  exports.portHeight = 2;
@@ -5,6 +5,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.pxToMM = exports.milsToMM = exports.UnitDimension = exports.getPackageVersion = exports.getDefaultLibsPath = exports.getFontsPath = exports.getCurrentPath = exports.detectJSModuleType = exports.renderScript = exports.validateScript = exports.ParseErrorStrategy = exports.getSemanticTokens = exports.getScriptText = exports.prepareFile = exports.JSModuleType = void 0;
7
7
  const fs_1 = require("fs");
8
+ const pdfkit_1 = __importDefault(require("pdfkit"));
9
+ const svg_to_pdfkit_1 = __importDefault(require("svg-to-pdfkit"));
8
10
  const export_js_1 = require("./export.js");
9
11
  const layout_js_1 = require("./layout.js");
10
12
  const ExecutionScope_js_1 = require("./objects/ExecutionScope.js");
@@ -219,17 +221,47 @@ function renderScript(scriptData, outputPath, options) {
219
221
  dumpData && (0, fs_1.writeFileSync)('dump/raw-sequence.txt', tmpSequence.join('\n'));
220
222
  let svgOutput = null;
221
223
  try {
222
- const layoutEngine = new layout_js_1.LayoutEngine();
224
+ let fileExtension = null;
225
+ let showBaseFrame = false;
226
+ if (outputPath) {
227
+ fileExtension = path_1.default.extname(outputPath).substring(1);
228
+ if (fileExtension === 'pdf') {
229
+ showBaseFrame = true;
230
+ }
231
+ }
232
+ const layoutEngine = new layout_js_1.LayoutEngine({
233
+ showBaseFrame,
234
+ });
223
235
  const layoutTimer = new utils_js_1.SimpleStopwatch();
224
236
  const graph = layoutEngine.runLayout(sequence, nets);
225
237
  layoutEngine.printWarnings();
226
238
  showStats && console.log('Layout took:', layoutTimer.lap());
227
239
  dumpData && (0, fs_1.writeFileSync)('dump/raw-layout.txt', layoutEngine.logger.dump());
228
240
  const generateSvgTimer = new utils_js_1.SimpleStopwatch();
229
- svgOutput = (0, render_js_1.generateSVG2)(graph);
241
+ const { svg: generatedSvg, width: svgWidth, height: svgHeight } = (0, render_js_1.generateSVG2)(graph);
242
+ svgOutput = generatedSvg;
230
243
  showStats && console.log('Render took:', generateSvgTimer.lap());
231
244
  if (outputPath) {
232
- (0, fs_1.writeFileSync)(outputPath, svgOutput);
245
+ if (fileExtension === 'svg') {
246
+ (0, fs_1.writeFileSync)(outputPath, svgOutput);
247
+ }
248
+ else if (fileExtension === 'pdf') {
249
+ const doc = new pdfkit_1.default({
250
+ layout: 'landscape',
251
+ size: 'A4',
252
+ });
253
+ const outputStream = (0, fs_1.createWriteStream)(outputPath);
254
+ const paperWidthMM = 297;
255
+ const paperHeightMM = 210;
256
+ const xOffset = (paperWidthMM - svgWidth) / 2;
257
+ const yOffset = (paperHeightMM - svgHeight) / 2;
258
+ (0, svg_to_pdfkit_1.default)(doc, svgOutput, xOffset * globals_js_1.MMToPt, yOffset * globals_js_1.MMToPt);
259
+ doc.pipe(outputStream);
260
+ doc.end();
261
+ }
262
+ else {
263
+ throw "Invalid output format";
264
+ }
233
265
  console.log('Generated file', outputPath);
234
266
  }
235
267
  }
@@ -13,10 +13,13 @@ const utils_js_1 = require("./utils.js");
13
13
  const types_js_1 = require("./objects/types.js");
14
14
  const helpers_js_1 = require("./helpers.js");
15
15
  class LayoutEngine {
16
- constructor() {
16
+ constructor(options = { showBaseFrame: false }) {
17
17
  this.placeSubgraphVersion = 2;
18
18
  this.layoutWarnings = [];
19
+ this.showBaseFrame = false;
19
20
  this.logger = new logger_js_1.Logger();
21
+ const { showBaseFrame = false } = options ?? {};
22
+ this.showBaseFrame = showBaseFrame;
20
23
  }
21
24
  print(...params) {
22
25
  this.logger.add(params.join(' '));
@@ -124,6 +127,11 @@ class LayoutEngine {
124
127
  const baseFrame = frameObjects[0];
125
128
  baseFrame.padding = 0;
126
129
  baseFrame.borderWidth = 0;
130
+ if (this.showBaseFrame) {
131
+ baseFrame.borderWidth = 5;
132
+ baseFrame.width = 11692 - 400 * 2;
133
+ baseFrame.height = 8267 - 400 * 2;
134
+ }
127
135
  baseFrame.x = 0;
128
136
  baseFrame.y = 0;
129
137
  let textObjects = [];
@@ -136,7 +144,7 @@ class LayoutEngine {
136
144
  const result = this.prepareFrames(graph, subgraphInfo, baseFrame);
137
145
  textObjects = result.textObjects;
138
146
  elementFrames = result.elementFrames;
139
- const logFrames = false;
147
+ const logFrames = true;
140
148
  if (logFrames) {
141
149
  this.print('===== dump frames =====');
142
150
  this.dumpFrame(baseFrame);
@@ -260,6 +268,12 @@ class LayoutEngine {
260
268
  boundPoints.push([innerFrame.x, innerFrame.y], [innerFrame.x + frameWidth, innerFrame.y + frameHeight]);
261
269
  });
262
270
  frame.bounds = (0, utils_js_1.resizeBounds)(getBoundsFromPoints(boundPoints), frame.padding);
271
+ if (frame.width !== null) {
272
+ frame.bounds.xmax = (0, helpers_js_1.milsToMM)(frame.bounds.xmin + frame.width);
273
+ }
274
+ if (frame.height !== null) {
275
+ frame.bounds.ymax = (0, helpers_js_1.milsToMM)(frame.bounds.ymin + frame.height);
276
+ }
263
277
  }
264
278
  dumpFrame(frame, level = 0) {
265
279
  this.print(level, "".padStart(level * 4), 'frame, items:', frame.innerItems.length);
@@ -497,6 +511,14 @@ class LayoutEngine {
497
511
  newFrame.borderWidth =
498
512
  frameObject.parameters.get(Frame_js_1.FrameParamKeys.Border);
499
513
  }
514
+ if (frameObject.parameters.has(Frame_js_1.FrameParamKeys.Width)) {
515
+ newFrame.width =
516
+ frameObject.parameters.get(Frame_js_1.FrameParamKeys.Width);
517
+ }
518
+ if (frameObject.parameters.has(Frame_js_1.FrameParamKeys.Height)) {
519
+ newFrame.height =
520
+ frameObject.parameters.get(Frame_js_1.FrameParamKeys.Height);
521
+ }
500
522
  containerFrames.push(newFrame);
501
523
  frameStack.push(newFrame);
502
524
  prevFrame && prevFrame.innerItems.push(newFrame);
@@ -658,14 +680,20 @@ class LayoutEngine {
658
680
  floatingNode.isFloating = false;
659
681
  this.print('set node as not floating:', floatingNode);
660
682
  const originNode = findOriginNode(fixedNode);
661
- originNodeGroups.get(originNode).push(floatingNode);
662
- this.print('linking node', floatingNode, 'to origin node', originNode);
683
+ const itemsArray = originNodeGroups.get(originNode);
684
+ if (itemsArray.indexOf(floatingNode) === -1) {
685
+ itemsArray.push(floatingNode);
686
+ this.print('linking node', floatingNode, 'to origin node', originNode);
687
+ }
688
+ else {
689
+ this.print('node is alread linked', floatingNode, 'to origin node', originNode);
690
+ }
663
691
  }
664
692
  [node1, node2].forEach(item => {
665
693
  if (item instanceof RenderWire && item.isEndAutoLength()) {
666
694
  const [instance, pin] = item.getEndAuto();
667
695
  const [, targetNode] = graph.node(instance.instanceName);
668
- this.print('wire auto length to target:', instance, pin);
696
+ this.print('wire', item, 'auto length to target:', instance, pin);
669
697
  if (targetNode.isFloating) {
670
698
  throw "Cannot create auto wire with floating node! Wire id: " + item.id + " to node " + instance + " pin " + pin;
671
699
  }
@@ -676,6 +704,7 @@ class LayoutEngine {
676
704
  }
677
705
  const [untilX, untilY] = getNodePositionAtPin(targetNode, pin);
678
706
  item.setEndAuto(untilX, untilY);
707
+ this.print(`set wire auto end at: ${untilX} ${untilY}`);
679
708
  }
680
709
  });
681
710
  });
@@ -1230,6 +1259,8 @@ class RenderFrame extends RenderObject {
1230
1259
  this.gap = (0, helpers_js_1.milsToMM)(100);
1231
1260
  this.direction = Frame_js_1.FramePlotDirection.Column;
1232
1261
  this.borderWidth = 5;
1262
+ this.width = null;
1263
+ this.height = null;
1233
1264
  this.subgraphId = "";
1234
1265
  this.containsTitle = false;
1235
1266
  this.frame = frame;
@@ -14,6 +14,8 @@ var FrameParamKeys;
14
14
  FrameParamKeys["Direction"] = "direction";
15
15
  FrameParamKeys["Padding"] = "padding";
16
16
  FrameParamKeys["Border"] = "border";
17
+ FrameParamKeys["Width"] = "width";
18
+ FrameParamKeys["Height"] = "height";
17
19
  })(FrameParamKeys || (exports.FrameParamKeys = FrameParamKeys = {}));
18
20
  var FramePlotDirection;
19
21
  (function (FramePlotDirection) {
@@ -15,14 +15,16 @@ function generateSVG2(graph) {
15
15
  const canvas = (0, svg_js_1.SVG)(document.documentElement);
16
16
  (0, sizing_js_1.applyFontsToSVG)(canvas);
17
17
  generateSVGChild(canvas, graph.components, graph.wires, graph.junctions, graph.mergedWires, graph.frameObjects, graph.textObjects);
18
- const { x, y, width, height } = canvas.bbox();
19
- const margin = (0, helpers_js_1.milsToMM)(10);
20
- const widthAndMargin = width + margin * 2;
21
- const heightAndMargin = height + margin * 2;
22
18
  const scale = globals_js_1.MMToPx * globals_js_1.defaultZoomScale;
23
- canvas.size(widthAndMargin * scale, heightAndMargin * scale);
24
- canvas.viewbox(x - margin, y - margin, widthAndMargin, heightAndMargin);
25
- return canvas.svg();
19
+ const { x, y, width, height } = canvas.bbox();
20
+ const scaledWidth = width * scale;
21
+ const scaledHeight = height * scale;
22
+ canvas.size(scaledWidth, scaledHeight);
23
+ canvas.viewbox(x, y, width, height);
24
+ return {
25
+ svg: canvas.svg(),
26
+ width, height,
27
+ };
26
28
  }
27
29
  exports.generateSVG2 = generateSVG2;
28
30
  function generateSVGChild(canvas, components, wires, junctions, mergedWires, frameObjects, textObjects) {
@@ -71,8 +73,8 @@ function generateSVGChild(canvas, components, wires, junctions, mergedWires, fra
71
73
  wires.forEach(wire => {
72
74
  wiresGroup.text(wire.id.toString())
73
75
  .font({
74
- family: 'Inter',
75
- size: 10,
76
+ family: 'Arial',
77
+ size: 50 * globals_js_1.fontDisplayScale,
76
78
  })
77
79
  .translate(wire.x + 5, wire.y + 5);
78
80
  });
@@ -783,6 +783,7 @@ export class ExecutionContext {
783
783
  enterFrame() {
784
784
  const frameId = this.scope.frames.length + 1;
785
785
  const frameObject = new Frame(frameId);
786
+ this.log('Enter frame', frameId);
786
787
  this.scope.frames.push(frameObject);
787
788
  this.scope.sequence.push([SequenceAction.Frame,
788
789
  frameObject, FrameAction.Enter]);
@@ -794,6 +795,7 @@ export class ExecutionContext {
794
795
  const frame = this.scope.frames[frameId - 1];
795
796
  this.scope.sequence.push([SequenceAction.Frame,
796
797
  frame, FrameAction.Exit]);
798
+ this.log('Leave frame', frameId);
797
799
  }
798
800
  }
799
801
  function isWireSegmentsEndAuto(segments) {
@@ -36,6 +36,7 @@ export var WireAutoDirection;
36
36
  })(WireAutoDirection || (WireAutoDirection = {}));
37
37
  export const MilsToMM = 0.0254;
38
38
  export const MMToPx = 3.779276;
39
+ export const MMToPt = 2.8346456693;
39
40
  export const PxToMM = 0.2645833;
40
41
  export const portWidth = 20;
41
42
  export const portHeight = 2;
@@ -1,4 +1,6 @@
1
- import { readFileSync, writeFileSync } from "fs";
1
+ import { readFileSync, writeFileSync, createWriteStream } from "fs";
2
+ import PDFDocument from "pdfkit";
3
+ import SVGtoPDF from "svg-to-pdfkit";
2
4
  import { generateKiCADNetList, printTree } from "./export.mjs";
3
5
  import { LayoutEngine } from "./layout.mjs";
4
6
  import { SequenceAction } from "./objects/ExecutionScope.mjs";
@@ -13,7 +15,7 @@ import { MainLexer } from "./lexer.mjs";
13
15
  import { CircuitScriptParser } from "./antlr/CircuitScriptParser.mjs";
14
16
  import { prepareTokens, SemanticTokensVisitor } from "./SemanticTokenVisitor.mjs";
15
17
  import path from "path";
16
- import { LengthUnit, MilsToMM, PxToMM } from "./globals.mjs";
18
+ import { LengthUnit, MilsToMM, MMToPt, PxToMM } from "./globals.mjs";
17
19
  export var JSModuleType;
18
20
  (function (JSModuleType) {
19
21
  JSModuleType["CommonJs"] = "cjs";
@@ -208,17 +210,47 @@ export function renderScript(scriptData, outputPath, options) {
208
210
  dumpData && writeFileSync('dump/raw-sequence.txt', tmpSequence.join('\n'));
209
211
  let svgOutput = null;
210
212
  try {
211
- const layoutEngine = new LayoutEngine();
213
+ let fileExtension = null;
214
+ let showBaseFrame = false;
215
+ if (outputPath) {
216
+ fileExtension = path.extname(outputPath).substring(1);
217
+ if (fileExtension === 'pdf') {
218
+ showBaseFrame = true;
219
+ }
220
+ }
221
+ const layoutEngine = new LayoutEngine({
222
+ showBaseFrame,
223
+ });
212
224
  const layoutTimer = new SimpleStopwatch();
213
225
  const graph = layoutEngine.runLayout(sequence, nets);
214
226
  layoutEngine.printWarnings();
215
227
  showStats && console.log('Layout took:', layoutTimer.lap());
216
228
  dumpData && writeFileSync('dump/raw-layout.txt', layoutEngine.logger.dump());
217
229
  const generateSvgTimer = new SimpleStopwatch();
218
- svgOutput = generateSVG2(graph);
230
+ const { svg: generatedSvg, width: svgWidth, height: svgHeight } = generateSVG2(graph);
231
+ svgOutput = generatedSvg;
219
232
  showStats && console.log('Render took:', generateSvgTimer.lap());
220
233
  if (outputPath) {
221
- writeFileSync(outputPath, svgOutput);
234
+ if (fileExtension === 'svg') {
235
+ writeFileSync(outputPath, svgOutput);
236
+ }
237
+ else if (fileExtension === 'pdf') {
238
+ const doc = new PDFDocument({
239
+ layout: 'landscape',
240
+ size: 'A4',
241
+ });
242
+ const outputStream = createWriteStream(outputPath);
243
+ const paperWidthMM = 297;
244
+ const paperHeightMM = 210;
245
+ const xOffset = (paperWidthMM - svgWidth) / 2;
246
+ const yOffset = (paperHeightMM - svgHeight) / 2;
247
+ SVGtoPDF(doc, svgOutput, xOffset * MMToPt, yOffset * MMToPt);
248
+ doc.pipe(outputStream);
249
+ doc.end();
250
+ }
251
+ else {
252
+ throw "Invalid output format";
253
+ }
222
254
  console.log('Generated file', outputPath);
223
255
  }
224
256
  }
@@ -13,8 +13,11 @@ export class LayoutEngine {
13
13
  logger;
14
14
  placeSubgraphVersion = 2;
15
15
  layoutWarnings = [];
16
- constructor() {
16
+ showBaseFrame = false;
17
+ constructor(options = { showBaseFrame: false }) {
17
18
  this.logger = new Logger();
19
+ const { showBaseFrame = false } = options ?? {};
20
+ this.showBaseFrame = showBaseFrame;
18
21
  }
19
22
  print(...params) {
20
23
  this.logger.add(params.join(' '));
@@ -122,6 +125,11 @@ export class LayoutEngine {
122
125
  const baseFrame = frameObjects[0];
123
126
  baseFrame.padding = 0;
124
127
  baseFrame.borderWidth = 0;
128
+ if (this.showBaseFrame) {
129
+ baseFrame.borderWidth = 5;
130
+ baseFrame.width = 11692 - 400 * 2;
131
+ baseFrame.height = 8267 - 400 * 2;
132
+ }
125
133
  baseFrame.x = 0;
126
134
  baseFrame.y = 0;
127
135
  let textObjects = [];
@@ -134,7 +142,7 @@ export class LayoutEngine {
134
142
  const result = this.prepareFrames(graph, subgraphInfo, baseFrame);
135
143
  textObjects = result.textObjects;
136
144
  elementFrames = result.elementFrames;
137
- const logFrames = false;
145
+ const logFrames = true;
138
146
  if (logFrames) {
139
147
  this.print('===== dump frames =====');
140
148
  this.dumpFrame(baseFrame);
@@ -258,6 +266,12 @@ export class LayoutEngine {
258
266
  boundPoints.push([innerFrame.x, innerFrame.y], [innerFrame.x + frameWidth, innerFrame.y + frameHeight]);
259
267
  });
260
268
  frame.bounds = resizeBounds(getBoundsFromPoints(boundPoints), frame.padding);
269
+ if (frame.width !== null) {
270
+ frame.bounds.xmax = milsToMM(frame.bounds.xmin + frame.width);
271
+ }
272
+ if (frame.height !== null) {
273
+ frame.bounds.ymax = milsToMM(frame.bounds.ymin + frame.height);
274
+ }
261
275
  }
262
276
  dumpFrame(frame, level = 0) {
263
277
  this.print(level, "".padStart(level * 4), 'frame, items:', frame.innerItems.length);
@@ -495,6 +509,14 @@ export class LayoutEngine {
495
509
  newFrame.borderWidth =
496
510
  frameObject.parameters.get(FrameParamKeys.Border);
497
511
  }
512
+ if (frameObject.parameters.has(FrameParamKeys.Width)) {
513
+ newFrame.width =
514
+ frameObject.parameters.get(FrameParamKeys.Width);
515
+ }
516
+ if (frameObject.parameters.has(FrameParamKeys.Height)) {
517
+ newFrame.height =
518
+ frameObject.parameters.get(FrameParamKeys.Height);
519
+ }
498
520
  containerFrames.push(newFrame);
499
521
  frameStack.push(newFrame);
500
522
  prevFrame && prevFrame.innerItems.push(newFrame);
@@ -656,14 +678,20 @@ export class LayoutEngine {
656
678
  floatingNode.isFloating = false;
657
679
  this.print('set node as not floating:', floatingNode);
658
680
  const originNode = findOriginNode(fixedNode);
659
- originNodeGroups.get(originNode).push(floatingNode);
660
- this.print('linking node', floatingNode, 'to origin node', originNode);
681
+ const itemsArray = originNodeGroups.get(originNode);
682
+ if (itemsArray.indexOf(floatingNode) === -1) {
683
+ itemsArray.push(floatingNode);
684
+ this.print('linking node', floatingNode, 'to origin node', originNode);
685
+ }
686
+ else {
687
+ this.print('node is alread linked', floatingNode, 'to origin node', originNode);
688
+ }
661
689
  }
662
690
  [node1, node2].forEach(item => {
663
691
  if (item instanceof RenderWire && item.isEndAutoLength()) {
664
692
  const [instance, pin] = item.getEndAuto();
665
693
  const [, targetNode] = graph.node(instance.instanceName);
666
- this.print('wire auto length to target:', instance, pin);
694
+ this.print('wire', item, 'auto length to target:', instance, pin);
667
695
  if (targetNode.isFloating) {
668
696
  throw "Cannot create auto wire with floating node! Wire id: " + item.id + " to node " + instance + " pin " + pin;
669
697
  }
@@ -674,6 +702,7 @@ export class LayoutEngine {
674
702
  }
675
703
  const [untilX, untilY] = getNodePositionAtPin(targetNode, pin);
676
704
  item.setEndAuto(untilX, untilY);
705
+ this.print(`set wire auto end at: ${untilX} ${untilY}`);
677
706
  }
678
707
  });
679
708
  });
@@ -1226,6 +1255,8 @@ export class RenderFrame extends RenderObject {
1226
1255
  gap = milsToMM(100);
1227
1256
  direction = FramePlotDirection.Column;
1228
1257
  borderWidth = 5;
1258
+ width = null;
1259
+ height = null;
1229
1260
  subgraphId = "";
1230
1261
  type;
1231
1262
  containsTitle = false;
@@ -11,6 +11,8 @@ export var FrameParamKeys;
11
11
  FrameParamKeys["Direction"] = "direction";
12
12
  FrameParamKeys["Padding"] = "padding";
13
13
  FrameParamKeys["Border"] = "border";
14
+ FrameParamKeys["Width"] = "width";
15
+ FrameParamKeys["Height"] = "height";
14
16
  })(FrameParamKeys || (FrameParamKeys = {}));
15
17
  export var FramePlotDirection;
16
18
  (function (FramePlotDirection) {
@@ -1,7 +1,7 @@
1
1
  import { SVG, registerWindow } from '@svgdotjs/svg.js';
2
2
  import { RenderFrameType, getBounds } from "./layout.mjs";
3
3
  import { applyFontsToSVG, getCreateSVGWindow } from './sizing.mjs';
4
- import { ColorScheme, ComponentTypes, MMToPx, ParamKeys, defaultGridSizeUnits, defaultWireLineWidth, defaultZoomScale, junctionSize } from './globals.mjs';
4
+ import { ColorScheme, ComponentTypes, MMToPx, ParamKeys, defaultGridSizeUnits, defaultWireLineWidth, defaultZoomScale, fontDisplayScale, junctionSize } from './globals.mjs';
5
5
  import { NumericValue } from './objects/ParamDefinition.mjs';
6
6
  import { getBoundsSize } from './utils.mjs';
7
7
  import { milsToMM } from './helpers.mjs';
@@ -12,14 +12,16 @@ export function generateSVG2(graph) {
12
12
  const canvas = SVG(document.documentElement);
13
13
  applyFontsToSVG(canvas);
14
14
  generateSVGChild(canvas, graph.components, graph.wires, graph.junctions, graph.mergedWires, graph.frameObjects, graph.textObjects);
15
- const { x, y, width, height } = canvas.bbox();
16
- const margin = milsToMM(10);
17
- const widthAndMargin = width + margin * 2;
18
- const heightAndMargin = height + margin * 2;
19
15
  const scale = MMToPx * defaultZoomScale;
20
- canvas.size(widthAndMargin * scale, heightAndMargin * scale);
21
- canvas.viewbox(x - margin, y - margin, widthAndMargin, heightAndMargin);
22
- return canvas.svg();
16
+ const { x, y, width, height } = canvas.bbox();
17
+ const scaledWidth = width * scale;
18
+ const scaledHeight = height * scale;
19
+ canvas.size(scaledWidth, scaledHeight);
20
+ canvas.viewbox(x, y, width, height);
21
+ return {
22
+ svg: canvas.svg(),
23
+ width, height,
24
+ };
23
25
  }
24
26
  function generateSVGChild(canvas, components, wires, junctions, mergedWires, frameObjects, textObjects) {
25
27
  const displayWireId = false;
@@ -67,8 +69,8 @@ function generateSVGChild(canvas, components, wires, junctions, mergedWires, fra
67
69
  wires.forEach(wire => {
68
70
  wiresGroup.text(wire.id.toString())
69
71
  .font({
70
- family: 'Inter',
71
- size: 10,
72
+ family: 'Arial',
73
+ size: 50 * fontDisplayScale,
72
74
  })
73
75
  .translate(wire.x + 5, wire.y + 5);
74
76
  });
@@ -30,6 +30,7 @@ export declare enum WireAutoDirection {
30
30
  }
31
31
  export declare const MilsToMM = 0.0254;
32
32
  export declare const MMToPx = 3.779276;
33
+ export declare const MMToPt = 2.8346456693;
33
34
  export declare const PxToMM = 0.2645833;
34
35
  export declare const portWidth = 20;
35
36
  export declare const portHeight = 2;
@@ -12,7 +12,10 @@ export declare class LayoutEngine {
12
12
  logger: Logger;
13
13
  placeSubgraphVersion: number;
14
14
  layoutWarnings: string[];
15
- constructor();
15
+ showBaseFrame: boolean;
16
+ constructor(options?: {
17
+ showBaseFrame: boolean;
18
+ });
16
19
  protected print(...params: any[]): void;
17
20
  protected printLevel(level: number, ...params: any[]): void;
18
21
  protected padLevel(value: number): string;
@@ -125,6 +128,8 @@ export declare class RenderFrame extends RenderObject {
125
128
  gap: number;
126
129
  direction: FramePlotDirection;
127
130
  borderWidth: number;
131
+ width: number | null;
132
+ height: number | null;
128
133
  subgraphId: string;
129
134
  type: RenderFrameType;
130
135
  containsTitle: boolean;
@@ -7,7 +7,9 @@ export declare enum FrameParamKeys {
7
7
  Title = "title",
8
8
  Direction = "direction",
9
9
  Padding = "padding",
10
- Border = "border"
10
+ Border = "border",
11
+ Width = "width",
12
+ Height = "height"
11
13
  }
12
14
  export declare enum FramePlotDirection {
13
15
  Row = "row",
@@ -7,4 +7,8 @@ export declare function generateSVG2(graph: {
7
7
  debugRects?: BoundBox[];
8
8
  frameObjects: RenderFrame[];
9
9
  textObjects: RenderText[];
10
- }): string;
10
+ }): {
11
+ svg: string;
12
+ width: number;
13
+ height: number;
14
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "circuitscript",
3
- "version": "0.0.31",
3
+ "version": "0.0.32",
4
4
  "description": "Interpreter for the circuitscript language",
5
5
  "homepage": "https://circuitscript.net",
6
6
  "engines": {
@@ -27,6 +27,8 @@
27
27
  "@types/figlet": "^1.5.8",
28
28
  "@types/jest": "~29.5",
29
29
  "@types/node": "~18",
30
+ "@types/pdfkit": "^0.13.6",
31
+ "@types/svg-to-pdfkit": "^0.1.3",
30
32
  "@types/svgdom": "^0.1.2",
31
33
  "@typescript-eslint/eslint-plugin": "~5.59",
32
34
  "@typescript-eslint/parser": "~5.59",
@@ -79,6 +81,8 @@
79
81
  "express": "^4.18.2",
80
82
  "figlet": "^1.7.0",
81
83
  "lodash": "^4.17.21",
84
+ "pdfkit": "^0.15.1",
85
+ "svg-to-pdfkit": "^0.1.8",
82
86
  "svgdom": "0.1.14",
83
87
  "this-file": "^2.0.3",
84
88
  "tslib": "~2.5",