circuitscript 0.5.4 → 0.5.5

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.
Files changed (58) hide show
  1. package/dist/cjs/BaseVisitor.js +11 -10
  2. package/dist/cjs/builtinMethods.js +6 -5
  3. package/dist/cjs/environment/environment.js +2 -2
  4. package/dist/cjs/errors.js +140 -0
  5. package/dist/cjs/execute.js +12 -5
  6. package/dist/cjs/main.js +3 -2
  7. package/dist/cjs/objects/ClassComponent.js +4 -4
  8. package/dist/cjs/objects/ExecutionScope.js +2 -2
  9. package/dist/cjs/objects/NumericValue.js +15 -0
  10. package/dist/cjs/objects/PinDefinition.js +2 -2
  11. package/dist/cjs/objects/types.js +2 -2
  12. package/dist/cjs/parser.js +3 -2
  13. package/dist/cjs/pipeline.js +21 -14
  14. package/dist/cjs/regenerate-tests.js +6 -6
  15. package/dist/cjs/render/draw_symbols.js +17 -17
  16. package/dist/cjs/render/geometry.js +6 -6
  17. package/dist/cjs/render/layout.js +325 -253
  18. package/dist/cjs/render/render.js +21 -18
  19. package/dist/cjs/semantic-tokens/getSemanticTokens.js +2 -2
  20. package/dist/cjs/sizing.js +2 -2
  21. package/dist/cjs/utils.js +13 -110
  22. package/dist/cjs/validate/validateScript.js +2 -2
  23. package/dist/cjs/visitor.js +14 -12
  24. package/dist/esm/BaseVisitor.js +2 -1
  25. package/dist/esm/builtinMethods.js +6 -5
  26. package/dist/esm/environment/environment.js +1 -1
  27. package/dist/esm/errors.js +119 -0
  28. package/dist/esm/execute.js +10 -3
  29. package/dist/esm/main.js +3 -2
  30. package/dist/esm/objects/ClassComponent.js +1 -1
  31. package/dist/esm/objects/ExecutionScope.js +1 -1
  32. package/dist/esm/objects/NumericValue.js +15 -0
  33. package/dist/esm/objects/PinDefinition.js +1 -1
  34. package/dist/esm/objects/types.js +1 -1
  35. package/dist/esm/parser.js +2 -1
  36. package/dist/esm/pipeline.js +10 -3
  37. package/dist/esm/regenerate-tests.js +6 -6
  38. package/dist/esm/render/draw_symbols.js +15 -15
  39. package/dist/esm/render/geometry.js +6 -6
  40. package/dist/esm/render/layout.js +325 -253
  41. package/dist/esm/render/render.js +22 -19
  42. package/dist/esm/semantic-tokens/getSemanticTokens.js +1 -1
  43. package/dist/esm/sizing.js +2 -2
  44. package/dist/esm/utils.js +10 -95
  45. package/dist/esm/validate/validateScript.js +1 -1
  46. package/dist/esm/visitor.js +4 -2
  47. package/dist/libs/std.cst +31 -31
  48. package/dist/types/BaseVisitor.d.ts +3 -1
  49. package/dist/types/errors.d.ts +37 -0
  50. package/dist/types/execute.d.ts +1 -1
  51. package/dist/types/helpers.d.ts +1 -1
  52. package/dist/types/objects/NumericValue.d.ts +5 -1
  53. package/dist/types/render/geometry.d.ts +4 -4
  54. package/dist/types/render/layout.d.ts +7 -1
  55. package/dist/types/utils.d.ts +2 -27
  56. package/dist/types/visitor.d.ts +1 -1
  57. package/libs/std.cst +31 -31
  58. package/package.json +1 -1
@@ -11,6 +11,7 @@ const globals_js_1 = require("../globals.js");
11
11
  const geometry_js_1 = require("./geometry.js");
12
12
  const Frame_js_1 = require("../objects/Frame.js");
13
13
  const utils_js_1 = require("../utils.js");
14
+ const errors_js_1 = require("../errors.js");
14
15
  const types_js_1 = require("../objects/types.js");
15
16
  const PinDefinition_js_1 = require("../objects/PinDefinition.js");
16
17
  const helpers_js_1 = require("../helpers.js");
@@ -182,6 +183,7 @@ class LayoutEngine {
182
183
  placeFrames(graph, subgraphInfo, frameObjects) {
183
184
  const baseFrame = frameObjects[0];
184
185
  baseFrame.padding = (0, NumericValue_js_1.numeric)(0);
186
+ baseFrame.gap = (0, NumericValue_js_1.numeric)(globals_js_1.defaultGridSizeUnits);
185
187
  baseFrame.borderWidth = (0, NumericValue_js_1.numeric)(0);
186
188
  if (this.showBaseFrame) {
187
189
  baseFrame.borderWidth = (0, NumericValue_js_1.numeric)(5);
@@ -258,51 +260,49 @@ class LayoutEngine {
258
260
  });
259
261
  }
260
262
  placeAndSizeFrame(frame, level = 0) {
263
+ if (level > 50) {
264
+ throw 'Exceeded placeAndSizeFrame depth limit!';
265
+ }
266
+ this.printLevel(level, `placeAndSizeFrame called`);
261
267
  const innerFrames = frame.innerItems;
262
268
  const gridSize = globals_js_1.defaultGridSizeUnits;
263
269
  const frameDirection = frame.direction;
264
- const boundPoints = [];
265
- const frameSizes = innerFrames.map(innerFrame => {
270
+ const isFrameDirectionRow = frameDirection === Frame_js_1.FramePlotDirection.Row;
271
+ this.printLevel(level, `frame info, id: ${frame.frameId}, direction: ${frameDirection}, virtual: ${frame.virtual}`);
272
+ const frameParams = frame.frame.parameters;
273
+ let hAlign = geometry_js_1.HorizontalAlign.Center;
274
+ let vAlign = geometry_js_1.VerticalAlign.Top;
275
+ if (frameParams.has(Frame_js_1.FrameParamKeys.HorizontalAlign)) {
276
+ hAlign =
277
+ frameParams.get(Frame_js_1.FrameParamKeys.HorizontalAlign);
278
+ }
279
+ if (frameParams.has(Frame_js_1.FrameParamKeys.VerticalAlign)) {
280
+ vAlign =
281
+ frameParams.get(Frame_js_1.FrameParamKeys.VerticalAlign);
282
+ }
283
+ if (frame.overwriteAlignParamsForTitleLayout) {
284
+ hAlign = geometry_js_1.HorizontalAlign.Center;
285
+ vAlign = geometry_js_1.VerticalAlign.Top;
286
+ }
287
+ this.printLevel(level, `align params: ${hAlign} ${vAlign}`);
288
+ this.printLevel(level, `size inner frames, length: ${innerFrames.length}`);
289
+ for (const innerFrame of innerFrames) {
266
290
  if (innerFrame.renderType === RenderFrameType.Elements) {
267
- innerFrame.bounds = (0, utils_js_1.resizeToNearestGrid)(innerFrame.bounds, gridSize);
291
+ if (!innerFrame.didResize) {
292
+ innerFrame.bounds = (0, utils_js_1.resizeToNearestGrid)(innerFrame.bounds, gridSize);
293
+ innerFrame.didResize = true;
294
+ }
268
295
  innerFrame.translateX = innerFrame.bounds.xmin;
269
296
  innerFrame.translateY = innerFrame.bounds.ymin;
297
+ this.printLevel(level, `element frame, id: ${innerFrame.frameId}, bounds: ${JSON.stringify(innerFrame.bounds)}`);
270
298
  }
271
299
  else {
272
300
  this.placeAndSizeFrame(innerFrame, level + 1);
273
301
  }
274
- return innerFrame.bounds;
275
- });
276
- const maxWidth = Math.max(...frameSizes.map(item => {
277
- const { width } = (0, utils_js_1.getBoundsSize)(item);
278
- return width;
279
- }));
280
- const maxHeight = Math.max(...frameSizes.map(item => {
281
- const { height } = (0, utils_js_1.getBoundsSize)(item);
282
- return height;
283
- }));
284
- let accumRowWidth = 0;
285
- let titleFrameWidth = 0;
286
- const inRowShouldCenterInnerFrames = true;
287
- if (frameDirection === Frame_js_1.FramePlotDirection.Row) {
288
- accumRowWidth = frameSizes.reduce((accum, item, index) => {
289
- const { width } = (0, utils_js_1.getBoundsSize)(item);
290
- if (frame.innerItems[index].containsTitle) {
291
- titleFrameWidth = width;
292
- return accum;
293
- }
294
- return accum + width +
295
- ((index + 1 < frameSizes.length) ? frame.gap.toNumber() : 0);
296
- }, 0);
297
- }
298
- else {
299
- accumRowWidth = maxWidth;
300
302
  }
303
+ this.printLevel(level, 'done sizing inner frames');
301
304
  let frameWidth = (0, NumericValue_js_1.numeric)(0);
302
305
  let frameHeight = (0, NumericValue_js_1.numeric)(0);
303
- let frameXMin = (0, NumericValue_js_1.numeric)(0);
304
- let frameYMin = (0, NumericValue_js_1.numeric)(0);
305
- const frameParams = frame.frame.parameters;
306
306
  const avoidAreas = [];
307
307
  if (frameParams.has(Frame_js_1.FrameParamKeys.SheetType)) {
308
308
  const frameComponent = frameParams.get(Frame_js_1.FrameParamKeys.SheetType);
@@ -332,6 +332,9 @@ class LayoutEngine {
332
332
  (0, helpers_js_1.milsToMM)(y2).sub(frameMinY).toNumber(),
333
333
  ]);
334
334
  });
335
+ if (!frameParams.has(Frame_js_1.FrameParamKeys.VerticalAlign)) {
336
+ vAlign = geometry_js_1.VerticalAlign.Center;
337
+ }
335
338
  }
336
339
  else {
337
340
  if (frame.width !== null) {
@@ -341,197 +344,144 @@ class LayoutEngine {
341
344
  frameHeight = frame.height;
342
345
  }
343
346
  }
344
- const offsetX = frame.padding;
345
- const offsetY = frame.padding;
346
- let centeredOffsetX = 0;
347
- let widthForTitle;
348
- if (frameWidth.toNumber() !== 0) {
349
- widthForTitle = frameWidth.toNumber();
350
- }
351
- else if (titleFrameWidth > accumRowWidth) {
352
- widthForTitle = titleFrameWidth;
347
+ const innerFramesWithoutTitle = innerFrames.filter(item => !item.containsTitle);
348
+ this.printLevel(level, `split into lines, width: ${frameWidth.toNumber()} height: ${frameHeight.toNumber()}, padding: ${frame.padding.toNumber()}, gap: ${frame.gap.toNumber()}, direction: ${frameDirection}`);
349
+ const frameLines = SplitIntoLines(frameWidth, frameHeight, frame.padding, frame.gap, frameDirection, innerFramesWithoutTitle, avoidAreas);
350
+ this.printLevel(level, `frame lines: ${frameLines.length}`);
351
+ if (frameLines.length > 1) {
352
+ this.printLevel(level, `split lines to containers`);
353
+ const newInnerFrames = [];
354
+ for (const line of frameLines) {
355
+ const container = RenderFrame.createContainer(frame.gap);
356
+ container.innerItems = [...line];
357
+ container.direction = frameDirection;
358
+ container.frame.parameters.set(Frame_js_1.FrameParamKeys.HorizontalAlign, hAlign);
359
+ container.frame.parameters.set(Frame_js_1.FrameParamKeys.VerticalAlign, vAlign);
360
+ if (isFrameDirectionRow) {
361
+ if (frameWidth.toNumber() !== 0) {
362
+ container.width = frameWidth.sub(frame.padding.mul(2));
363
+ }
364
+ const itemHeights = container.innerItems.map(frame => {
365
+ const bounds = frame.bounds;
366
+ return (bounds.ymax - bounds.ymin);
367
+ });
368
+ const maxHeight = Math.max(...itemHeights);
369
+ container.height = (0, NumericValue_js_1.numeric)(maxHeight);
370
+ this.printLevel(level, `set container size w: ${container.width}, h: ${container.height}`);
371
+ }
372
+ else {
373
+ if (frameHeight.toNumber() !== 0) {
374
+ container.height = frameHeight.sub(frame.padding.mul(2));
375
+ }
376
+ }
377
+ newInnerFrames.push(container);
378
+ }
379
+ const container = RenderFrame.createContainer(frame.gap);
380
+ container.direction = isFrameDirectionRow ? Frame_js_1.FramePlotDirection.Column : Frame_js_1.FramePlotDirection.Row;
381
+ container.innerItems = newInnerFrames;
382
+ frame.innerItems = [container];
383
+ this.placeAndSizeFrame(frame, level + 1);
353
384
  }
354
385
  else {
355
- widthForTitle = accumRowWidth;
356
- }
357
- if (frameDirection === Frame_js_1.FramePlotDirection.Row &&
358
- inRowShouldCenterInnerFrames &&
359
- titleFrameWidth !== null && titleFrameWidth > accumRowWidth) {
360
- centeredOffsetX =
361
- (0, utils_js_1.toNearestGrid)(titleFrameWidth / 2 - accumRowWidth / 2, gridSize);
362
- }
363
- let title_align = geometry_js_1.HorizontalAlign.Middle;
364
- if (frameParams.has(Frame_js_1.FrameParamKeys.TitleAlign)) {
365
- title_align = frameParams.get(Frame_js_1.FrameParamKeys.TitleAlign);
366
- }
367
- let accumX = (0, NumericValue_js_1.numeric)(0);
368
- let accumY = (0, NumericValue_js_1.numeric)(0);
369
- innerFrames.forEach((innerFrame, index) => {
370
- const { width: innerFrameWidth, height: innerFrameHeight } = (0, utils_js_1.getBoundsSize)(innerFrame.bounds);
371
- let arrangeLineAttempts = 0;
372
- const maxAttempts = 10;
373
- let innerFrameX = (0, NumericValue_js_1.numeric)(0);
374
- let innerFrameY = (0, NumericValue_js_1.numeric)(0);
375
- if (innerFrame.containsTitle) {
376
- innerFrame.x = offsetX.add(accumX);
377
- innerFrame.y = offsetY.add(accumY);
378
- accumY = accumY.add(innerFrameHeight).add(frame.gap);
386
+ let accumValue = frame.padding.copy();
387
+ const bounds = [];
388
+ for (const innerFrame of innerFrames) {
389
+ const { width: innerFrameWidth, height: innerFrameHeight } = (0, utils_js_1.getBoundsSize)(innerFrame.bounds);
390
+ if (isFrameDirectionRow) {
391
+ innerFrame.x = accumValue.copy();
392
+ innerFrame.y = frame.padding.copy();
393
+ accumValue = accumValue.add(innerFrameWidth).add(frame.gap);
394
+ }
395
+ else {
396
+ innerFrame.x = frame.padding.copy();
397
+ innerFrame.y = accumValue.copy();
398
+ accumValue = accumValue.add(innerFrameHeight).add(frame.gap);
399
+ }
400
+ bounds.push([innerFrame.x.toNumber(), innerFrame.y.toNumber()], [
401
+ innerFrame.x.add(innerFrameWidth).toNumber(),
402
+ innerFrame.y.add(innerFrameHeight).toNumber(),
403
+ ]);
379
404
  }
380
- else {
381
- if (frameDirection === Frame_js_1.FramePlotDirection.Column) {
382
- innerFrameX = offsetX.add(accumX);
383
- innerFrameY = offsetY.add(accumY);
384
- while (arrangeLineAttempts < maxAttempts) {
385
- const innerFrameY2 = innerFrameY.toNumber() + innerFrameHeight;
386
- const doesExceedFrameHeight = (frameHeight.toNumber() > 0
387
- && innerFrameY2 > frameHeight.toNumber());
388
- const { xmax } = getBoundsFromPoints(boundPoints);
389
- const tmpX1 = innerFrameX.toNumber();
390
- const tmpY1 = innerFrameY.toNumber();
391
- const tmpX2 = tmpX1 + innerFrameWidth;
392
- const tmpY2 = tmpY1 + innerFrameHeight;
393
- const frameArea = [tmpX1, tmpY1, tmpX2, tmpY2];
394
- const overlaps = avoidAreas.filter(area => (0, utils_js_1.areasOverlap)(frameArea, area));
395
- const doesOverlapAreasToAvoid = overlaps.length > 0;
396
- if (boundPoints.length > 0 && (doesExceedFrameHeight || doesOverlapAreasToAvoid)) {
397
- innerFrameY = offsetY;
398
- const nextX = (0, NumericValue_js_1.numeric)(xmax).sub(offsetX).add(frame.gap);
399
- innerFrameX = offsetX.add(nextX);
400
- accumY = (0, NumericValue_js_1.numeric)(0);
401
- accumX = nextX;
402
- }
403
- arrangeLineAttempts++;
404
- if (arrangeLineAttempts > maxAttempts) {
405
- throw "Failed to place inner frame";
406
- }
405
+ const frameInnerBounds = getBoundsFromPoints(bounds);
406
+ const contentsPaddedBounds = (0, utils_js_1.resizeBounds)(frameInnerBounds, frame.padding.toNumber());
407
+ const contentsPaddedWidth = (0, NumericValue_js_1.roundValue)(contentsPaddedBounds.xmax - contentsPaddedBounds.xmin).toNumber();
408
+ const contentsPaddedHeight = (0, NumericValue_js_1.roundValue)(contentsPaddedBounds.ymax - contentsPaddedBounds.ymin).toNumber();
409
+ const contentsWidth = (0, NumericValue_js_1.roundValue)(frameInnerBounds.xmax - frameInnerBounds.xmin).toNumber();
410
+ const contentsHeight = (0, NumericValue_js_1.roundValue)(frameInnerBounds.ymax - frameInnerBounds.ymin).toNumber();
411
+ if (frameWidth.toNumber() === 0) {
412
+ frameWidth = (0, NumericValue_js_1.numeric)(contentsPaddedWidth);
413
+ }
414
+ if (frameHeight.toNumber() === 0) {
415
+ frameHeight = (0, NumericValue_js_1.numeric)(contentsPaddedHeight);
416
+ }
417
+ frame.bounds = {
418
+ xmin: contentsPaddedBounds.xmin,
419
+ xmax: contentsPaddedBounds.xmin + frameWidth.toNumber(),
420
+ ymin: contentsPaddedBounds.ymin,
421
+ ymax: contentsPaddedBounds.ymin + frameHeight.toNumber(),
422
+ };
423
+ this.printLevel(level, `alignment h: ${hAlign}, v: ${vAlign}`);
424
+ const tmpFrameWidth = frameWidth.sub(frame.padding.mul(2));
425
+ const tmpFrameHeight = frameHeight.sub(frame.padding.mul(2));
426
+ this.printLevel(level, `inner frame size, width: ${tmpFrameWidth}, height: ${tmpFrameHeight}`);
427
+ let offsetX = 0;
428
+ let offsetY = 0;
429
+ if (isFrameDirectionRow) {
430
+ switch (hAlign) {
431
+ case geometry_js_1.HorizontalAlign.Left:
432
+ offsetX = 0;
433
+ break;
434
+ case geometry_js_1.HorizontalAlign.Center:
435
+ offsetX = (0, utils_js_1.toNearestGrid)(tmpFrameWidth.sub(contentsWidth).div(2).toNumber(), gridSize);
436
+ break;
437
+ case geometry_js_1.HorizontalAlign.Right:
438
+ offsetX = (0, utils_js_1.toNearestGrid)(tmpFrameWidth.sub(contentsWidth).toNumber(), gridSize);
439
+ break;
440
+ }
441
+ offsetX = (0, NumericValue_js_1.roundValue)(offsetX).toNumber();
442
+ offsetY = 0;
443
+ for (const innerFrame of innerFrames) {
444
+ const { height: innerFrameHeight } = (0, utils_js_1.getBoundsSize)(innerFrame.bounds);
445
+ if (vAlign === geometry_js_1.VerticalAlign.Center) {
446
+ offsetY = (0, utils_js_1.toNearestGrid)(tmpFrameHeight.sub(innerFrameHeight).div(2).toNumber(), gridSize);
447
+ }
448
+ else if (vAlign === geometry_js_1.VerticalAlign.Bottom) {
449
+ offsetY = (0, utils_js_1.toNearestGrid)(tmpFrameHeight.sub(innerFrameHeight).toNumber(), gridSize);
407
450
  }
408
- innerFrame.x = innerFrameX;
409
- innerFrame.y = innerFrameY;
410
- accumY = accumY.add(innerFrameHeight).add(frame.gap);
451
+ offsetY = (0, NumericValue_js_1.roundValue)(offsetY).toNumber();
452
+ innerFrame.x = innerFrame.x.add(offsetX);
453
+ innerFrame.y = innerFrame.y.add(offsetY);
411
454
  }
412
- else if (frameDirection === Frame_js_1.FramePlotDirection.Row) {
413
- innerFrameX = offsetX.add(centeredOffsetX).add(accumX);
414
- innerFrameY = offsetY.add(accumY);
415
- while (arrangeLineAttempts < maxAttempts) {
416
- const innerFrameX2 = innerFrameX.toNumber() + innerFrameWidth;
417
- const doesExceedFrameWidth = (frameWidth.toNumber() > 0
418
- && innerFrameX2 > frameWidth.toNumber());
419
- const tmpX1 = innerFrameX.toNumber();
420
- const tmpY1 = innerFrameY.toNumber();
421
- const tmpX2 = tmpX1 + innerFrameWidth;
422
- const tmpY2 = tmpY1 + innerFrameHeight;
423
- const frameArea = [tmpX1, tmpY1, tmpX2, tmpY2];
424
- const overlaps = avoidAreas.filter(area => (0, utils_js_1.areasOverlap)(frameArea, area));
425
- const doesOverlapAreasToAvoid = overlaps.length > 0;
426
- if (boundPoints.length > 0 && (doesExceedFrameWidth || doesOverlapAreasToAvoid)) {
427
- innerFrameX = offsetX.add(centeredOffsetX);
428
- const { ymax } = getBoundsFromPoints(boundPoints);
429
- const nextY = (0, NumericValue_js_1.numeric)(ymax).sub(offsetY).add(frame.gap);
430
- innerFrameY = offsetY.add(nextY);
431
- accumX = (0, NumericValue_js_1.numeric)(0);
432
- accumY = nextY;
433
- }
434
- else {
435
- break;
436
- }
437
- arrangeLineAttempts++;
438
- if (arrangeLineAttempts > maxAttempts) {
439
- throw "Failed to place inner frame";
440
- }
455
+ }
456
+ else {
457
+ switch (vAlign) {
458
+ case geometry_js_1.VerticalAlign.Top:
459
+ offsetY = 0;
460
+ break;
461
+ case geometry_js_1.VerticalAlign.Center:
462
+ offsetY = (0, utils_js_1.toNearestGrid)(tmpFrameHeight.sub(contentsHeight).div(2).toNumber(), gridSize);
463
+ break;
464
+ case geometry_js_1.VerticalAlign.Bottom:
465
+ offsetY = (0, utils_js_1.toNearestGrid)(tmpFrameHeight.sub(contentsHeight).toNumber(), gridSize);
466
+ break;
467
+ }
468
+ offsetX = 0;
469
+ offsetY = (0, NumericValue_js_1.roundValue)(offsetY).toNumber();
470
+ for (const innerFrame of innerFrames) {
471
+ const { width: innerFrameHeight } = (0, utils_js_1.getBoundsSize)(innerFrame.bounds);
472
+ if (hAlign === geometry_js_1.HorizontalAlign.Center) {
473
+ offsetX = (0, utils_js_1.toNearestGrid)(tmpFrameWidth.sub(innerFrameHeight).div(2).toNumber(), gridSize);
441
474
  }
442
- innerFrame.x = innerFrameX;
443
- innerFrame.y = innerFrameY;
444
- accumX = accumX.add(innerFrameWidth).add(frame.gap);
475
+ else if (hAlign === geometry_js_1.HorizontalAlign.Right) {
476
+ offsetX = (0, utils_js_1.toNearestGrid)(tmpFrameWidth.sub(innerFrameHeight).toNumber(), gridSize);
477
+ }
478
+ offsetX = (0, NumericValue_js_1.roundValue)(offsetX).toNumber();
479
+ innerFrame.x = innerFrame.x.add(offsetX);
480
+ innerFrame.y = innerFrame.y.add(offsetY);
445
481
  }
446
482
  }
447
- boundPoints.push([
448
- innerFrame.x.toNumber(),
449
- innerFrame.y.toNumber()
450
- ], [
451
- innerFrame.x.add(innerFrameWidth).toNumber(),
452
- innerFrame.y.add(innerFrameHeight).toNumber()
453
- ]);
454
- });
455
- const contentsBounds = (0, utils_js_1.resizeBounds)(getBoundsFromPoints(boundPoints), frame.padding.toNumber());
456
- const contentsWidth = contentsBounds.xmax - contentsBounds.xmin;
457
- const contentsHeight = contentsBounds.ymax - contentsBounds.ymin;
458
- let hAlign = geometry_js_1.HorizontalAlign.Middle;
459
- let vAlign = geometry_js_1.VerticalAlign.Middle;
460
- if (frameParams.has(Frame_js_1.FrameParamKeys.HorizontalAlign)) {
461
- hAlign =
462
- frameParams.get(Frame_js_1.FrameParamKeys.HorizontalAlign);
463
483
  }
464
- if (frameParams.has(Frame_js_1.FrameParamKeys.VerticalAlign)) {
465
- vAlign =
466
- frameParams.get(Frame_js_1.FrameParamKeys.VerticalAlign);
467
- }
468
- if (frameParams.has(Frame_js_1.FrameParamKeys.SheetType)) {
469
- frameXMin = (0, NumericValue_js_1.numeric)(0);
470
- frameYMin = (0, NumericValue_js_1.numeric)(0);
471
- }
472
- else {
473
- frameXMin = (0, NumericValue_js_1.numeric)(contentsBounds.xmin);
474
- frameYMin = (0, NumericValue_js_1.numeric)(contentsBounds.ymin);
475
- }
476
- if (frameWidth.toNumber() === 0) {
477
- frameWidth = (0, NumericValue_js_1.numeric)(contentsWidth);
478
- }
479
- if (frameHeight.toNumber() === 0) {
480
- frameHeight = (0, NumericValue_js_1.numeric)(contentsHeight);
481
- }
482
- const titleFrame = innerFrames.find(frame => {
483
- return frame.containsTitle;
484
- });
485
- if (titleFrame) {
486
- const { width: innerFrameWidth } = (0, utils_js_1.getBoundsSize)(titleFrame.bounds);
487
- let titleOffset = 0;
488
- switch (title_align) {
489
- case geometry_js_1.HorizontalAlign.Left:
490
- titleOffset = 0;
491
- break;
492
- case geometry_js_1.HorizontalAlign.Middle:
493
- titleOffset = (0, utils_js_1.toNearestGrid)(widthForTitle / 2 - innerFrameWidth / 2, gridSize);
494
- break;
495
- case geometry_js_1.HorizontalAlign.Right:
496
- titleOffset = frameWidth.toNumber() - innerFrameWidth;
497
- break;
498
- }
499
- titleFrame.x = titleFrame.x.add(titleOffset);
500
- }
501
- let frameOffsetX = 0;
502
- let frameOffsetY = 0;
503
- switch (hAlign) {
504
- case geometry_js_1.HorizontalAlign.Left:
505
- frameOffsetX = 0;
506
- break;
507
- case geometry_js_1.HorizontalAlign.Middle:
508
- frameOffsetX = (0, utils_js_1.toNearestGrid)((frameWidth.toNumber() - contentsWidth) / 2, gridSize);
509
- break;
510
- case geometry_js_1.HorizontalAlign.Right:
511
- frameOffsetX = (0, utils_js_1.toNearestGrid)(frameWidth.toNumber() - contentsWidth, gridSize);
512
- break;
513
- }
514
- switch (vAlign) {
515
- case geometry_js_1.VerticalAlign.Top:
516
- frameOffsetY = 0;
517
- break;
518
- case geometry_js_1.VerticalAlign.Middle:
519
- frameOffsetY = (0, utils_js_1.toNearestGrid)((frameHeight.toNumber() - contentsHeight) / 2, gridSize);
520
- break;
521
- case geometry_js_1.VerticalAlign.Bottom:
522
- frameOffsetY = (0, utils_js_1.toNearestGrid)(frameHeight.toNumber() - contentsHeight, gridSize);
523
- break;
524
- }
525
- innerFrames.forEach(innerFrame => {
526
- innerFrame.x = innerFrame.x.add(frameOffsetX);
527
- innerFrame.y = innerFrame.y.add(frameOffsetY);
528
- });
529
- frame.bounds = {
530
- xmin: frameXMin.toNumber(),
531
- ymin: frameYMin.toNumber(),
532
- xmax: frameXMin.toNumber() + frameWidth.toNumber(),
533
- ymax: frameYMin.toNumber() + frameHeight.toNumber(),
534
- };
484
+ return;
535
485
  }
536
486
  dumpFrame(frame, level = 0) {
537
487
  this.print(level, "".padStart(level * 4), 'frame, items:', frame.innerItems.length);
@@ -598,33 +548,80 @@ class LayoutEngine {
598
548
  };
599
549
  }
600
550
  checkAddFrameTitle(frame, elementFrames, textObjects, level) {
601
- if (frame.renderType === RenderFrameType.Container) {
602
- const frameObject = frame.frame;
603
- const isSheetFrame = frameObject.frameType === globals_js_1.FrameType.Sheet;
604
- if (frameObject.parameters.has(Frame_js_1.FrameParamKeys.Title) && !isSheetFrame) {
605
- const title = frameObject.parameters.get(Frame_js_1.FrameParamKeys.Title);
606
- const tmpFrame = new RenderFrame(new Frame_js_1.Frame(Frame_js_1.FixedFrameIds.FrameIdNotUsed), RenderFrameType.Elements);
607
- tmpFrame.containsTitle = true;
608
- tmpFrame.subgraphId = title.replace(/\s/g, "_");
609
- const textObject = new RenderText(title);
610
- textObject.fontSize = (0, NumericValue_js_1.numeric)(globals_js_1.defaultFrameTitleTextSize);
611
- textObject.fontWeight = 'bold';
612
- textObject.symbol.refreshDrawing();
613
- tmpFrame.innerItems.push(textObject);
614
- const tmpBox = textObject.symbol.drawing.getBoundingBox();
615
- tmpFrame.bounds = {
616
- xmin: tmpBox.start[0],
617
- ymin: tmpBox.start[1],
618
- xmax: tmpBox.start[0] + tmpBox.width,
619
- ymax: tmpBox.start[1] + tmpBox.height
620
- };
621
- textObject.x = (0, NumericValue_js_1.numeric)(0);
622
- textObject.y = (0, NumericValue_js_1.numeric)(0);
623
- frame.innerItems.splice(0, 0, tmpFrame);
624
- this.printLevel(level, frame, 'added text', tmpFrame);
625
- textObjects.push(textObject);
626
- elementFrames.splice(0, 0, tmpFrame);
551
+ if (frame.renderType !== RenderFrameType.Container) {
552
+ return;
553
+ }
554
+ const frameObject = frame.frame;
555
+ const frameParams = frame.frame.parameters;
556
+ const isSheetFrame = frameObject.frameType === globals_js_1.FrameType.Sheet;
557
+ if (frameParams.has(Frame_js_1.FrameParamKeys.Title) && !isSheetFrame) {
558
+ const title = frameParams.get(Frame_js_1.FrameParamKeys.Title);
559
+ const titleFrame = new RenderFrame(new Frame_js_1.Frame(Frame_js_1.FixedFrameIds.FrameIdNotUsed), RenderFrameType.Elements);
560
+ titleFrame.containsTitle = true;
561
+ titleFrame.subgraphId = title.replace(/\s/g, "_");
562
+ const textObject = new RenderText(title);
563
+ textObject.fontSize = (0, NumericValue_js_1.numeric)(globals_js_1.defaultFrameTitleTextSize);
564
+ textObject.fontWeight = 'bold';
565
+ textObject.x = (0, NumericValue_js_1.numeric)(0);
566
+ textObject.y = (0, NumericValue_js_1.numeric)(0);
567
+ textObject.symbol.refreshDrawing();
568
+ titleFrame.innerItems = [textObject];
569
+ const tmpBox = textObject.symbol.drawing.getBoundingBox();
570
+ const tmpBounds = {
571
+ xmin: tmpBox.start[0],
572
+ ymin: tmpBox.start[1],
573
+ xmax: tmpBox.start[0] + tmpBox.width,
574
+ ymax: tmpBox.start[1] + tmpBox.height
575
+ };
576
+ titleFrame.bounds = (0, utils_js_1.resizeToNearestGrid)(tmpBounds, globals_js_1.defaultGridSizeUnits);
577
+ titleFrame.didResize = true;
578
+ const titleFrameContainer = RenderFrame.createContainer((0, NumericValue_js_1.numeric)(0));
579
+ titleFrameContainer.innerItems = [titleFrame];
580
+ if (frameParams.has(Frame_js_1.FrameParamKeys.TitleAlign)) {
581
+ const alignValue = frameParams.get(Frame_js_1.FrameParamKeys.TitleAlign);
582
+ titleFrameContainer.frame.parameters.set(Frame_js_1.FrameParamKeys.HorizontalAlign, alignValue);
583
+ }
584
+ const container = RenderFrame.createContainer(frame.gap);
585
+ container.direction = frame.direction;
586
+ container.innerItems = [...frame.innerItems];
587
+ let hAlign = geometry_js_1.HorizontalAlign.Center;
588
+ let vAlign = geometry_js_1.VerticalAlign.Center;
589
+ if (frameParams.has(Frame_js_1.FrameParamKeys.HorizontalAlign)) {
590
+ hAlign =
591
+ frameParams.get(Frame_js_1.FrameParamKeys.HorizontalAlign);
592
+ }
593
+ if (frameParams.has(Frame_js_1.FrameParamKeys.VerticalAlign)) {
594
+ vAlign =
595
+ frameParams.get(Frame_js_1.FrameParamKeys.VerticalAlign);
596
+ }
597
+ container.frame.parameters.set(Frame_js_1.FrameParamKeys.HorizontalAlign, hAlign);
598
+ container.frame.parameters.set(Frame_js_1.FrameParamKeys.VerticalAlign, vAlign);
599
+ const columnLayoutContainer = RenderFrame.createContainer((0, NumericValue_js_1.numeric)(globals_js_1.defaultGridSizeUnits));
600
+ columnLayoutContainer.direction = Frame_js_1.FramePlotDirection.Column;
601
+ columnLayoutContainer.innerItems = [
602
+ titleFrameContainer,
603
+ container,
604
+ ];
605
+ const frameWidth = frame.width ?? (0, NumericValue_js_1.numeric)(0);
606
+ if (frameWidth.toNumber() !== 0) {
607
+ columnLayoutContainer.width = frameWidth.sub(frame.padding.mul(2));
608
+ container.width = columnLayoutContainer.width.copy();
609
+ titleFrameContainer.width = columnLayoutContainer.width.copy();
627
610
  }
611
+ const frameHeight = frame.height ?? (0, NumericValue_js_1.numeric)(0);
612
+ if (frameHeight.toNumber() !== 0) {
613
+ columnLayoutContainer.height = frameHeight.sub(frame.padding.mul(2));
614
+ const { height: titleFrameHeight } = (0, utils_js_1.getBoundsSize)(titleFrame.bounds);
615
+ container.height = columnLayoutContainer.height
616
+ .sub(titleFrameHeight)
617
+ .sub(columnLayoutContainer.gap);
618
+ }
619
+ frame.innerItems = [columnLayoutContainer];
620
+ frame.overwriteAlignParamsForTitleLayout = true;
621
+ columnLayoutContainer.overwriteAlignParamsForTitleLayout = true;
622
+ this.printLevel(level, frame, 'added text', titleFrame);
623
+ textObjects.push(textObject);
624
+ elementFrames.splice(0, 0, titleFrame);
628
625
  }
629
626
  }
630
627
  sizeSubGraphs(graph) {
@@ -784,7 +781,7 @@ class LayoutEngine {
784
781
  const targetOriginNode = findOriginNode(targetNode);
785
782
  const itemOriginNode = findOriginNode(item);
786
783
  if (targetOriginNode !== itemOriginNode) {
787
- throw "Wire auto length failed. Please specify a fixed wire length.";
784
+ throw new errors_js_1.AutoWireFailedError_("Wire auto length failed. Please specify a fixed wire length.", item.wire);
788
785
  }
789
786
  const [untilX, untilY] = getNodePositionAtPin(targetNode, pin);
790
787
  item.setEndAuto(untilX, untilY);
@@ -921,17 +918,6 @@ function getNodePositionAtPin(item, pin) {
921
918
  (0, NumericValue_js_1.roundValue)(x), (0, NumericValue_js_1.roundValue)(y)
922
919
  ];
923
920
  }
924
- function getNeighbours(graph, nodeIds) {
925
- return nodeIds.reduce((accum, nodeId) => {
926
- const tmp = graph.neighbors(nodeId);
927
- if (tmp) {
928
- tmp.forEach(neighborNodeId => {
929
- accum.push([nodeId, neighborNodeId]);
930
- });
931
- }
932
- return accum;
933
- }, []);
934
- }
935
921
  function applyComponentParamsToSymbol(componentUnit, symbol) {
936
922
  const { widthProp = null, heightProp = null } = componentUnit;
937
923
  const newMap = new Map(componentUnit.parameters);
@@ -1251,7 +1237,7 @@ class RenderText extends RenderObject {
1251
1237
  }
1252
1238
  exports.RenderText = RenderText;
1253
1239
  class RenderFrame extends RenderObject {
1254
- constructor(frame, type = RenderFrameType.Container) {
1240
+ constructor(frame, type = RenderFrameType.Container, virtual = false) {
1255
1241
  super();
1256
1242
  this.bounds = null;
1257
1243
  this.innerItems = [];
@@ -1260,15 +1246,21 @@ class RenderFrame extends RenderObject {
1260
1246
  this.padding = (0, helpers_js_1.milsToMM)(100);
1261
1247
  this.gap = (0, helpers_js_1.milsToMM)(100);
1262
1248
  this.borderWidth = (0, NumericValue_js_1.numeric)(5);
1249
+ this.borderColor = "#111";
1263
1250
  this.direction = Frame_js_1.FramePlotDirection.Row;
1264
1251
  this.width = null;
1265
1252
  this.height = null;
1266
1253
  this.subgraphId = "";
1267
1254
  this.containsTitle = false;
1255
+ this.overwriteAlignParamsForTitleLayout = false;
1256
+ this.virtual = false;
1257
+ this.didResize = false;
1258
+ this.lineIndex = 0;
1268
1259
  this.frame = frame;
1269
1260
  this.renderType = type;
1270
1261
  this.frameId = RenderFrame.FrameIdCounter;
1271
1262
  RenderFrame.FrameIdCounter++;
1263
+ this.virtual = virtual;
1272
1264
  }
1273
1265
  toString() {
1274
1266
  let name = "";
@@ -1281,6 +1273,13 @@ class RenderFrame extends RenderObject {
1281
1273
  return name + ": " + this.x + "," + this.y
1282
1274
  + " bounds:" + (this.bounds && (0, utils_js_1.printBounds)(this.bounds));
1283
1275
  }
1276
+ static createContainer(gap) {
1277
+ const tmpFrame = new RenderFrame(new Frame_js_1.Frame(Frame_js_1.FixedFrameIds.FrameIdNotUsed), RenderFrameType.Container, true);
1278
+ tmpFrame.gap = gap.copy();
1279
+ tmpFrame.borderWidth = (0, NumericValue_js_1.numeric)(0);
1280
+ tmpFrame.padding = (0, NumericValue_js_1.numeric)(0);
1281
+ return tmpFrame;
1282
+ }
1284
1283
  }
1285
1284
  exports.RenderFrame = RenderFrame;
1286
1285
  RenderFrame.FrameIdCounter = 0;
@@ -1341,3 +1340,76 @@ exports.ExtractDrawingRects = ExtractDrawingRects;
1341
1340
  function isPointOverlap(x, y, other) {
1342
1341
  return (x >= other.x && y >= other.y && x <= (other.x + other.width) && y <= (other.y + other.height));
1343
1342
  }
1343
+ function SplitIntoLines(frameWidth, frameHeight, framePadding, frameGap, frameDirection, innerFrames, avoidAreas) {
1344
+ if (frameWidth.toNumber() === 0) {
1345
+ frameWidth = (0, NumericValue_js_1.numeric)(1e24);
1346
+ }
1347
+ if (frameHeight.toNumber() === 0) {
1348
+ frameHeight = (0, NumericValue_js_1.numeric)(1e24);
1349
+ }
1350
+ const allGroups = [];
1351
+ let currentGroup = [];
1352
+ const tmpFrameWidth = frameWidth.sub(framePadding.mul(2)).toNumber();
1353
+ const tmpFrameHeight = frameHeight.sub(framePadding.mul(2)).toNumber();
1354
+ const isRowDirection = frameDirection === Frame_js_1.FramePlotDirection.Row;
1355
+ const dimensionLimit = isRowDirection ? tmpFrameWidth : tmpFrameHeight;
1356
+ let accumX = (0, NumericValue_js_1.numeric)(0);
1357
+ let accumY = (0, NumericValue_js_1.numeric)(0);
1358
+ const framePaddingValue = framePadding.toNumber();
1359
+ avoidAreas = avoidAreas.map(bounds => {
1360
+ return [
1361
+ bounds[0] - framePaddingValue,
1362
+ bounds[1] - framePaddingValue,
1363
+ bounds[2] - framePaddingValue,
1364
+ bounds[3] - framePaddingValue
1365
+ ];
1366
+ });
1367
+ for (const innerFrame of innerFrames) {
1368
+ const { width: innerFrameWidth, height: innerFrameHeight } = (0, utils_js_1.getBoundsSize)(innerFrame.bounds);
1369
+ const tmpX1 = accumX.toNumber();
1370
+ const tmpY1 = accumY.toNumber();
1371
+ const tmpX2 = tmpX1 + innerFrameWidth;
1372
+ const tmpY2 = tmpY1 + innerFrameHeight;
1373
+ const frameArea = [tmpX1, tmpY1, tmpX2, tmpY2];
1374
+ const conditionOverlapAvoidAreas = avoidAreas.filter(area => (0, utils_js_1.areasOverlap)(frameArea, area)).length > 0;
1375
+ if (isRowDirection) {
1376
+ const tmpX = accumX.add(innerFrameWidth).toNumber();
1377
+ const conditionExceedDimension = tmpX > dimensionLimit;
1378
+ if ((conditionExceedDimension || conditionOverlapAvoidAreas) && currentGroup.length > 0) {
1379
+ allGroups.push(currentGroup);
1380
+ const heightsInLine = currentGroup.map(item => item.height);
1381
+ const maxHeight = Math.max(...heightsInLine);
1382
+ accumX = (0, NumericValue_js_1.numeric)(0);
1383
+ accumY = accumY.add(frameGap).add(maxHeight);
1384
+ currentGroup = [];
1385
+ }
1386
+ accumX = accumX.add(innerFrameWidth).add(frameGap);
1387
+ }
1388
+ else {
1389
+ const tmpY = accumY.add(innerFrameHeight).toNumber();
1390
+ const conditionExistDimension = tmpY > dimensionLimit;
1391
+ if ((conditionExistDimension || conditionOverlapAvoidAreas) && currentGroup.length > 0) {
1392
+ allGroups.push(currentGroup);
1393
+ const widthsInLine = currentGroup.map(item => item.width);
1394
+ const maxWidth = Math.max(...widthsInLine);
1395
+ accumX = accumX.add(frameGap).add(maxWidth);
1396
+ accumY = (0, NumericValue_js_1.numeric)(0);
1397
+ currentGroup = [];
1398
+ }
1399
+ accumY = accumY.add(innerFrameHeight).add(frameGap);
1400
+ }
1401
+ currentGroup.push({
1402
+ x: accumX.toNumber(),
1403
+ y: accumY.toNumber(),
1404
+ width: innerFrameWidth,
1405
+ height: innerFrameHeight,
1406
+ frame: innerFrame
1407
+ });
1408
+ }
1409
+ if (currentGroup.length > 0) {
1410
+ allGroups.push(currentGroup);
1411
+ }
1412
+ return allGroups.map(lines => {
1413
+ return lines.map(layoutItem => layoutItem.frame);
1414
+ });
1415
+ }