circuitscript 0.0.28 → 0.0.31

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 (60) hide show
  1. package/dist/cjs/BaseVisitor.js +6 -1
  2. package/dist/cjs/antlr/CircuitScriptLexer.js +204 -200
  3. package/dist/cjs/antlr/CircuitScriptParser.js +1066 -1173
  4. package/dist/cjs/draw_symbols.js +383 -103
  5. package/dist/cjs/execute.js +39 -14
  6. package/dist/cjs/geometry.js +79 -18
  7. package/dist/cjs/globals.js +41 -7
  8. package/dist/cjs/helpers.js +40 -2
  9. package/dist/cjs/layout.js +72 -39
  10. package/dist/cjs/main.js +10 -4
  11. package/dist/cjs/objects/ClassComponent.js +2 -0
  12. package/dist/cjs/objects/ExecutionScope.js +1 -1
  13. package/dist/cjs/objects/Net.js +3 -2
  14. package/dist/cjs/objects/PinTypes.js +7 -1
  15. package/dist/cjs/objects/types.js +11 -1
  16. package/dist/cjs/regenerate-tests.js +84 -14
  17. package/dist/cjs/render.js +22 -15
  18. package/dist/cjs/sizing.js +4 -6
  19. package/dist/cjs/utils.js +29 -5
  20. package/dist/cjs/visitor.js +176 -10
  21. package/dist/esm/BaseVisitor.mjs +6 -1
  22. package/dist/esm/antlr/CircuitScriptLexer.mjs +204 -200
  23. package/dist/esm/antlr/CircuitScriptParser.mjs +1061 -1171
  24. package/dist/esm/antlr/CircuitScriptVisitor.mjs +3 -0
  25. package/dist/esm/draw_symbols.mjs +378 -102
  26. package/dist/esm/execute.mjs +40 -15
  27. package/dist/esm/geometry.mjs +79 -17
  28. package/dist/esm/globals.mjs +40 -6
  29. package/dist/esm/helpers.mjs +38 -1
  30. package/dist/esm/layout.mjs +75 -42
  31. package/dist/esm/main.mjs +11 -5
  32. package/dist/esm/objects/ClassComponent.mjs +6 -0
  33. package/dist/esm/objects/ExecutionScope.mjs +1 -1
  34. package/dist/esm/objects/Net.mjs +3 -2
  35. package/dist/esm/objects/PinTypes.mjs +6 -0
  36. package/dist/esm/objects/types.mjs +14 -0
  37. package/dist/esm/regenerate-tests.mjs +85 -15
  38. package/dist/esm/render.mjs +23 -16
  39. package/dist/esm/sizing.mjs +3 -4
  40. package/dist/esm/utils.mjs +26 -4
  41. package/dist/esm/visitor.mjs +179 -13
  42. package/dist/types/antlr/CircuitScriptLexer.d.ts +42 -41
  43. package/dist/types/antlr/CircuitScriptParser.d.ts +144 -133
  44. package/dist/types/antlr/CircuitScriptVisitor.d.ts +6 -0
  45. package/dist/types/draw_symbols.d.ts +24 -6
  46. package/dist/types/execute.d.ts +5 -4
  47. package/dist/types/geometry.d.ts +5 -3
  48. package/dist/types/globals.d.ts +38 -6
  49. package/dist/types/helpers.d.ts +12 -0
  50. package/dist/types/layout.d.ts +2 -1
  51. package/dist/types/objects/ClassComponent.d.ts +8 -0
  52. package/dist/types/objects/PinTypes.d.ts +1 -0
  53. package/dist/types/objects/Wire.d.ts +4 -2
  54. package/dist/types/objects/types.d.ts +8 -0
  55. package/dist/types/sizing.d.ts +0 -4
  56. package/dist/types/utils.d.ts +3 -0
  57. package/dist/types/visitor.d.ts +8 -1
  58. package/fonts/Arial.ttf +0 -0
  59. package/libs/lib.cst +78 -55
  60. package/package.json +1 -1
@@ -1,10 +1,11 @@
1
- import { ReferenceTypes, SymbolPinSide, defaultFont } from "./globals.mjs";
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";
2
3
  import { Geometry, GeometryProp, HorizontalAlign, Textbox, VerticalAlign } from "./geometry.mjs";
3
4
  import { PinTypes } from "./objects/PinTypes.mjs";
4
- const defaultSymbolLineWidth = 2;
5
+ import { roundValue } from "./utils.mjs";
5
6
  export class SymbolGraphic {
6
7
  drawPortsName = true;
7
- displayBounds = true;
8
+ displayBounds = false;
8
9
  drawing;
9
10
  _angle = 0;
10
11
  _flipX = 0;
@@ -51,6 +52,7 @@ export class SymbolGraphic {
51
52
  this.drawPins(innerGroup);
52
53
  this.drawLabels(innerGroup);
53
54
  this.drawPlaceRemove(innerGroup, extra);
55
+ this.displayBounds && this.drawBounds(group);
54
56
  }
55
57
  drawPlaceRemove(group, extra) {
56
58
  if (extra && extra.place === false) {
@@ -69,8 +71,8 @@ export class SymbolGraphic {
69
71
  pinPosition(id) {
70
72
  const pin = this.drawing.getPinPosition(id);
71
73
  const [x, y] = pin.start;
72
- const useX = Math.round(x * 10000) / 10000;
73
- const useY = Math.round(y * 10000 / 10000);
74
+ const useX = roundValue(x);
75
+ const useY = roundValue(y);
74
76
  return {
75
77
  x: useX,
76
78
  y: useY,
@@ -79,15 +81,16 @@ export class SymbolGraphic {
79
81
  }
80
82
  drawBounds(group) {
81
83
  const bbox = this.drawing.getBoundingBox();
82
- group.circle(3)
83
- .translate(-3 / 2, -3 / 2)
84
+ const originSize = milsToMM(10);
85
+ group.circle(originSize)
86
+ .translate(-originSize / 2, -originSize / 2)
84
87
  .fill('red')
85
88
  .stroke('none');
86
89
  group.rect(bbox.width, bbox.height)
87
90
  .translate(bbox.start[0], bbox.start[1])
88
91
  .fill('none')
89
92
  .stroke({
90
- width: 1,
93
+ width: milsToMM(2),
91
94
  color: '#ccc',
92
95
  });
93
96
  }
@@ -104,17 +107,20 @@ export class SymbolGraphic {
104
107
  });
105
108
  }
106
109
  drawPins(group) {
107
- group.path(this.drawing.getPinsPath())
108
- .stroke({
109
- width: defaultSymbolLineWidth,
110
- color: '#333',
110
+ const pinPaths = this.drawing.getPinsPath();
111
+ pinPaths.forEach(({ path, lineColor }) => {
112
+ group.path(path)
113
+ .stroke({
114
+ width: defaultSymbolLineWidth,
115
+ color: lineColor
116
+ });
111
117
  });
112
118
  }
113
119
  drawLabels(group) {
114
120
  const labels = this.drawing.getLabels();
115
121
  labels.forEach(label => {
116
122
  const tmpLabel = label;
117
- const { fontSize = 10, anchor = HorizontalAlign.Left, vanchor = VerticalAlign.Bottom, fontWeight = 'regular', angle: labelAngle = 0, } = tmpLabel.style ?? {};
123
+ const { fontSize = 50, anchor = HorizontalAlign.Left, vanchor = VerticalAlign.Bottom, fontWeight = 'regular', angle: labelAngle = 0, textColor = "#333", } = tmpLabel.style ?? {};
118
124
  let anchorStyle = 'start';
119
125
  let dominantBaseline = 'auto';
120
126
  let useAnchor = anchor;
@@ -155,15 +161,6 @@ export class SymbolGraphic {
155
161
  }
156
162
  const useFont = defaultFont;
157
163
  const textContainer = group.group();
158
- const text = textContainer.text(tmpLabel.text)
159
- .fill('#333')
160
- .font({
161
- family: useFont,
162
- size: fontSize,
163
- anchor: anchorStyle,
164
- 'dominant-baseline': dominantBaseline,
165
- weight: fontWeight,
166
- });
167
164
  let translateX, translateY;
168
165
  let useRotateAngle = 0;
169
166
  if (isRotation180) {
@@ -176,26 +173,121 @@ export class SymbolGraphic {
176
173
  translateY = position[1];
177
174
  useRotateAngle = this.angle;
178
175
  }
179
- translateX = this.roundValues(translateX);
180
- translateY = this.roundValues(translateY);
181
- text.rotate(labelAngle);
176
+ translateX = roundValue(translateX);
177
+ translateY = roundValue(translateY);
178
+ const { portType = null } = tmpLabel.style;
179
+ if (portType !== null) {
180
+ const { x: boundsX, y: boundsY } = tmpLabel.textMeasurementBounds;
181
+ const paddingHorizontal = PortPaddingHorizontal;
182
+ const paddingVert = PortPaddingVertical;
183
+ const boundsWidth = tmpLabel.textMeasurementBounds.width
184
+ + paddingHorizontal * 2;
185
+ const boundsHeight = tmpLabel.textMeasurementBounds.height
186
+ + paddingVert * 2;
187
+ let path = [];
188
+ let boundsTranslateX = -paddingHorizontal;
189
+ switch (portType) {
190
+ case PinTypes.Input:
191
+ path = ['M', 0, 0,
192
+ 'L', boundsWidth, 0,
193
+ 'L', boundsWidth, boundsHeight,
194
+ 'L', 0, boundsHeight,
195
+ 'L', -PortArrowSize, boundsHeight / 2,
196
+ 'Z',
197
+ ];
198
+ break;
199
+ case PinTypes.Output:
200
+ path = ['M', 0, 0,
201
+ 'L', boundsWidth, 0,
202
+ 'L', boundsWidth + PortArrowSize,
203
+ boundsHeight / 2,
204
+ 'L', boundsWidth, boundsHeight,
205
+ 'L', 0, boundsHeight,
206
+ 'Z',
207
+ ];
208
+ break;
209
+ case PinTypes.IO:
210
+ path = ['M', 0, 0,
211
+ 'L', boundsWidth, 0,
212
+ 'L', boundsWidth + PortArrowSize,
213
+ boundsHeight / 2,
214
+ 'L', boundsWidth, boundsHeight,
215
+ 'L', 0, boundsHeight,
216
+ 'L', -PortArrowSize, boundsHeight / 2,
217
+ 'Z',
218
+ ];
219
+ break;
220
+ case PinTypes.Any:
221
+ case PinTypes.Power:
222
+ path = ['M', 0, 0,
223
+ 'L', boundsWidth, 0,
224
+ 'L', boundsWidth, boundsHeight,
225
+ 'L', 0, boundsHeight,
226
+ 'Z',
227
+ ];
228
+ break;
229
+ }
230
+ if (path.length > 0) {
231
+ let flip = 1;
232
+ if (this.flipX !== 0) {
233
+ flip = -1;
234
+ boundsTranslateX = paddingHorizontal;
235
+ }
236
+ textContainer.path(path)
237
+ .stroke({
238
+ width: milsToMM(5),
239
+ color: '#333'
240
+ })
241
+ .fill('none')
242
+ .scale(flip, 1, 0, 0)
243
+ .translate(boundsTranslateX, boundsY - paddingVert);
244
+ }
245
+ }
246
+ const drawTextBounds = false;
247
+ const drawBoxBounds = false;
248
+ const drawOrigin = false;
249
+ if (drawBoxBounds) {
250
+ const box = tmpLabel.box;
251
+ textContainer.rect(box.width, box.height).fill('red')
252
+ .translate(box.xmin, box.ymin)
253
+ .scale(this.flipX !== 0 ? -1 : 1, 1, -box.xmin, box.ymin);
254
+ }
255
+ if (drawTextBounds) {
256
+ const textBounds = tmpLabel.textMeasurementBounds;
257
+ const xOffset = (this.flipX !== 0) ? textBounds.width : 0;
258
+ textContainer.rect(textBounds.width, textBounds.height).fill('#cccccc')
259
+ .translate(textBounds.x - xOffset, textBounds.y);
260
+ }
182
261
  textContainer.translate(translateX, translateY)
183
262
  .rotate(useRotateAngle, -translateX, -translateY);
263
+ textContainer.text(tmpLabel.text)
264
+ .fill(textColor)
265
+ .font({
266
+ family: useFont,
267
+ size: fontSize * fontDisplayScale,
268
+ anchor: anchorStyle,
269
+ 'dominant-baseline': dominantBaseline,
270
+ weight: fontWeight,
271
+ })
272
+ .rotate(labelAngle);
184
273
  const { a, b, c, d, e, f } = textContainer.matrix();
185
274
  const newMatrix = {
186
- a: this.roundValues(a),
187
- b: this.roundValues(b),
188
- c: this.roundValues(c),
189
- d: this.roundValues(d),
190
- e: this.roundValues(e),
191
- f: this.roundValues(f),
275
+ a: roundValue(a),
276
+ b: roundValue(b),
277
+ c: roundValue(c),
278
+ d: roundValue(d),
279
+ e: roundValue(e),
280
+ f: roundValue(f),
192
281
  };
193
282
  textContainer.transform(newMatrix);
283
+ if (drawOrigin) {
284
+ const originSize = milsToMM(10);
285
+ textContainer.circle(originSize)
286
+ .translate(originSize / 2, originSize / 2)
287
+ .fill('green');
288
+ }
194
289
  });
195
290
  }
196
- roundValues(value) {
197
- return +value.toFixed(7);
198
- }
199
291
  flipTextAnchor(value) {
200
292
  if (value === HorizontalAlign.Left) {
201
293
  return HorizontalAlign.Right;
@@ -244,7 +336,7 @@ export class SymbolPointHidden extends SymbolGraphic {
244
336
  }
245
337
  export class SymbolText extends SymbolGraphic {
246
338
  text;
247
- fontSize = 10;
339
+ fontSize = 40;
248
340
  fontWeight = 'regular';
249
341
  constructor(text) {
250
342
  super();
@@ -268,8 +360,16 @@ export class SymbolPlaceholder extends SymbolGraphic {
268
360
  drawing.angle = this._angle;
269
361
  drawing.flipX = this._flipX;
270
362
  drawing.flipY = this._flipY;
271
- const commands = drawing.getCommands();
363
+ const commands = [
364
+ [PlaceHolderCommands.units, ['mils'], {}],
365
+ [PlaceHolderCommands.lineColor, [ColorScheme.PinLineColor], {}],
366
+ [PlaceHolderCommands.textColor, [ColorScheme.PinNameColor], {}],
367
+ [PlaceHolderCommands.lineWidth, [5], {}],
368
+ ...drawing.getCommands()
369
+ ];
272
370
  drawing.log('id: ', drawing.id, 'angle: ', this._angle, "commands:", commands.length);
371
+ let lineColor = "#333";
372
+ let textColor = "#333";
273
373
  commands.forEach(([commandName, positionParams, keywordParams]) => {
274
374
  switch (commandName) {
275
375
  case PlaceHolderCommands.rect:
@@ -299,6 +399,11 @@ export class SymbolPlaceholder extends SymbolGraphic {
299
399
  break;
300
400
  case PlaceHolderCommands.lineColor:
301
401
  drawing.addSetLineColor(...positionParams);
402
+ lineColor = positionParams[0];
403
+ break;
404
+ case PlaceHolderCommands.textColor:
405
+ drawing.addSetTextColor(...positionParams);
406
+ textColor = positionParams[0];
302
407
  break;
303
408
  case PlaceHolderCommands.arc:
304
409
  drawing.addArc(...positionParams);
@@ -313,11 +418,14 @@ export class SymbolPlaceholder extends SymbolGraphic {
313
418
  case PlaceHolderCommands.hpin:
314
419
  case PlaceHolderCommands.vpin:
315
420
  {
316
- this.drawPinParams(drawing, commandName, keywordParams, positionParams);
421
+ this.drawPinParams(drawing, commandName, keywordParams, positionParams, lineColor, textColor);
317
422
  break;
318
423
  }
319
424
  case PlaceHolderCommands.label: {
320
425
  const style = this.parseLabelStyle(keywordParams);
426
+ if (style['textColor'] === undefined) {
427
+ style['textColor'] = textColor;
428
+ }
321
429
  positionParams = [...positionParams];
322
430
  positionParams.push(style);
323
431
  const labelId = positionParams[0];
@@ -343,12 +451,17 @@ export class SymbolPlaceholder extends SymbolGraphic {
343
451
  drawing.addTextbox(offsetX, offsetY, content, style);
344
452
  break;
345
453
  }
454
+ case PlaceHolderCommands.units: {
455
+ drawing.addSetUnits(...positionParams);
456
+ break;
457
+ }
346
458
  }
347
459
  });
348
460
  drawing.log("=== end generate drawing ===");
349
461
  }
350
462
  parseLabelStyle(keywordParams) {
351
- const keywords = ['fontSize', 'anchor', 'vanchor', 'angle'];
463
+ const keywords = ['fontSize', 'anchor', 'vanchor',
464
+ 'angle', 'textColor', 'portType'];
352
465
  const style = {};
353
466
  keywords.forEach(item => {
354
467
  if (keywordParams.has(item)) {
@@ -357,13 +470,16 @@ export class SymbolPlaceholder extends SymbolGraphic {
357
470
  });
358
471
  return style;
359
472
  }
360
- drawPinParams(drawing, commandName, keywordParams, positionParams) {
473
+ drawPinParams(drawing, commandName, keywordParams, positionParams, lineColor, pinNameColor) {
361
474
  drawing.log('add pin', ...positionParams);
475
+ positionParams = [...positionParams];
362
476
  const keywordDisplayPinId = 'display_pin_id';
363
477
  let displayPinId = true;
364
- if (keywordParams.has(keywordDisplayPinId)
365
- && keywordParams.get(keywordDisplayPinId) === 0) {
366
- displayPinId = false;
478
+ if (keywordParams.has(keywordDisplayPinId)) {
479
+ const value = keywordParams.get(keywordDisplayPinId);
480
+ if (value === 0 || value === false) {
481
+ displayPinId = false;
482
+ }
367
483
  }
368
484
  let pinNameParam = null;
369
485
  let pinType = PinTypes.Any;
@@ -375,10 +491,10 @@ export class SymbolPlaceholder extends SymbolGraphic {
375
491
  pinNameParam = positionParams[1];
376
492
  positionParams = [positionParams[0], ...positionParams.slice(2)];
377
493
  }
378
- const startX = positionParams[1];
379
- const startY = positionParams[2];
494
+ const startX = milsToMM(positionParams[1]);
495
+ const startY = milsToMM(positionParams[2]);
380
496
  if (commandName === PlaceHolderCommands.vpin) {
381
- const magnitude = positionParams[3];
497
+ const magnitude = milsToMM(positionParams[3]);
382
498
  positionParams = [
383
499
  positionParams[0],
384
500
  startX,
@@ -388,7 +504,7 @@ export class SymbolPlaceholder extends SymbolGraphic {
388
504
  ];
389
505
  }
390
506
  else if (commandName === PlaceHolderCommands.hpin) {
391
- const magnitude = positionParams[3];
507
+ const magnitude = milsToMM(positionParams[3]);
392
508
  positionParams = [
393
509
  positionParams[0],
394
510
  startX,
@@ -397,50 +513,64 @@ export class SymbolPlaceholder extends SymbolGraphic {
397
513
  startY
398
514
  ];
399
515
  }
400
- drawing.addPin(...positionParams);
516
+ else {
517
+ const [, , , endX, endY] = positionParams;
518
+ positionParams = [
519
+ positionParams[0],
520
+ startX,
521
+ startY,
522
+ milsToMM(endX),
523
+ milsToMM(endY)
524
+ ];
525
+ }
526
+ drawing.addPinMM(...positionParams, lineColor);
401
527
  const lastAddedPin = this.drawing.pins[this.drawing.pins.length - 1];
402
528
  const [pinId, , angle] = lastAddedPin;
403
529
  const [, , , endX, endY] = positionParams;
404
530
  let pinNameAlignment = HorizontalAlign.Left;
405
- let pinNameOffsetX = 4;
531
+ const offset1 = 15;
532
+ const offset2 = 15;
533
+ let pinNameOffsetX = milsToMM(offset1);
406
534
  let pinIdOffsetX = 0;
407
535
  let pinIdAlignment = HorizontalAlign.Left;
408
536
  let pinIdVAlignment = VerticalAlign.Bottom;
409
- let pinIdOffsetY = -2;
537
+ let pinIdOffsetY = milsToMM(-offset2);
410
538
  switch (angle) {
411
539
  case 0:
412
540
  pinNameAlignment = HorizontalAlign.Left;
413
- pinNameOffsetX = 4;
541
+ pinNameOffsetX = milsToMM(offset1);
414
542
  pinIdAlignment = HorizontalAlign.Right;
415
- pinIdOffsetX = -2;
543
+ pinIdOffsetX = milsToMM(-offset2);
416
544
  break;
417
545
  case 90:
418
546
  case 180:
419
547
  pinNameAlignment = HorizontalAlign.Right;
420
- pinNameOffsetX = -4;
548
+ pinNameOffsetX = milsToMM(-offset1);
421
549
  pinIdAlignment = HorizontalAlign.Left;
422
- pinIdOffsetX = 2;
550
+ pinIdOffsetX = milsToMM(offset2);
423
551
  break;
424
552
  case 270:
425
553
  pinNameAlignment = HorizontalAlign.Left;
426
- pinNameOffsetX = 4;
554
+ pinNameOffsetX = milsToMM(offset1);
427
555
  pinIdAlignment = HorizontalAlign.Left;
428
- pinIdOffsetX = 2;
429
- pinIdOffsetY = 2;
556
+ pinIdOffsetX = milsToMM(offset2);
557
+ pinIdOffsetY = milsToMM(offset2);
430
558
  pinIdVAlignment = VerticalAlign.Top;
431
559
  break;
432
560
  }
433
561
  if (angle === 0 || angle === 90 || angle === 180 || angle === 270) {
434
562
  const usePinName = pinNameParam ?? "";
435
563
  usePinName !== "" && drawing.addLabel(endX + pinNameOffsetX, endY, usePinName, {
436
- fontSize: 10,
564
+ fontSize: defaultPinNameTextSize,
437
565
  anchor: pinNameAlignment,
438
566
  vanchor: VerticalAlign.Middle,
567
+ textColor: pinNameColor,
439
568
  });
440
569
  displayPinId && drawing.addLabel(endX + pinIdOffsetX, endY + pinIdOffsetY, pinId.toString(), {
441
- fontSize: 8,
570
+ fontSize: defaultPinIdTextSize,
442
571
  anchor: pinIdAlignment,
443
572
  vanchor: pinIdVAlignment,
573
+ textColor: lineColor
444
574
  });
445
575
  }
446
576
  }
@@ -466,16 +596,18 @@ export var PlaceHolderCommands;
466
596
  PlaceHolderCommands["lineWidth"] = "lineWidth";
467
597
  PlaceHolderCommands["fill"] = "fill";
468
598
  PlaceHolderCommands["lineColor"] = "lineColor";
599
+ PlaceHolderCommands["textColor"] = "textColor";
469
600
  PlaceHolderCommands["text"] = "text";
601
+ PlaceHolderCommands["units"] = "units";
470
602
  })(PlaceHolderCommands || (PlaceHolderCommands = {}));
471
603
  export class SymbolCustom extends SymbolGraphic {
472
604
  pinDefinition = [];
473
- bodyWidth = 100;
474
- pinLength = 20;
475
- width = 100;
476
- height = 100;
477
- pinSpacing = 20;
478
- pinTextPadding = 5;
605
+ bodyWidth = milsToMM(400);
606
+ pinLength = milsToMM(100);
607
+ width = milsToMM(100);
608
+ height = milsToMM(100);
609
+ pinSpacing = milsToMM(100);
610
+ pinTextPadding = milsToMM(5);
479
611
  pins = [];
480
612
  _cacheLeftPins;
481
613
  _cacheRightPins;
@@ -498,65 +630,109 @@ export class SymbolCustom extends SymbolGraphic {
498
630
  drawing.flipY = this._flipY;
499
631
  const bodyWidth = this.bodyWidth;
500
632
  const bodyHeight = (1 + Math.max(maxLeftPins, maxRightPins)) * this.pinSpacing;
501
- drawing.addRect(0, 0, bodyWidth, bodyHeight);
502
- const leftPinStart = -bodyWidth / 2;
503
- const rightPinStart = bodyWidth / 2;
504
- const pinStartY = -bodyHeight / 2;
633
+ const defaultLineColor = ColorScheme.PinLineColor;
634
+ drawing.addSetLineColor(defaultLineColor);
635
+ drawing.addSetLineWidth(5);
636
+ drawing.addRectMM(0, 0, bodyWidth, bodyHeight);
637
+ this.generateDrawingPins(drawing, bodyWidth, bodyHeight, leftPins, rightPins, defaultLineColor);
638
+ this.drawing = drawing;
639
+ this._cacheLeftPins = leftPins;
640
+ this._cacheRightPins = rightPins;
641
+ }
642
+ generateDrawingPins(drawing, bodyWidthMM, bodyHeightMM, leftPins, rightPins, defaultLineColor) {
643
+ const leftPinStart = -bodyWidthMM / 2;
644
+ const rightPinStart = bodyWidthMM / 2;
645
+ const pinStartY = -bodyHeightMM / 2;
505
646
  leftPins.forEach(pin => {
506
647
  const position = pin.position;
507
648
  const pinY = pinStartY + (position + 1) * this.pinSpacing;
508
- drawing.addPin(pin.pinId, leftPinStart - this.pinLength, pinY, leftPinStart, pinY);
509
- drawing.addLabel(leftPinStart + 4, pinY, pin.text, {
510
- fontSize: 10,
649
+ drawing.addPinMM(pin.pinId, leftPinStart - this.pinLength, pinY, leftPinStart, pinY, defaultLineColor);
650
+ drawing.addLabel(leftPinStart + milsToMM(20), pinY, pin.text, {
651
+ fontSize: CustomSymbolPinTextSize,
511
652
  anchor: HorizontalAlign.Left,
512
653
  vanchor: VerticalAlign.Middle,
654
+ textColor: ColorScheme.PinNameColor,
513
655
  });
514
- drawing.addLabel(leftPinStart - 2, pinY - 2, pin.pinId.toString(), {
515
- fontSize: 8,
656
+ drawing.addLabel(leftPinStart - milsToMM(10), pinY - milsToMM(10), pin.pinId.toString(), {
657
+ fontSize: CustomSymbolPinIdSize,
516
658
  anchor: HorizontalAlign.Right,
517
659
  vanchor: VerticalAlign.Bottom,
660
+ textColor: defaultLineColor
518
661
  });
519
662
  });
520
663
  rightPins.forEach(pin => {
521
664
  const position = pin.position;
522
665
  const pinY = pinStartY + (position + 1) * this.pinSpacing;
523
- drawing.addPin(pin.pinId, rightPinStart + this.pinLength, pinY, rightPinStart, pinY);
524
- drawing.addLabel(rightPinStart - 4, pinY, pin.text, {
525
- fontSize: 10,
666
+ drawing.addPinMM(pin.pinId, rightPinStart + this.pinLength, pinY, rightPinStart, pinY, defaultLineColor);
667
+ drawing.addLabel(rightPinStart - milsToMM(20), pinY, pin.text, {
668
+ fontSize: CustomSymbolPinTextSize,
526
669
  anchor: HorizontalAlign.Right,
527
670
  vanchor: VerticalAlign.Middle,
671
+ textColor: ColorScheme.PinNameColor,
528
672
  });
529
- drawing.addLabel(rightPinStart + 2, pinY - 2, pin.pinId.toString(), {
530
- fontSize: 8,
673
+ drawing.addLabel(rightPinStart + milsToMM(10), pinY - milsToMM(10), pin.pinId.toString(), {
674
+ fontSize: CustomSymbolPinIdSize,
531
675
  anchor: HorizontalAlign.Left,
532
676
  vanchor: VerticalAlign.Bottom,
677
+ textColor: defaultLineColor
533
678
  });
534
679
  });
535
680
  const instanceName = this.getLabelValue("refdes");
536
- instanceName && drawing.addLabel(-bodyWidth / 2, -bodyHeight / 2 - 4, instanceName, {
537
- fontSize: 10,
681
+ instanceName && drawing.addLabel(-bodyWidthMM / 2, -bodyHeightMM / 2 - milsToMM(20), instanceName, {
682
+ fontSize: CustomSymbolRefDesSize,
538
683
  anchor: HorizontalAlign.Left,
539
684
  });
540
685
  const acceptedMPNKeys = ['MPN', 'mpn', 'manufacturer_pn'];
541
686
  acceptedMPNKeys.some(key => {
542
687
  const labelValue = this.getLabelValue(key);
543
688
  if (labelValue !== undefined) {
544
- drawing.addLabel(-bodyWidth / 2, bodyHeight / 2 + 4, labelValue, {
545
- fontSize: 10,
689
+ drawing.addLabel(-bodyWidthMM / 2, bodyHeightMM / 2 + milsToMM(20), labelValue, {
690
+ fontSize: CustomSymbolParamTextSize,
546
691
  anchor: HorizontalAlign.Left,
547
692
  vanchor: VerticalAlign.Top,
548
693
  });
549
694
  }
550
695
  });
551
- this.drawing = drawing;
552
- this._cacheLeftPins = leftPins;
553
- this._cacheRightPins = rightPins;
554
696
  }
555
697
  calculateSize() {
556
698
  this.width = this.bodyWidth + 2 * this.pinLength;
557
699
  this.height = (1 + Math.max(this._cacheLeftPins.length, this._cacheRightPins.length)) * this.pinSpacing;
558
700
  }
559
701
  }
702
+ export class SymbolCustomModule extends SymbolCustom {
703
+ pinLength = 0;
704
+ portWidth = milsToMM(100);
705
+ portHeight = milsToMM(50);
706
+ generateDrawingPins(drawing, bodyWidthMM, bodyHeightMM, leftPins, rightPins, defaultLineColor) {
707
+ const leftPinStart = -bodyWidthMM / 2;
708
+ const rightPinStart = bodyWidthMM / 2;
709
+ const pinStartY = -bodyHeightMM / 2;
710
+ leftPins.forEach(pin => {
711
+ const position = pin.position;
712
+ const pinY = pinStartY + (position + 1) * this.pinSpacing;
713
+ drawing.addPinMM(pin.pinId, leftPinStart - this.pinLength, pinY, leftPinStart, pinY, defaultLineColor);
714
+ drawing.addModulePort(leftPinStart, pinY, this.portWidth, this.portHeight, pin.pinType);
715
+ drawing.addLabel(leftPinStart + this.portWidth + milsToMM(20), pinY, pin.text, {
716
+ fontSize: 40,
717
+ anchor: HorizontalAlign.Left,
718
+ vanchor: VerticalAlign.Middle,
719
+ textColor: ColorScheme.PinNameColor,
720
+ });
721
+ });
722
+ rightPins.forEach(pin => {
723
+ const position = pin.position;
724
+ const pinY = pinStartY + (position + 1) * this.pinSpacing;
725
+ drawing.addPinMM(pin.pinId, rightPinStart + this.pinLength, pinY, rightPinStart, pinY, defaultLineColor);
726
+ drawing.addModulePort(rightPinStart, pinY, this.portWidth, this.portHeight, pin.pinType, -1);
727
+ drawing.addLabel(rightPinStart - this.portWidth - milsToMM(20), pinY, pin.text, {
728
+ fontSize: 40,
729
+ anchor: HorizontalAlign.Right,
730
+ vanchor: VerticalAlign.Middle,
731
+ textColor: ColorScheme.PinNameColor,
732
+ });
733
+ });
734
+ }
735
+ }
560
736
  export class SymbolDrawing {
561
737
  items = [];
562
738
  pins = [];
@@ -573,43 +749,68 @@ export class SymbolDrawing {
573
749
  this.logger && this.logger.add(params.join(' '));
574
750
  }
575
751
  addLine(startX, startY, endX, endY) {
752
+ startX = milsToMM(startX);
753
+ startY = milsToMM(startY);
754
+ endX = milsToMM(endX);
755
+ endY = milsToMM(endY);
576
756
  this.items.push(Geometry.segment([startX, startY], [endX, endY]));
577
757
  return this;
578
758
  }
579
- addPin(pinId, startX, startY, endX, endY) {
759
+ addPin(pinId, startX, startY, endX, endY, lineColor) {
760
+ startX = milsToMM(startX);
761
+ startY = milsToMM(startY);
762
+ endX = milsToMM(endX);
763
+ endY = milsToMM(endY);
764
+ return this.addPinMM(pinId, startX, startY, endX, endY, lineColor);
765
+ }
766
+ addPinMM(pinId, startXMM, startYMM, endXMM, endYMM, lineColor) {
580
767
  let angle = 0;
581
- if (startX === endX) {
582
- if (startY > endY) {
768
+ if (startXMM === endXMM) {
769
+ if (startYMM > endYMM) {
583
770
  angle = 270;
584
771
  }
585
- else if (startY < endY) {
772
+ else if (startYMM < endYMM) {
586
773
  angle = 90;
587
774
  }
588
775
  }
589
776
  else {
590
- if (startX < endX) {
777
+ if (startXMM < endXMM) {
591
778
  angle = 0;
592
779
  }
593
- else if (startX > endX) {
780
+ else if (startXMM > endXMM) {
594
781
  angle = 180;
595
782
  }
596
783
  }
597
784
  this.pins.push([
598
785
  pinId,
599
- Geometry.segment([startX, startY], [endX, endY]),
600
- angle
786
+ Geometry.segment([startXMM, startYMM], [endXMM, endYMM]),
787
+ angle,
788
+ lineColor
601
789
  ]);
602
790
  return this;
603
791
  }
604
792
  addVLine(startX, startY, value) {
793
+ startX = milsToMM(startX);
794
+ startY = milsToMM(startY);
795
+ value = milsToMM(value);
605
796
  this.items.push(Geometry.segment([startX, startY], [startX, startY + value]));
606
797
  return this;
607
798
  }
608
799
  addHLine(startX, startY, value) {
800
+ startX = milsToMM(startX);
801
+ startY = milsToMM(startY);
802
+ value = milsToMM(value);
609
803
  this.items.push(Geometry.segment([startX, startY], [startX + value, startY]));
610
804
  return this;
611
805
  }
612
806
  addRect(centerX, centerY, width, height) {
807
+ centerX = milsToMM(centerX);
808
+ centerY = milsToMM(centerY);
809
+ width = milsToMM(width);
810
+ height = milsToMM(height);
811
+ return this.addRectMM(centerX, centerY, width, height);
812
+ }
813
+ addRectMM(centerX, centerY, width, height) {
613
814
  const width2 = width / 2;
614
815
  const height2 = height / 2;
615
816
  this.items.push(Geometry.polygon([
@@ -622,6 +823,11 @@ export class SymbolDrawing {
622
823
  return this;
623
824
  }
624
825
  addTriangle(startX, startY, endX, endY, width) {
826
+ startX = milsToMM(startX);
827
+ startY = milsToMM(startY);
828
+ endX = milsToMM(endX);
829
+ endY = milsToMM(endY);
830
+ width = milsToMM(width);
625
831
  const line = Geometry.line(startX, startY, endX, endY);
626
832
  const normLine = line.norm;
627
833
  const dx1 = normLine.x * width / 2;
@@ -651,13 +857,67 @@ export class SymbolDrawing {
651
857
  return this;
652
858
  }
653
859
  addLabelId(id, x, y, textValue, style) {
860
+ x = milsToMM(x);
861
+ y = milsToMM(y);
654
862
  this.items.push(Geometry.label(id, x, y, textValue, style));
655
863
  return this;
656
864
  }
657
865
  addTextbox(x, y, textValue, style) {
866
+ x = milsToMM(x);
867
+ y = milsToMM(y);
658
868
  this.items.push(Geometry.textbox(null, x, y, textValue, style));
659
869
  return this;
660
870
  }
871
+ addModulePort(x, y, width, height, portType = PinTypes.Any, scaleX = 1) {
872
+ const height2 = height / 2;
873
+ let path = [];
874
+ const arrowSize = milsToMM(30);
875
+ if (portType === PinTypes.Any) {
876
+ path = [
877
+ [0, -height2],
878
+ [width, -height2],
879
+ [width, +height2],
880
+ [0, +height2],
881
+ [0, -height2]
882
+ ];
883
+ }
884
+ else if (portType === PinTypes.Output) {
885
+ path = [
886
+ [arrowSize, -height2],
887
+ [width, -height2],
888
+ [width, height2],
889
+ [arrowSize, height2],
890
+ [0, 0],
891
+ [arrowSize, -height2]
892
+ ];
893
+ }
894
+ else if (portType === PinTypes.Input) {
895
+ path = [
896
+ [0, -height2],
897
+ [width - arrowSize, -height2],
898
+ [width, 0],
899
+ [width - arrowSize, height2],
900
+ [0, +height2],
901
+ [0, -height2],
902
+ ];
903
+ }
904
+ else if (portType === PinTypes.IO) {
905
+ path = [
906
+ [arrowSize, -height2],
907
+ [width - arrowSize, -height2],
908
+ [width, 0],
909
+ [width - arrowSize, +height2],
910
+ [arrowSize, +height2],
911
+ [0, 0],
912
+ [0 + arrowSize, -height2],
913
+ ];
914
+ }
915
+ path = path.map(point => {
916
+ return [x + point[0] * scaleX, y + point[1]];
917
+ });
918
+ this.items.push(Geometry.polygon(path));
919
+ return this;
920
+ }
661
921
  addPath(...pathParts) {
662
922
  const parts = pathParts.reduce((accum, tmp) => {
663
923
  if (typeof tmp === "string") {
@@ -676,14 +936,14 @@ export class SymbolDrawing {
676
936
  if (currentObj !== null) {
677
937
  geomObjects.push(currentObj);
678
938
  }
679
- const x = Number(parts[i + 1]);
680
- const y = Number(parts[i + 2]);
939
+ const x = milsToMM(Number(parts[i + 1]));
940
+ const y = milsToMM(Number(parts[i + 2]));
681
941
  currentObj = [[x, y]];
682
942
  i += 2;
683
943
  }
684
944
  else if (command === 'L') {
685
- const x = Number(parts[i + 1]);
686
- const y = Number(parts[i + 2]);
945
+ const x = milsToMM(Number(parts[i + 1]));
946
+ const y = milsToMM(Number(parts[i + 2]));
687
947
  currentObj.push([x, y]);
688
948
  i += 2;
689
949
  }
@@ -709,6 +969,7 @@ export class SymbolDrawing {
709
969
  return this;
710
970
  }
711
971
  addSetLineWidth(value) {
972
+ value = milsToMM(value);
712
973
  this.items.push(new GeometryProp('lineWidth', value));
713
974
  return this;
714
975
  }
@@ -716,16 +977,27 @@ export class SymbolDrawing {
716
977
  this.items.push(new GeometryProp('lineColor', value));
717
978
  return this;
718
979
  }
980
+ addSetTextColor(value) {
981
+ this.items.push(new GeometryProp('textColor', value));
982
+ return this;
983
+ }
719
984
  addSetFillColor(value) {
720
985
  this.items.push(new GeometryProp('fillColor', value));
721
986
  return this;
722
987
  }
723
988
  addArc(x, y, radius, startAngle, endAngle) {
989
+ x = milsToMM(x);
990
+ y = milsToMM(y);
991
+ radius = milsToMM(radius);
724
992
  startAngle = startAngle * Math.PI / 180;
725
993
  endAngle = endAngle * Math.PI / 180;
726
994
  this.items.push(Geometry.arc([x, y], radius, startAngle, endAngle, true));
727
995
  return this;
728
996
  }
997
+ addSetUnits(value) {
998
+ this.items.push(new GeometryProp('units', value));
999
+ return this;
1000
+ }
729
1001
  getPaths() {
730
1002
  let currentFill = "#fff";
731
1003
  let currentLineWidth = 1;
@@ -760,11 +1032,15 @@ export class SymbolDrawing {
760
1032
  return pathItems;
761
1033
  }
762
1034
  getPinsPath() {
763
- let features = this.pins.map(item => item[1]);
764
- features = Geometry.groupFlip(features, this.flipX, this.flipY);
765
- features = Geometry.groupRotate(features, this.angle, this.mainOrigin);
766
- const { path } = this.featuresToPath(features, this.flipX, this.flipY);
767
- return path;
1035
+ return this.pins.map(item => {
1036
+ let features = Geometry.groupFlip([item[1]], this.flipX, this.flipY);
1037
+ features = Geometry.groupRotate(features, this.angle, this.mainOrigin);
1038
+ const { path } = this.featuresToPath(features, this.flipX, this.flipY);
1039
+ return {
1040
+ path,
1041
+ lineColor: item[3],
1042
+ };
1043
+ });
768
1044
  }
769
1045
  getLabels() {
770
1046
  return this.items.filter(item => item instanceof Textbox);