circuitscript 0.0.38 → 0.1.2

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 (66) hide show
  1. package/dist/cjs/BaseVisitor.js +69 -46
  2. package/dist/cjs/SymbolValidatorVisitor.js +1 -1
  3. package/dist/cjs/antlr/CircuitScriptLexer.js +80 -80
  4. package/dist/cjs/antlr/CircuitScriptParser.js +580 -613
  5. package/dist/cjs/builtinMethods.js +32 -10
  6. package/dist/cjs/draw_symbols.js +375 -233
  7. package/dist/cjs/execute.js +142 -131
  8. package/dist/cjs/export.js +2 -4
  9. package/dist/cjs/geometry.js +52 -19
  10. package/dist/cjs/globals.js +14 -9
  11. package/dist/cjs/helpers.js +16 -3
  12. package/dist/cjs/layout.js +143 -151
  13. package/dist/cjs/logger.js +8 -1
  14. package/dist/cjs/objects/ClassComponent.js +22 -22
  15. package/dist/cjs/objects/ExecutionScope.js +10 -4
  16. package/dist/cjs/objects/Frame.js +4 -1
  17. package/dist/cjs/objects/ParamDefinition.js +120 -4
  18. package/dist/cjs/objects/PinDefinition.js +1 -4
  19. package/dist/cjs/objects/types.js +41 -0
  20. package/dist/cjs/render.js +41 -110
  21. package/dist/cjs/sizing.js +33 -7
  22. package/dist/cjs/utils.js +92 -2
  23. package/dist/cjs/visitor.js +279 -284
  24. package/dist/esm/BaseVisitor.mjs +70 -47
  25. package/dist/esm/SymbolValidatorVisitor.mjs +1 -1
  26. package/dist/esm/antlr/CircuitScriptLexer.mjs +80 -80
  27. package/dist/esm/antlr/CircuitScriptParser.mjs +580 -613
  28. package/dist/esm/builtinMethods.mjs +29 -10
  29. package/dist/esm/draw_symbols.mjs +381 -238
  30. package/dist/esm/execute.mjs +144 -133
  31. package/dist/esm/export.mjs +2 -4
  32. package/dist/esm/geometry.mjs +52 -19
  33. package/dist/esm/globals.mjs +13 -8
  34. package/dist/esm/helpers.mjs +17 -4
  35. package/dist/esm/layout.mjs +144 -153
  36. package/dist/esm/logger.mjs +8 -1
  37. package/dist/esm/objects/ClassComponent.mjs +21 -26
  38. package/dist/esm/objects/ExecutionScope.mjs +10 -4
  39. package/dist/esm/objects/Frame.mjs +4 -1
  40. package/dist/esm/objects/ParamDefinition.mjs +119 -3
  41. package/dist/esm/objects/PinDefinition.mjs +0 -2
  42. package/dist/esm/objects/types.mjs +42 -0
  43. package/dist/esm/render.mjs +44 -113
  44. package/dist/esm/sizing.mjs +34 -8
  45. package/dist/esm/utils.mjs +86 -1
  46. package/dist/esm/visitor.mjs +281 -286
  47. package/dist/types/BaseVisitor.d.ts +3 -2
  48. package/dist/types/antlr/CircuitScriptParser.d.ts +5 -3
  49. package/dist/types/draw_symbols.d.ts +81 -49
  50. package/dist/types/execute.d.ts +16 -11
  51. package/dist/types/geometry.d.ts +31 -19
  52. package/dist/types/globals.d.ts +15 -10
  53. package/dist/types/helpers.d.ts +2 -1
  54. package/dist/types/layout.d.ts +22 -21
  55. package/dist/types/logger.d.ts +1 -1
  56. package/dist/types/objects/ClassComponent.d.ts +19 -16
  57. package/dist/types/objects/ExecutionScope.d.ts +2 -1
  58. package/dist/types/objects/Frame.d.ts +5 -3
  59. package/dist/types/objects/ParamDefinition.d.ts +31 -2
  60. package/dist/types/objects/PinDefinition.d.ts +0 -2
  61. package/dist/types/objects/types.d.ts +7 -2
  62. package/dist/types/render.d.ts +2 -1
  63. package/dist/types/utils.d.ts +9 -1
  64. package/dist/types/visitor.d.ts +5 -5
  65. package/libs/lib.cst +102 -32
  66. package/package.json +7 -3
@@ -1,8 +1,10 @@
1
1
  import { milsToMM } from "./helpers.mjs";
2
- import { ColorScheme, CustomSymbolParamTextSize, CustomSymbolPinIdSize, CustomSymbolPinTextSize, CustomSymbolRefDesSize, PortArrowSize, PortPaddingHorizontal, PortPaddingVertical, ReferenceTypes, SymbolPinSide, defaultFont, defaultPinIdTextSize, defaultPinNameTextSize, defaultSymbolLineWidth, fontDisplayScale } from "./globals.mjs";
3
- import { Geometry, GeometryProp, HorizontalAlign, Textbox, VerticalAlign } from "./geometry.mjs";
2
+ import { ColorScheme, CustomSymbolParamTextSize, CustomSymbolPinIdSize, CustomSymbolPinTextSize, CustomSymbolRefDesSize, PortArrowSize, PortPaddingHorizontal, PortPaddingVertical, ReferenceTypes, RenderFlags, SymbolPinSide, defaultFont, defaultPinIdTextSize, defaultPinNameTextSize, defaultSymbolLineWidth, fontDisplayScale } from "./globals.mjs";
3
+ import { Geometry, GeometryProp, HorizontalAlign, HorizontalAlignProp, Textbox, VerticalAlign, VerticalAlignProp } from "./geometry.mjs";
4
4
  import { PinTypes } from "./objects/PinTypes.mjs";
5
- import { roundValue } from "./utils.mjs";
5
+ import { roundValue, throwWithContext } from "./utils.mjs";
6
+ import { DeclaredReference, UndeclaredReference } from "./objects/types.mjs";
7
+ import { numeric, NumericValue } from "./objects/ParamDefinition.mjs";
6
8
  export class SymbolGraphic {
7
9
  drawPortsName = true;
8
10
  displayBounds = false;
@@ -10,9 +12,12 @@ export class SymbolGraphic {
10
12
  _angle = 0;
11
13
  _flipX = 0;
12
14
  _flipY = 0;
13
- width;
14
- height;
15
+ width = numeric(-1);
16
+ height = numeric(-1);
15
17
  labelTexts = new Map();
18
+ constructor() {
19
+ this.drawing = new SymbolDrawing();
20
+ }
16
21
  get angle() {
17
22
  return (this._angle % 360);
18
23
  }
@@ -37,15 +42,21 @@ export class SymbolGraphic {
37
42
  }
38
43
  calculateSize() {
39
44
  const { width, height } = this.drawing.getBoundingBox();
40
- this.width = width;
41
- this.height = height;
42
- }
43
- size() {
45
+ this.width = numeric(width);
46
+ this.height = numeric(height);
44
47
  return {
48
+ bodyWidth: numeric(-1),
49
+ bodyHeight: numeric(-1),
45
50
  width: this.width,
46
51
  height: this.height
47
52
  };
48
53
  }
54
+ size() {
55
+ return {
56
+ width: this.width.toNumber(),
57
+ height: this.height.toNumber(),
58
+ };
59
+ }
49
60
  draw(group, extra) {
50
61
  const innerGroup = group.group();
51
62
  this.drawBody(innerGroup);
@@ -82,15 +93,15 @@ export class SymbolGraphic {
82
93
  drawBounds(group) {
83
94
  const bbox = this.drawing.getBoundingBox();
84
95
  const originSize = milsToMM(10);
85
- group.circle(originSize)
86
- .translate(-originSize / 2, -originSize / 2)
96
+ group.circle(originSize.toNumber())
97
+ .translate(originSize.neg().div(2).toNumber(), originSize.neg().div(2).toNumber())
87
98
  .fill('red')
88
99
  .stroke('none');
89
100
  group.rect(bbox.width, bbox.height)
90
101
  .translate(bbox.start[0], bbox.start[1])
91
102
  .fill('none')
92
103
  .stroke({
93
- width: milsToMM(2),
104
+ width: milsToMM(2).toNumber(),
94
105
  color: '#ccc',
95
106
  });
96
107
  }
@@ -100,7 +111,7 @@ export class SymbolGraphic {
100
111
  const { path, lineColor, fillColor, lineWidth } = pathInfo;
101
112
  group.path(path)
102
113
  .stroke({
103
- width: lineWidth,
114
+ width: lineWidth.toNumber(),
104
115
  color: lineColor,
105
116
  })
106
117
  .fill(fillColor);
@@ -120,7 +131,8 @@ export class SymbolGraphic {
120
131
  const labels = this.drawing.getLabels();
121
132
  labels.forEach(label => {
122
133
  const tmpLabel = label;
123
- const { fontSize = 50, anchor = HorizontalAlign.Left, vanchor = VerticalAlign.Bottom, fontWeight = 'regular', angle: labelAngle = 0, textColor = "#333", } = tmpLabel.style ?? {};
134
+ const { fontSize = numeric(50), anchor = HorizontalAlign.Left, vanchor = VerticalAlign.Bottom, fontWeight = 'regular', angle: tmpLabelAngle = numeric(0), textColor = "#333", } = tmpLabel.style ?? {};
135
+ const labelAngle = tmpLabelAngle.toNumber();
124
136
  let anchorStyle = 'start';
125
137
  let dominantBaseline = 'auto';
126
138
  let useAnchor = anchor;
@@ -132,40 +144,44 @@ export class SymbolGraphic {
132
144
  }
133
145
  switch (useAnchor) {
134
146
  case HorizontalAlign.Left:
135
- anchorStyle = (this.flipX === 0) ? 'start' : 'end';
147
+ anchorStyle = (this.flipX === 0)
148
+ ? HorizontalAlignProp.Start : HorizontalAlignProp.End;
136
149
  break;
137
150
  case HorizontalAlign.Middle:
138
- anchorStyle = 'middle';
151
+ anchorStyle = HorizontalAlignProp.Middle;
139
152
  break;
140
153
  case HorizontalAlign.Right:
141
- anchorStyle = (this.flipX === 0) ? 'end' : 'start';
154
+ anchorStyle = (this.flipX === 0)
155
+ ? HorizontalAlignProp.End : HorizontalAlignProp.Start;
142
156
  break;
143
157
  }
144
158
  switch (useDominantBaseline) {
145
159
  case VerticalAlign.Top:
146
- dominantBaseline = (this.flipY === 0) ? 'hanging' : 'text-top';
160
+ dominantBaseline = (this.flipY === 0)
161
+ ? VerticalAlignProp.Hanging : VerticalAlignProp.TextTop;
147
162
  break;
148
163
  case VerticalAlign.Middle:
149
- dominantBaseline = 'middle';
164
+ dominantBaseline = VerticalAlignProp.Central;
150
165
  break;
151
166
  case VerticalAlign.Bottom:
152
- dominantBaseline = (this.flipY === 0) ? 'text-top' : 'hanging';
167
+ dominantBaseline = (this.flipY === 0)
168
+ ? VerticalAlignProp.TextTop : VerticalAlignProp.Hanging;
153
169
  break;
154
170
  }
155
171
  const position = tmpLabel.getLabelPosition();
156
172
  if (this.flipX !== 0) {
157
- position[0] *= -1;
173
+ position[0] = position[0].neg();
158
174
  }
159
175
  if (this.flipY !== 0) {
160
- position[1] *= -1;
176
+ position[1] = position[1].neg();
161
177
  }
162
178
  const useFont = defaultFont;
163
179
  const textContainer = group.group();
164
180
  let translateX, translateY;
165
181
  let useRotateAngle = 0;
166
182
  if (isRotation180) {
167
- translateX = -position[0];
168
- translateY = -position[1];
183
+ translateX = position[0].neg();
184
+ translateY = position[1].neg();
169
185
  useRotateAngle = 0;
170
186
  }
171
187
  else {
@@ -235,7 +251,7 @@ export class SymbolGraphic {
235
251
  }
236
252
  textContainer.path(path)
237
253
  .stroke({
238
- width: milsToMM(5),
254
+ width: milsToMM(5).toNumber(),
239
255
  color: '#333'
240
256
  })
241
257
  .fill('none')
@@ -243,47 +259,55 @@ export class SymbolGraphic {
243
259
  .translate(boundsTranslateX, boundsY - paddingVert);
244
260
  }
245
261
  }
246
- const drawTextBounds = false;
247
- const drawBoxBounds = false;
248
- const drawOrigin = false;
249
- if (drawBoxBounds) {
262
+ if (RenderFlags.ShowLabelBoxBounds) {
250
263
  const box = tmpLabel.box;
251
- textContainer.rect(box.width, box.height).fill('red')
264
+ textContainer.rect(box.width, box.height)
265
+ .fill('none')
266
+ .stroke({
267
+ width: 0.1,
268
+ color: 'blue',
269
+ })
252
270
  .translate(box.xmin, box.ymin)
253
- .scale(this.flipX !== 0 ? -1 : 1, 1, -box.xmin, box.ymin);
271
+ .rotate(labelAngle, -box.xmin, -box.ymin);
254
272
  }
255
- if (drawTextBounds) {
273
+ if (RenderFlags.ShowLabelBounds) {
256
274
  const textBounds = tmpLabel.textMeasurementBounds;
257
275
  const xOffset = (this.flipX !== 0) ? textBounds.width : 0;
258
- textContainer.rect(textBounds.width, textBounds.height).fill('#cccccc')
276
+ textContainer.rect(textBounds.width, textBounds.height)
277
+ .fill('none')
278
+ .stroke({
279
+ width: 0.1,
280
+ color: 'red',
281
+ })
259
282
  .translate(textBounds.x - xOffset, textBounds.y);
260
283
  }
261
- textContainer.translate(translateX, translateY)
262
- .rotate(useRotateAngle, -translateX, -translateY);
284
+ textContainer.translate(translateX.toNumber(), translateY.toNumber())
285
+ .rotate(useRotateAngle, -translateX.toNumber(), -translateY.toNumber());
263
286
  textContainer.text(tmpLabel.text)
264
287
  .fill(textColor)
265
288
  .font({
266
289
  family: useFont,
267
- size: fontSize * fontDisplayScale,
290
+ size: fontSize.toNumber() * fontDisplayScale,
268
291
  anchor: anchorStyle,
269
292
  'dominant-baseline': dominantBaseline,
270
293
  weight: fontWeight,
271
294
  })
272
- .rotate(labelAngle);
295
+ .attr("xml:space", "preserve")
296
+ .rotate(labelAngle, 0, 0);
273
297
  const { a, b, c, d, e, f } = textContainer.matrix();
274
298
  const newMatrix = {
275
- a: roundValue(a),
276
- b: roundValue(b),
277
- c: roundValue(c),
278
- d: roundValue(d),
279
- e: roundValue(e),
280
- f: roundValue(f),
299
+ a: roundValue(numeric(a)).toNumber(),
300
+ b: roundValue(numeric(b)).toNumber(),
301
+ c: roundValue(numeric(c)).toNumber(),
302
+ d: roundValue(numeric(d)).toNumber(),
303
+ e: roundValue(numeric(e)).toNumber(),
304
+ f: roundValue(numeric(f)).toNumber(),
281
305
  };
282
306
  textContainer.transform(newMatrix);
283
- if (drawOrigin) {
284
- const originSize = milsToMM(10);
307
+ if (RenderFlags.ShowLabelOrigin) {
308
+ const originSize = milsToMM(10).toNumber();
285
309
  textContainer.circle(originSize)
286
- .translate(originSize / 2, originSize / 2)
310
+ .translate(-originSize / 2, -originSize / 2)
287
311
  .fill('green');
288
312
  }
289
313
  });
@@ -310,41 +334,19 @@ export class SymbolGraphic {
310
334
  return VerticalAlign.Middle;
311
335
  }
312
336
  }
313
- setLabelValue(labelId, labelValue) {
314
- this.labelTexts.set(labelId, labelValue);
315
- }
316
- getLabelValue(labelId) {
317
- if (this.labelTexts.has(labelId)) {
318
- return this.labelTexts.get(labelId);
319
- }
320
- return undefined;
321
- }
322
- }
323
- export function SymbolFactory(name) {
324
- switch (name) {
325
- case 'point':
326
- return new SymbolPointHidden();
327
- }
328
- return null;
329
- }
330
- export class SymbolPointHidden extends SymbolGraphic {
331
- generateDrawing() {
332
- const drawing = new SymbolDrawing();
333
- drawing.addPin(1, 0, 0, 0, 0);
334
- this.drawing = drawing;
335
- }
336
337
  }
337
338
  export class SymbolText extends SymbolGraphic {
338
339
  text;
339
- fontSize = 40;
340
+ fontSize = numeric(40);
340
341
  fontWeight = 'regular';
341
342
  constructor(text) {
342
343
  super();
343
344
  this.text = text;
344
345
  }
345
346
  generateDrawing() {
346
- const drawing = new SymbolDrawing();
347
- drawing.addTextbox(0, 0, this.text, {
347
+ const drawing = this.drawing;
348
+ drawing.clear();
349
+ drawing.addTextbox(numeric(0), numeric(0), this.text, {
348
350
  fontSize: this.fontSize,
349
351
  anchor: HorizontalAlign.Middle,
350
352
  fontWeight: this.fontWeight,
@@ -364,13 +366,23 @@ export class SymbolPlaceholder extends SymbolGraphic {
364
366
  [PlaceHolderCommands.units, ['mils'], {}],
365
367
  [PlaceHolderCommands.lineColor, [ColorScheme.PinLineColor], {}],
366
368
  [PlaceHolderCommands.textColor, [ColorScheme.PinNameColor], {}],
367
- [PlaceHolderCommands.lineWidth, [5], {}],
369
+ [PlaceHolderCommands.lineWidth, [numeric(5)], {}],
368
370
  ...drawing.getCommands()
369
371
  ];
370
372
  drawing.log('id: ', drawing.id, 'angle: ', this._angle, "commands:", commands.length);
371
373
  let lineColor = "#333";
372
374
  let textColor = "#333";
373
- commands.forEach(([commandName, positionParams, keywordParams]) => {
375
+ commands.forEach(([commandName, positionParams, keywordParams, ctx]) => {
376
+ positionParams = positionParams.map(param => {
377
+ return this.resolveReference(param);
378
+ });
379
+ if (keywordParams instanceof Map) {
380
+ const tmpKeywordParams = new Map(keywordParams);
381
+ tmpKeywordParams.forEach((value, key) => {
382
+ tmpKeywordParams.set(key, this.resolveReference(value));
383
+ });
384
+ keywordParams = tmpKeywordParams;
385
+ }
374
386
  switch (commandName) {
375
387
  case PlaceHolderCommands.rect:
376
388
  drawing.log('add rect', ...positionParams);
@@ -409,7 +421,7 @@ export class SymbolPlaceholder extends SymbolGraphic {
409
421
  drawing.addArc(...positionParams);
410
422
  break;
411
423
  case PlaceHolderCommands.circle:
412
- drawing.addArc(...positionParams, 0, 360);
424
+ drawing.addArc(...positionParams, numeric(0), numeric(360));
413
425
  break;
414
426
  case PlaceHolderCommands.triangle:
415
427
  drawing.addTriangle(...positionParams);
@@ -426,23 +438,24 @@ export class SymbolPlaceholder extends SymbolGraphic {
426
438
  if (style['textColor'] === undefined) {
427
439
  style['textColor'] = textColor;
428
440
  }
429
- positionParams = [...positionParams];
430
- positionParams.push(style);
431
- const labelId = positionParams[0];
432
- const tmpPositionParams = [...positionParams];
433
- const tmpLabelValue = this.getLabelValue(labelId);
434
- if (tmpLabelValue !== undefined) {
435
- tmpPositionParams[3] = tmpLabelValue;
436
- }
441
+ const tmpPositionParams = [
442
+ positionParams[1], positionParams[2],
443
+ positionParams[0], style
444
+ ];
437
445
  drawing.log('add label', JSON.stringify(tmpPositionParams));
438
- drawing.addLabelId(...tmpPositionParams);
446
+ try {
447
+ drawing.addLabelMils(...tmpPositionParams);
448
+ }
449
+ catch (err) {
450
+ throwWithContext(ctx, err);
451
+ }
439
452
  break;
440
453
  }
441
454
  case PlaceHolderCommands.text: {
442
455
  const style = this.parseLabelStyle(keywordParams);
443
456
  const content = keywordParams.get('content');
444
- let offsetX = 0;
445
- let offsetY = 0;
457
+ let offsetX = numeric(0);
458
+ let offsetY = numeric(0);
446
459
  if (keywordParams.has('offset')) {
447
460
  const offset = keywordParams.get('offset');
448
461
  offsetX = offset[0];
@@ -459,13 +472,30 @@ export class SymbolPlaceholder extends SymbolGraphic {
459
472
  });
460
473
  drawing.log("=== end generate drawing ===");
461
474
  }
475
+ resolveReference(param) {
476
+ if (param instanceof DeclaredReference) {
477
+ return param.value;
478
+ }
479
+ else if (param instanceof UndeclaredReference) {
480
+ throw "Undefined symbol: " + param.nameString();
481
+ }
482
+ return param;
483
+ }
462
484
  parseLabelStyle(keywordParams) {
463
485
  const keywords = ['fontSize', 'anchor', 'vanchor',
464
- 'angle', 'textColor', 'portType'];
486
+ 'angle', 'textColor', 'portType', 'bold'];
465
487
  const style = {};
466
488
  keywords.forEach(item => {
467
489
  if (keywordParams.has(item)) {
468
490
  style[item] = keywordParams.get(item);
491
+ if (item === 'bold') {
492
+ if (keywordParams.get(item) === true) {
493
+ style['fontWeight'] = 'bold';
494
+ }
495
+ else {
496
+ style['fontWeight'] = 'normal';
497
+ }
498
+ }
469
499
  }
470
500
  });
471
501
  return style;
@@ -477,6 +507,9 @@ export class SymbolPlaceholder extends SymbolGraphic {
477
507
  let displayPinId = true;
478
508
  if (keywordParams.has(keywordDisplayPinId)) {
479
509
  const value = keywordParams.get(keywordDisplayPinId);
510
+ if (value instanceof NumericValue && value.toNumber() === 0) {
511
+ displayPinId = false;
512
+ }
480
513
  if (value === 0 || value === false) {
481
514
  displayPinId = false;
482
515
  }
@@ -500,7 +533,7 @@ export class SymbolPlaceholder extends SymbolGraphic {
500
533
  startX,
501
534
  startY,
502
535
  startX,
503
- startY + magnitude
536
+ startY.add(magnitude)
504
537
  ];
505
538
  }
506
539
  else if (commandName === PlaceHolderCommands.hpin) {
@@ -509,7 +542,7 @@ export class SymbolPlaceholder extends SymbolGraphic {
509
542
  positionParams[0],
510
543
  startX,
511
544
  startY,
512
- startX + magnitude,
545
+ startX.add(magnitude),
513
546
  startY
514
547
  ];
515
548
  }
@@ -531,11 +564,12 @@ export class SymbolPlaceholder extends SymbolGraphic {
531
564
  const offset1 = 15;
532
565
  const offset2 = 15;
533
566
  let pinNameOffsetX = milsToMM(offset1);
534
- let pinIdOffsetX = 0;
567
+ let pinIdOffsetX = numeric(0);
535
568
  let pinIdAlignment = HorizontalAlign.Left;
536
569
  let pinIdVAlignment = VerticalAlign.Bottom;
537
570
  let pinIdOffsetY = milsToMM(-offset2);
538
- switch (angle) {
571
+ const angleValue = angle.toNumber();
572
+ switch (angleValue) {
539
573
  case 0:
540
574
  pinNameAlignment = HorizontalAlign.Left;
541
575
  pinNameOffsetX = milsToMM(offset1);
@@ -558,16 +592,16 @@ export class SymbolPlaceholder extends SymbolGraphic {
558
592
  pinIdVAlignment = VerticalAlign.Top;
559
593
  break;
560
594
  }
561
- if (angle === 0 || angle === 90 || angle === 180 || angle === 270) {
595
+ if (angleValue === 0 || angleValue === 90 || angleValue === 180 || angleValue === 270) {
562
596
  const usePinName = pinNameParam ?? "";
563
- usePinName !== "" && drawing.addLabel(endX + pinNameOffsetX, endY, usePinName, {
564
- fontSize: defaultPinNameTextSize,
597
+ usePinName !== "" && drawing.addLabel(endX.add(pinNameOffsetX), endY, usePinName, {
598
+ fontSize: numeric(defaultPinNameTextSize),
565
599
  anchor: pinNameAlignment,
566
600
  vanchor: VerticalAlign.Middle,
567
601
  textColor: pinNameColor,
568
602
  });
569
- displayPinId && drawing.addLabel(endX + pinIdOffsetX, endY + pinIdOffsetY, pinId.toString(), {
570
- fontSize: defaultPinIdTextSize,
603
+ displayPinId && drawing.addLabel(endX.add(pinIdOffsetX), endY.add(pinIdOffsetY), pinId.toDisplayString(), {
604
+ fontSize: numeric(defaultPinIdTextSize),
571
605
  anchor: pinIdAlignment,
572
606
  vanchor: pinIdVAlignment,
573
607
  textColor: lineColor
@@ -604,58 +638,74 @@ export var PlaceHolderCommands;
604
638
  export class SymbolCustom extends SymbolGraphic {
605
639
  pinDefinition = [];
606
640
  bodyWidth = milsToMM(400);
641
+ bodyHeight = milsToMM(100);
607
642
  pinLength = milsToMM(100);
608
643
  width = milsToMM(100);
609
644
  height = milsToMM(100);
610
645
  pinSpacing = milsToMM(100);
611
646
  pinTextPadding = milsToMM(5);
612
647
  pins = [];
613
- _cacheLeftPins;
614
- _cacheRightPins;
615
- constructor(pinDefinition) {
648
+ _cacheLeftPins = [];
649
+ _cacheRightPins = [];
650
+ _cacheTopPins = [];
651
+ _cacheBottomPins = [];
652
+ pinMaxPositions;
653
+ constructor(pinDefinition, pinMaxPositions) {
616
654
  super();
617
655
  this.pinDefinition = pinDefinition;
656
+ this.pinMaxPositions = pinMaxPositions;
618
657
  }
619
658
  generateDrawing() {
620
- const leftPins = this.pinDefinition.filter(item => {
621
- return item.side === SymbolPinSide.Left;
622
- });
623
- const rightPins = this.pinDefinition.filter(item => {
624
- return item.side === SymbolPinSide.Right;
625
- });
626
- const maxLeftPins = Math.max(...leftPins.map(item => item.position)) + 1;
627
- const maxRightPins = Math.max(...rightPins.map(item => item.position)) + 1;
628
- const drawing = new SymbolDrawing();
659
+ const leftPins = this.getPins(SymbolPinSide.Left);
660
+ const rightPins = this.getPins(SymbolPinSide.Right);
661
+ const topPins = this.getPins(SymbolPinSide.Top);
662
+ const bottomPins = this.getPins(SymbolPinSide.Bottom);
663
+ this.drawing.clear();
664
+ const drawing = this.drawing;
629
665
  drawing.angle = this._angle;
630
666
  drawing.flipX = this._flipX;
631
667
  drawing.flipY = this._flipY;
632
- const bodyWidth = this.bodyWidth;
633
- const bodyHeight = (1 + Math.max(maxLeftPins, maxRightPins)) * this.pinSpacing;
668
+ const { bodyWidth, bodyHeight } = this.calculateSize();
634
669
  const defaultLineColor = ColorScheme.PinLineColor;
635
670
  drawing.addSetLineColor(defaultLineColor);
636
- drawing.addSetLineWidth(5);
637
- drawing.addRectMM(0, 0, bodyWidth, bodyHeight);
638
- this.generateDrawingPins(drawing, bodyWidth, bodyHeight, leftPins, rightPins, defaultLineColor);
671
+ drawing.addSetLineWidth(numeric(5));
672
+ drawing.addRectMM(numeric(0), numeric(0), bodyWidth, bodyHeight);
673
+ this.generateDrawingPins(drawing, bodyWidth, bodyHeight, {
674
+ left: leftPins, right: rightPins, top: topPins, bottom: bottomPins
675
+ }, defaultLineColor);
639
676
  this.drawing = drawing;
640
677
  this._cacheLeftPins = leftPins;
641
678
  this._cacheRightPins = rightPins;
679
+ this._cacheTopPins = topPins;
680
+ this._cacheBottomPins = bottomPins;
642
681
  }
643
- generateDrawingPins(drawing, bodyWidthMM, bodyHeightMM, leftPins, rightPins, defaultLineColor) {
644
- const leftPinStart = -bodyWidthMM / 2;
645
- const rightPinStart = bodyWidthMM / 2;
646
- const pinStartY = -bodyHeightMM / 2;
682
+ getPins(side) {
683
+ const pins = this.pinDefinition.filter(item => {
684
+ return item.side === side;
685
+ });
686
+ return pins;
687
+ }
688
+ generateDrawingPins(drawing, bodyWidthMM, bodyHeightMM, pins, defaultLineColor) {
689
+ const { left: leftPins, right: rightPins, top: topPins, bottom: bottomPins } = pins;
690
+ const leftPinStart = bodyWidthMM.neg().div(2);
691
+ const rightPinStart = bodyWidthMM.div(2);
692
+ const topPinStart = bodyHeightMM.neg().div(2);
693
+ const bottomPinStart = bodyHeightMM.div(2);
694
+ const pinStartY = bodyHeightMM.neg().div(2);
695
+ const pinStartX = bodyWidthMM.neg().div(2);
696
+ const tmpPinSpacing = this.pinSpacing.toNumber();
647
697
  leftPins.forEach(pin => {
648
698
  const position = pin.position;
649
- const pinY = pinStartY + (position + 1) * this.pinSpacing;
650
- drawing.addPinMM(pin.pinId, leftPinStart - this.pinLength, pinY, leftPinStart, pinY, defaultLineColor);
651
- drawing.addLabel(leftPinStart + milsToMM(20), pinY, pin.text, {
652
- fontSize: CustomSymbolPinTextSize,
699
+ const pinY = pinStartY.add((position + 1) * tmpPinSpacing);
700
+ drawing.addPinMM(numeric(pin.pinId), leftPinStart.sub(this.pinLength), pinY, leftPinStart, pinY, defaultLineColor);
701
+ drawing.addLabel(leftPinStart.add(milsToMM(20)), pinY, pin.text, {
702
+ fontSize: numeric(CustomSymbolPinTextSize),
653
703
  anchor: HorizontalAlign.Left,
654
704
  vanchor: VerticalAlign.Middle,
655
705
  textColor: ColorScheme.PinNameColor,
656
706
  });
657
- drawing.addLabel(leftPinStart - milsToMM(10), pinY - milsToMM(10), pin.pinId.toString(), {
658
- fontSize: CustomSymbolPinIdSize,
707
+ drawing.addLabel(leftPinStart.sub(milsToMM(10)), pinY.sub(milsToMM(10)), pin.pinId.toString(), {
708
+ fontSize: numeric(CustomSymbolPinIdSize),
659
709
  anchor: HorizontalAlign.Right,
660
710
  vanchor: VerticalAlign.Bottom,
661
711
  textColor: defaultLineColor
@@ -663,32 +713,70 @@ export class SymbolCustom extends SymbolGraphic {
663
713
  });
664
714
  rightPins.forEach(pin => {
665
715
  const position = pin.position;
666
- const pinY = pinStartY + (position + 1) * this.pinSpacing;
667
- drawing.addPinMM(pin.pinId, rightPinStart + this.pinLength, pinY, rightPinStart, pinY, defaultLineColor);
668
- drawing.addLabel(rightPinStart - milsToMM(20), pinY, pin.text, {
669
- fontSize: CustomSymbolPinTextSize,
716
+ const pinY = pinStartY.add((position + 1) * tmpPinSpacing);
717
+ drawing.addPinMM(numeric(pin.pinId), rightPinStart.add(this.pinLength), pinY, rightPinStart, pinY, defaultLineColor);
718
+ drawing.addLabel(rightPinStart.sub(milsToMM(20)), pinY, pin.text, {
719
+ fontSize: numeric(CustomSymbolPinTextSize),
670
720
  anchor: HorizontalAlign.Right,
671
721
  vanchor: VerticalAlign.Middle,
672
722
  textColor: ColorScheme.PinNameColor,
673
723
  });
674
- drawing.addLabel(rightPinStart + milsToMM(10), pinY - milsToMM(10), pin.pinId.toString(), {
675
- fontSize: CustomSymbolPinIdSize,
724
+ drawing.addLabel(rightPinStart.add(milsToMM(10)), pinY.sub(milsToMM(10)), pin.pinId.toString(), {
725
+ fontSize: numeric(CustomSymbolPinIdSize),
676
726
  anchor: HorizontalAlign.Left,
677
727
  vanchor: VerticalAlign.Bottom,
678
728
  textColor: defaultLineColor
679
729
  });
680
730
  });
681
- const instanceName = this.getLabelValue("refdes");
682
- instanceName && drawing.addLabel(-bodyWidthMM / 2, -bodyHeightMM / 2 - milsToMM(20), instanceName, {
683
- fontSize: CustomSymbolRefDesSize,
731
+ topPins.forEach(pin => {
732
+ const position = pin.position;
733
+ const pinX = pinStartX.add((position + 1) * tmpPinSpacing);
734
+ drawing.addPinMM(numeric(pin.pinId), pinX, topPinStart.sub(this.pinLength), pinX, topPinStart, defaultLineColor);
735
+ drawing.addLabel(pinX, topPinStart.add(milsToMM(20)), pin.text, {
736
+ fontSize: numeric(CustomSymbolPinTextSize),
737
+ anchor: HorizontalAlign.Right,
738
+ vanchor: VerticalAlign.Middle,
739
+ textColor: ColorScheme.PinNameColor,
740
+ angle: numeric(-90),
741
+ });
742
+ drawing.addLabel(pinX.sub(milsToMM(10)), topPinStart.sub(milsToMM(10)), pin.pinId.toString(), {
743
+ fontSize: numeric(CustomSymbolPinIdSize),
744
+ anchor: HorizontalAlign.Left,
745
+ vanchor: VerticalAlign.Bottom,
746
+ textColor: defaultLineColor,
747
+ angle: numeric(-90),
748
+ });
749
+ });
750
+ bottomPins.forEach(pin => {
751
+ const position = pin.position;
752
+ const pinX = pinStartX.add((position + 1) * tmpPinSpacing);
753
+ drawing.addPinMM(numeric(pin.pinId), pinX, bottomPinStart.add(this.pinLength), pinX, bottomPinStart, defaultLineColor);
754
+ drawing.addLabel(pinX, bottomPinStart.sub(milsToMM(20)), pin.text, {
755
+ fontSize: numeric(CustomSymbolPinTextSize),
756
+ anchor: HorizontalAlign.Left,
757
+ vanchor: VerticalAlign.Middle,
758
+ textColor: ColorScheme.PinNameColor,
759
+ angle: numeric(-90),
760
+ });
761
+ drawing.addLabel(pinX.sub(milsToMM(10)), bottomPinStart.add(milsToMM(10)), pin.pinId.toString(), {
762
+ fontSize: numeric(CustomSymbolPinIdSize),
763
+ anchor: HorizontalAlign.Right,
764
+ vanchor: VerticalAlign.Bottom,
765
+ textColor: defaultLineColor,
766
+ angle: numeric(-90)
767
+ });
768
+ });
769
+ const instanceName = drawing.variables.get('refdes');
770
+ instanceName && drawing.addLabel(bodyWidthMM.neg().div(2), bodyHeightMM.neg().div(2).sub(milsToMM(20)), instanceName, {
771
+ fontSize: numeric(CustomSymbolRefDesSize),
684
772
  anchor: HorizontalAlign.Left,
685
773
  });
686
774
  const acceptedMPNKeys = ['MPN', 'mpn', 'manufacturer_pn'];
687
775
  acceptedMPNKeys.some(key => {
688
- const labelValue = this.getLabelValue(key);
776
+ const labelValue = drawing.variables.get(key);
689
777
  if (labelValue !== undefined) {
690
- drawing.addLabel(-bodyWidthMM / 2, bodyHeightMM / 2 + milsToMM(20), labelValue, {
691
- fontSize: CustomSymbolParamTextSize,
778
+ drawing.addLabel(bodyWidthMM.neg().div(2), bodyHeightMM.div(2).add(milsToMM(20)), labelValue, {
779
+ fontSize: numeric(CustomSymbolParamTextSize),
692
780
  anchor: HorizontalAlign.Left,
693
781
  vanchor: VerticalAlign.Top,
694
782
  });
@@ -696,25 +784,55 @@ export class SymbolCustom extends SymbolGraphic {
696
784
  });
697
785
  }
698
786
  calculateSize() {
699
- this.width = this.bodyWidth + 2 * this.pinLength;
700
- this.height = (1 + Math.max(this._cacheLeftPins.length, this._cacheRightPins.length)) * this.pinSpacing;
787
+ const tmpPinSpacing = this.pinSpacing.toNumber();
788
+ const tmpPinLength = this.pinLength.toNumber();
789
+ const { [SymbolPinSide.Top]: maxTopPins, [SymbolPinSide.Bottom]: maxBottomPins, [SymbolPinSide.Left]: maxLeftPins, [SymbolPinSide.Right]: maxRightPins } = this.pinMaxPositions;
790
+ const bodyWidthFromPins = numeric((1 + Math.max(maxTopPins, maxBottomPins)) * tmpPinSpacing);
791
+ const bodyWidth = Math.max(bodyWidthFromPins.toNumber(), this.bodyWidth.toNumber());
792
+ let tmpBodyHeight = 0;
793
+ if (maxLeftPins === 0 && maxRightPins === 0) {
794
+ tmpBodyHeight = 3;
795
+ }
796
+ else {
797
+ tmpBodyHeight = (1 + Math.max(maxLeftPins, maxRightPins));
798
+ }
799
+ const bodyHeight = Math.max(tmpBodyHeight * tmpPinSpacing, this.bodyHeight.toNumber());
800
+ const useHeight = bodyHeight
801
+ + ((this._cacheTopPins.length > 0) ? tmpPinLength : 0)
802
+ + ((this._cacheBottomPins.length > 0) ? tmpPinLength : 0);
803
+ const useWidth = bodyWidth
804
+ + ((this._cacheLeftPins.length > 0) ? tmpPinLength : 0)
805
+ + ((this._cacheRightPins.length > 0) ? tmpPinLength : 0);
806
+ this.width = numeric(useWidth);
807
+ this.height = numeric(useHeight);
808
+ return {
809
+ bodyWidth: numeric(bodyWidth),
810
+ bodyHeight: numeric(bodyHeight),
811
+ width: this.width,
812
+ height: this.height
813
+ };
701
814
  }
702
815
  }
703
816
  export class SymbolCustomModule extends SymbolCustom {
704
- pinLength = 0;
817
+ pinLength = milsToMM(0);
705
818
  portWidth = milsToMM(100);
706
819
  portHeight = milsToMM(50);
707
- generateDrawingPins(drawing, bodyWidthMM, bodyHeightMM, leftPins, rightPins, defaultLineColor) {
708
- const leftPinStart = -bodyWidthMM / 2;
709
- const rightPinStart = bodyWidthMM / 2;
710
- const pinStartY = -bodyHeightMM / 2;
820
+ generateDrawingPins(drawing, bodyWidthMM, bodyHeightMM, pins, defaultLineColor) {
821
+ const leftPinStart = bodyWidthMM.neg().div(2);
822
+ const rightPinStart = bodyWidthMM.div(2);
823
+ const topPinStart = bodyHeightMM.neg().div(2);
824
+ const bottomPinStart = bodyHeightMM.div(2);
825
+ const pinStartY = bodyHeightMM.neg().div(2);
826
+ const pinStartX = bodyWidthMM.neg().div(2);
827
+ const tmpPinSpacing = this.pinSpacing.toNumber();
828
+ const { left: leftPins, right: rightPins, top: topPins, bottom: bottomPins } = pins;
711
829
  leftPins.forEach(pin => {
712
830
  const position = pin.position;
713
- const pinY = pinStartY + (position + 1) * this.pinSpacing;
714
- drawing.addPinMM(pin.pinId, leftPinStart - this.pinLength, pinY, leftPinStart, pinY, defaultLineColor);
831
+ const pinY = pinStartY.add((position + 1) * tmpPinSpacing);
832
+ drawing.addPinMM(numeric(pin.pinId), leftPinStart.sub(this.pinLength), pinY, leftPinStart, pinY, defaultLineColor);
715
833
  drawing.addModulePort(leftPinStart, pinY, this.portWidth, this.portHeight, pin.pinType);
716
- drawing.addLabel(leftPinStart + this.portWidth + milsToMM(20), pinY, pin.text, {
717
- fontSize: 40,
834
+ drawing.addLabel(leftPinStart.add(this.portWidth).add(milsToMM(20)), pinY, pin.text, {
835
+ fontSize: numeric(40),
718
836
  anchor: HorizontalAlign.Left,
719
837
  vanchor: VerticalAlign.Middle,
720
838
  textColor: ColorScheme.PinNameColor,
@@ -722,14 +840,40 @@ export class SymbolCustomModule extends SymbolCustom {
722
840
  });
723
841
  rightPins.forEach(pin => {
724
842
  const position = pin.position;
725
- const pinY = pinStartY + (position + 1) * this.pinSpacing;
726
- drawing.addPinMM(pin.pinId, rightPinStart + this.pinLength, pinY, rightPinStart, pinY, defaultLineColor);
843
+ const pinY = pinStartY.add((position + 1) * tmpPinSpacing);
844
+ drawing.addPinMM(numeric(pin.pinId), rightPinStart.add(this.pinLength), pinY, rightPinStart, pinY, defaultLineColor);
727
845
  drawing.addModulePort(rightPinStart, pinY, this.portWidth, this.portHeight, pin.pinType, -1);
728
- drawing.addLabel(rightPinStart - this.portWidth - milsToMM(20), pinY, pin.text, {
729
- fontSize: 40,
846
+ drawing.addLabel(rightPinStart.sub(this.portWidth).sub(milsToMM(20)), pinY, pin.text, {
847
+ fontSize: numeric(40),
848
+ anchor: HorizontalAlign.Right,
849
+ vanchor: VerticalAlign.Middle,
850
+ textColor: ColorScheme.PinNameColor,
851
+ });
852
+ });
853
+ topPins.forEach(pin => {
854
+ const position = pin.position;
855
+ const pinX = pinStartX.add((position + 1) * tmpPinSpacing);
856
+ drawing.addPinMM(numeric(pin.pinId), pinX, topPinStart.sub(this.pinLength), pinX, topPinStart, defaultLineColor);
857
+ drawing.addModulePort(pinX, topPinStart, this.portWidth, this.portHeight, pin.pinType, 1, 90);
858
+ drawing.addLabel(pinX, topPinStart.add(this.portWidth).add(milsToMM(20)), pin.text, {
859
+ fontSize: numeric(40),
730
860
  anchor: HorizontalAlign.Right,
731
861
  vanchor: VerticalAlign.Middle,
732
862
  textColor: ColorScheme.PinNameColor,
863
+ angle: numeric(-90),
864
+ });
865
+ });
866
+ bottomPins.forEach(pin => {
867
+ const position = pin.position;
868
+ const pinX = pinStartX.add((position + 1) * tmpPinSpacing);
869
+ drawing.addPinMM(numeric(pin.pinId), pinX, bottomPinStart, pinX, bottomPinStart.sub(this.pinLength), defaultLineColor);
870
+ drawing.addModulePort(pinX, bottomPinStart, this.portWidth, this.portHeight, pin.pinType, 1, -90);
871
+ drawing.addLabel(pinX, bottomPinStart.sub(this.portWidth).sub(milsToMM(20)), pin.text, {
872
+ fontSize: numeric(40),
873
+ anchor: HorizontalAlign.Left,
874
+ vanchor: VerticalAlign.Middle,
875
+ textColor: ColorScheme.PinNameColor,
876
+ angle: numeric(-90),
733
877
  });
734
878
  });
735
879
  }
@@ -740,8 +884,9 @@ export class SymbolDrawing {
740
884
  angle = 0;
741
885
  flipX = 0;
742
886
  flipY = 0;
743
- mainOrigin = [0, 0];
887
+ mainOrigin = [numeric(0), numeric(0)];
744
888
  logger = null;
889
+ variables = new Map();
745
890
  clear() {
746
891
  this.items = [];
747
892
  this.pins = [];
@@ -766,26 +911,30 @@ export class SymbolDrawing {
766
911
  }
767
912
  addPinMM(pinId, startXMM, startYMM, endXMM, endYMM, lineColor) {
768
913
  let angle = 0;
769
- if (startXMM === endXMM) {
770
- if (startYMM > endYMM) {
914
+ const tmpStartXMM = startXMM.toNumber();
915
+ const tmpEndXMM = endXMM.toNumber();
916
+ const tmpStartYMM = startYMM.toNumber();
917
+ const tmpEndYMM = endYMM.toNumber();
918
+ if (tmpStartXMM === tmpEndXMM) {
919
+ if (tmpStartYMM > tmpEndYMM) {
771
920
  angle = 270;
772
921
  }
773
- else if (startYMM < endYMM) {
922
+ else if (tmpStartYMM < tmpEndYMM) {
774
923
  angle = 90;
775
924
  }
776
925
  }
777
926
  else {
778
- if (startXMM < endXMM) {
927
+ if (tmpStartXMM < tmpEndXMM) {
779
928
  angle = 0;
780
929
  }
781
- else if (startXMM > endXMM) {
930
+ else if (tmpStartXMM > tmpEndXMM) {
782
931
  angle = 180;
783
932
  }
784
933
  }
785
934
  this.pins.push([
786
935
  pinId,
787
936
  Geometry.segment([startXMM, startYMM], [endXMM, endYMM]),
788
- angle,
937
+ numeric(angle),
789
938
  lineColor
790
939
  ]);
791
940
  return this;
@@ -794,14 +943,14 @@ export class SymbolDrawing {
794
943
  startX = milsToMM(startX);
795
944
  startY = milsToMM(startY);
796
945
  value = milsToMM(value);
797
- this.items.push(Geometry.segment([startX, startY], [startX, startY + value]));
946
+ this.items.push(Geometry.segment([startX, startY], [startX, startY.add(value)]));
798
947
  return this;
799
948
  }
800
949
  addHLine(startX, startY, value) {
801
950
  startX = milsToMM(startX);
802
951
  startY = milsToMM(startY);
803
952
  value = milsToMM(value);
804
- this.items.push(Geometry.segment([startX, startY], [startX + value, startY]));
953
+ this.items.push(Geometry.segment([startX, startY], [startX.add(value), startY]));
805
954
  return this;
806
955
  }
807
956
  addRect(centerX, centerY, width, height) {
@@ -812,14 +961,14 @@ export class SymbolDrawing {
812
961
  return this.addRectMM(centerX, centerY, width, height);
813
962
  }
814
963
  addRectMM(centerX, centerY, width, height) {
815
- const width2 = width / 2;
816
- const height2 = height / 2;
964
+ const width2 = width.div(2);
965
+ const height2 = height.div(2);
817
966
  this.items.push(Geometry.polygon([
818
- [centerX - width2, centerY - height2],
819
- [centerX + width2, centerY - height2],
820
- [centerX + width2, centerY + height2],
821
- [centerX - width2, centerY + height2],
822
- [centerX - width2, centerY - height2]
967
+ [centerX.sub(width2), centerY.sub(height2)],
968
+ [centerX.add(width2), centerY.sub(height2)],
969
+ [centerX.add(width2), centerY.add(height2)],
970
+ [centerX.sub(width2), centerY.add(height2)],
971
+ [centerX.sub(width2), centerY.sub(height2)]
823
972
  ]));
824
973
  return this;
825
974
  }
@@ -831,25 +980,15 @@ export class SymbolDrawing {
831
980
  width = milsToMM(width);
832
981
  const line = Geometry.line(startX, startY, endX, endY);
833
982
  const normLine = line.norm;
834
- const dx1 = normLine.x * width / 2;
835
- const dy1 = normLine.y * width / 2;
836
- const dx2 = normLine.x * -width / 2;
837
- const dy2 = normLine.y * -width / 2;
983
+ const dx1 = numeric(normLine.x).mul(width).div(2);
984
+ const dy1 = numeric(normLine.y).mul(width).div(2);
985
+ const dx2 = numeric(normLine.x).mul(width.neg()).div(2);
986
+ const dy2 = numeric(normLine.y).mul(width.neg()).div(2);
838
987
  this.items.push(Geometry.polygon([
839
- [dx1 + startX, dy1 + startY],
840
- [dx2 + startX, dy2 + startY],
988
+ [dx1.add(startX), dy1.add(startY)],
989
+ [dx2.add(startX), dy2.add(startY)],
841
990
  [endX, endY],
842
- [dx1 + startX, dy1 + startY],
843
- ]));
844
- return this;
845
- }
846
- addRect2(x, y, x2, y2) {
847
- this.items.push(Geometry.polygon([
848
- [x, y],
849
- [x2, y],
850
- [x2, y2],
851
- [x, y2],
852
- [x, y]
991
+ [dx1.add(startX), dy1.add(startY)],
853
992
  ]));
854
993
  return this;
855
994
  }
@@ -857,10 +996,10 @@ export class SymbolDrawing {
857
996
  this.items.push(Geometry.label(null, x, y, textValue, style));
858
997
  return this;
859
998
  }
860
- addLabelId(id, x, y, textValue, style) {
999
+ addLabelMils(x, y, textValue, style) {
861
1000
  x = milsToMM(x);
862
1001
  y = milsToMM(y);
863
- this.items.push(Geometry.label(id, x, y, textValue, style));
1002
+ this.items.push(Geometry.label(null, x, y, textValue, style));
864
1003
  return this;
865
1004
  }
866
1005
  addTextbox(x, y, textValue, style) {
@@ -869,54 +1008,59 @@ export class SymbolDrawing {
869
1008
  this.items.push(Geometry.textbox(null, x, y, textValue, style));
870
1009
  return this;
871
1010
  }
872
- addModulePort(x, y, width, height, portType = PinTypes.Any, scaleX = 1) {
873
- const height2 = height / 2;
1011
+ addModulePort(x, y, width, height, portType = PinTypes.Any, scaleX = 1, angle = 0) {
1012
+ const height2 = height.div(2);
874
1013
  let path = [];
875
1014
  const arrowSize = milsToMM(30);
876
1015
  if (portType === PinTypes.Any) {
877
1016
  path = [
878
- [0, -height2],
879
- [width, -height2],
880
- [width, +height2],
881
- [0, +height2],
882
- [0, -height2]
1017
+ [numeric(0), height2.neg()],
1018
+ [width, height2.neg()],
1019
+ [width, height2],
1020
+ [numeric(0), height2],
1021
+ [numeric(0), height2.neg()]
883
1022
  ];
884
1023
  }
885
1024
  else if (portType === PinTypes.Output) {
886
1025
  path = [
887
- [arrowSize, -height2],
888
- [width, -height2],
1026
+ [arrowSize, height2.neg()],
1027
+ [width, height2.neg()],
889
1028
  [width, height2],
890
1029
  [arrowSize, height2],
891
- [0, 0],
892
- [arrowSize, -height2]
1030
+ [numeric(0), numeric(0)],
1031
+ [arrowSize, height2.neg()]
893
1032
  ];
894
1033
  }
895
1034
  else if (portType === PinTypes.Input) {
896
1035
  path = [
897
- [0, -height2],
898
- [width - arrowSize, -height2],
899
- [width, 0],
900
- [width - arrowSize, height2],
901
- [0, +height2],
902
- [0, -height2],
1036
+ [numeric(0), height2.neg()],
1037
+ [width.sub(arrowSize), height2.neg()],
1038
+ [width, numeric(0)],
1039
+ [width.sub(arrowSize), height2],
1040
+ [numeric(0), height2],
1041
+ [numeric(0), height2.neg()],
903
1042
  ];
904
1043
  }
905
1044
  else if (portType === PinTypes.IO) {
906
1045
  path = [
907
- [arrowSize, -height2],
908
- [width - arrowSize, -height2],
909
- [width, 0],
910
- [width - arrowSize, +height2],
911
- [arrowSize, +height2],
912
- [0, 0],
913
- [0 + arrowSize, -height2],
1046
+ [arrowSize, height2.neg()],
1047
+ [width.sub(arrowSize), height2.neg()],
1048
+ [width, numeric(0)],
1049
+ [width.sub(arrowSize), height2],
1050
+ [arrowSize, height2],
1051
+ [numeric(0), numeric(0)],
1052
+ [arrowSize, height2.neg()],
914
1053
  ];
915
1054
  }
916
1055
  path = path.map(point => {
917
- return [x + point[0] * scaleX, y + point[1]];
1056
+ return [
1057
+ x.add(point[0].mul(scaleX)),
1058
+ y.add(point[1])
1059
+ ];
918
1060
  });
919
- this.items.push(Geometry.polygon(path));
1061
+ const polygon = Geometry.polygon(path)
1062
+ .rotate(angle * Math.PI / 180, Geometry.point(x, y));
1063
+ this.items.push(polygon);
920
1064
  return this;
921
1065
  }
922
1066
  addPath(...pathParts) {
@@ -925,6 +1069,9 @@ export class SymbolDrawing {
925
1069
  accum = accum.concat(tmp.split(" "));
926
1070
  }
927
1071
  else if (typeof tmp === "number") {
1072
+ accum.push(numeric(tmp));
1073
+ }
1074
+ else if (tmp instanceof NumericValue) {
928
1075
  accum.push(tmp);
929
1076
  }
930
1077
  return accum;
@@ -937,14 +1084,14 @@ export class SymbolDrawing {
937
1084
  if (currentObj !== null) {
938
1085
  geomObjects.push(currentObj);
939
1086
  }
940
- const x = milsToMM(Number(parts[i + 1]));
941
- const y = milsToMM(Number(parts[i + 2]));
1087
+ const x = milsToMM(parts[i + 1]);
1088
+ const y = milsToMM(parts[i + 2]);
942
1089
  currentObj = [[x, y]];
943
1090
  i += 2;
944
1091
  }
945
1092
  else if (command === 'L') {
946
- const x = milsToMM(Number(parts[i + 1]));
947
- const y = milsToMM(Number(parts[i + 2]));
1093
+ const x = milsToMM(parts[i + 1]);
1094
+ const y = milsToMM(parts[i + 2]);
948
1095
  currentObj.push([x, y]);
949
1096
  i += 2;
950
1097
  }
@@ -990,8 +1137,8 @@ export class SymbolDrawing {
990
1137
  x = milsToMM(x);
991
1138
  y = milsToMM(y);
992
1139
  radius = milsToMM(radius);
993
- startAngle = startAngle * Math.PI / 180;
994
- endAngle = endAngle * Math.PI / 180;
1140
+ startAngle = startAngle.mul(Math.PI).div(180);
1141
+ endAngle = endAngle.mul(Math.PI).div(180);
995
1142
  this.items.push(Geometry.arc([x, y], radius, startAngle, endAngle, true));
996
1143
  return this;
997
1144
  }
@@ -1001,7 +1148,7 @@ export class SymbolDrawing {
1001
1148
  }
1002
1149
  getPaths() {
1003
1150
  let currentFill = "#fff";
1004
- let currentLineWidth = 1;
1151
+ let currentLineWidth = numeric(1);
1005
1152
  let currentLineColor = '#333';
1006
1153
  const pathItems = [];
1007
1154
  this.items.forEach(item => {
@@ -1068,7 +1215,7 @@ export class SymbolDrawing {
1068
1215
  }
1069
1216
  getPinPosition(pinId) {
1070
1217
  const pin = this.pins.find(item => {
1071
- return item[0] === pinId;
1218
+ return item[0].toNumber() === pinId;
1072
1219
  });
1073
1220
  if (pin) {
1074
1221
  const [, feature, angle] = pin;
@@ -1086,31 +1233,27 @@ export class SymbolDrawing {
1086
1233
  }
1087
1234
  export class SymbolDrawingCommands extends SymbolDrawing {
1088
1235
  id = "";
1089
- commands;
1090
- constructor(commands) {
1236
+ commands = [];
1237
+ paramIds = [];
1238
+ callback;
1239
+ constructor(callback) {
1091
1240
  super();
1092
- this.commands = commands;
1241
+ this.callback = callback;
1093
1242
  this.id = Math.random().toString().slice(2);
1094
1243
  }
1244
+ runCommands() {
1245
+ this.commands = this.callback(this.variables);
1246
+ }
1095
1247
  getCommands() {
1248
+ this.runCommands();
1096
1249
  return this.commands;
1097
1250
  }
1098
1251
  clone() {
1099
- const tmpCommands = this.commands.map(item => {
1100
- if (item[0] === PlaceHolderCommands.label) {
1101
- const commandName = item[0];
1102
- const positionParams = item[1];
1103
- const keywordParams = item[2];
1104
- const newMap = new Map();
1105
- for (const [key, value] of keywordParams) {
1106
- newMap.set(key, value);
1107
- }
1108
- return [commandName, positionParams, newMap];
1109
- }
1110
- else {
1111
- return [...item];
1112
- }
1113
- });
1114
- return new SymbolDrawingCommands(tmpCommands);
1252
+ const cloned = new SymbolDrawingCommands(this.callback);
1253
+ cloned.variables = this.variables;
1254
+ return cloned;
1255
+ }
1256
+ eq(other) {
1257
+ return this.callback === other.callback;
1115
1258
  }
1116
1259
  }