circuit-to-svg 0.0.66 → 0.0.68
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1073 -144
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -1,21 +1,119 @@
|
|
|
1
1
|
// lib/pcb/convert-circuit-json-to-pcb-svg.ts
|
|
2
2
|
import { stringify } from "svgson";
|
|
3
3
|
import {
|
|
4
|
-
applyToPoint as
|
|
4
|
+
applyToPoint as applyToPoint12,
|
|
5
5
|
compose as compose3,
|
|
6
6
|
scale,
|
|
7
7
|
translate as translate3
|
|
8
8
|
} from "transformation-matrix";
|
|
9
9
|
|
|
10
|
-
// lib/pcb/svg-object-fns/create-svg-objects-from-pcb-
|
|
10
|
+
// lib/pcb/svg-object-fns/create-svg-objects-from-pcb-trace-error.ts
|
|
11
11
|
import { applyToPoint } from "transformation-matrix";
|
|
12
|
+
function createSvgObjectsFromPcbTraceError(pcbTraceError, transform, circuitJson, shouldDrawErrors) {
|
|
13
|
+
if (!shouldDrawErrors) return [];
|
|
14
|
+
const { pcb_port_ids } = pcbTraceError;
|
|
15
|
+
const port1 = circuitJson.find(
|
|
16
|
+
(el) => el.type === "pcb_port" && el.pcb_port_id === pcb_port_ids?.[0]
|
|
17
|
+
);
|
|
18
|
+
const port2 = circuitJson.find(
|
|
19
|
+
(el) => el.type === "pcb_port" && el.pcb_port_id === pcb_port_ids?.[1]
|
|
20
|
+
);
|
|
21
|
+
if (!port1 || !port2) return [];
|
|
22
|
+
const screenPort1 = applyToPoint(transform, {
|
|
23
|
+
x: port1.x,
|
|
24
|
+
y: port1.y
|
|
25
|
+
});
|
|
26
|
+
const screenPort2 = applyToPoint(transform, {
|
|
27
|
+
x: port2.x,
|
|
28
|
+
y: port2.y
|
|
29
|
+
});
|
|
30
|
+
const errorCenter = {
|
|
31
|
+
x: (screenPort1.x + screenPort2.x) / 2,
|
|
32
|
+
y: (screenPort1.y + screenPort2.y) / 2
|
|
33
|
+
};
|
|
34
|
+
if (isNaN(screenPort1.x) || isNaN(screenPort1.y) || isNaN(screenPort2.x) || isNaN(screenPort2.y) || isNaN(errorCenter.x) || isNaN(errorCenter.y)) {
|
|
35
|
+
return [];
|
|
36
|
+
}
|
|
37
|
+
const svgObjects = [
|
|
38
|
+
{
|
|
39
|
+
name: "line",
|
|
40
|
+
type: "element",
|
|
41
|
+
attributes: {
|
|
42
|
+
x1: screenPort1.x.toString(),
|
|
43
|
+
y1: screenPort1.y.toString(),
|
|
44
|
+
x2: errorCenter.x.toString(),
|
|
45
|
+
y2: errorCenter.y.toString(),
|
|
46
|
+
stroke: "red",
|
|
47
|
+
"stroke-width": "1.5",
|
|
48
|
+
"stroke-dasharray": "2,2"
|
|
49
|
+
},
|
|
50
|
+
children: [],
|
|
51
|
+
value: ""
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
name: "line",
|
|
55
|
+
type: "element",
|
|
56
|
+
attributes: {
|
|
57
|
+
x1: errorCenter.x.toString(),
|
|
58
|
+
y1: errorCenter.y.toString(),
|
|
59
|
+
x2: screenPort2.x.toString(),
|
|
60
|
+
y2: screenPort2.y.toString(),
|
|
61
|
+
stroke: "red",
|
|
62
|
+
"stroke-width": "1.5",
|
|
63
|
+
"stroke-dasharray": "2,2"
|
|
64
|
+
},
|
|
65
|
+
children: [],
|
|
66
|
+
value: ""
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
name: "rect",
|
|
70
|
+
type: "element",
|
|
71
|
+
attributes: {
|
|
72
|
+
x: (errorCenter.x - 5).toString(),
|
|
73
|
+
y: (errorCenter.y - 5).toString(),
|
|
74
|
+
width: "10",
|
|
75
|
+
height: "10",
|
|
76
|
+
fill: "red",
|
|
77
|
+
transform: `rotate(45 ${errorCenter.x} ${errorCenter.y})`
|
|
78
|
+
},
|
|
79
|
+
children: [],
|
|
80
|
+
value: ""
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
name: "text",
|
|
84
|
+
type: "element",
|
|
85
|
+
attributes: {
|
|
86
|
+
x: errorCenter.x.toString(),
|
|
87
|
+
y: (errorCenter.y - 15).toString(),
|
|
88
|
+
fill: "red",
|
|
89
|
+
"font-family": "sans-serif",
|
|
90
|
+
"font-size": "12",
|
|
91
|
+
"text-anchor": "middle"
|
|
92
|
+
},
|
|
93
|
+
children: [
|
|
94
|
+
{
|
|
95
|
+
type: "text",
|
|
96
|
+
value: pcbTraceError.message || "Pcb Trace Error",
|
|
97
|
+
name: "",
|
|
98
|
+
attributes: {},
|
|
99
|
+
children: []
|
|
100
|
+
}
|
|
101
|
+
],
|
|
102
|
+
value: ""
|
|
103
|
+
}
|
|
104
|
+
];
|
|
105
|
+
return svgObjects;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// lib/pcb/svg-object-fns/create-svg-objects-from-pcb-fabrication-note-path.ts
|
|
109
|
+
import { applyToPoint as applyToPoint2 } from "transformation-matrix";
|
|
12
110
|
function createSvgObjectsFromPcbFabricationNotePath(fabNotePath, transform) {
|
|
13
111
|
if (!fabNotePath.route || !Array.isArray(fabNotePath.route)) return [];
|
|
14
112
|
const firstPoint = fabNotePath.route[0];
|
|
15
113
|
const lastPoint = fabNotePath.route[fabNotePath.route.length - 1];
|
|
16
114
|
const isClosed = firstPoint.x === lastPoint.x && firstPoint.y === lastPoint.y;
|
|
17
115
|
const path = fabNotePath.route.slice(0, isClosed ? -1 : void 0).map((point, index) => {
|
|
18
|
-
const [x, y] =
|
|
116
|
+
const [x, y] = applyToPoint2(transform, [point.x, point.y]);
|
|
19
117
|
return index === 0 ? `M ${x} ${y}` : `L ${x} ${y}`;
|
|
20
118
|
}).join(" ") + (isClosed ? " Z" : "");
|
|
21
119
|
return [
|
|
@@ -40,7 +138,7 @@ function createSvgObjectsFromPcbFabricationNotePath(fabNotePath, transform) {
|
|
|
40
138
|
// lib/pcb/svg-object-fns/create-svg-objects-from-pcb-fabrication-note-text.ts
|
|
41
139
|
import { toString as matrixToString } from "transformation-matrix";
|
|
42
140
|
import {
|
|
43
|
-
applyToPoint as
|
|
141
|
+
applyToPoint as applyToPoint3,
|
|
44
142
|
compose,
|
|
45
143
|
rotate,
|
|
46
144
|
translate
|
|
@@ -58,7 +156,7 @@ function createSvgObjectsFromPcbFabricationNoteText(pcbFabNoteText, transform) {
|
|
|
58
156
|
console.error("Invalid anchor_position:", anchor_position);
|
|
59
157
|
return [];
|
|
60
158
|
}
|
|
61
|
-
const [transformedX, transformedY] =
|
|
159
|
+
const [transformedX, transformedY] = applyToPoint3(transform, [
|
|
62
160
|
anchor_position.x,
|
|
63
161
|
anchor_position.y
|
|
64
162
|
]);
|
|
@@ -98,9 +196,9 @@ function createSvgObjectsFromPcbFabricationNoteText(pcbFabNoteText, transform) {
|
|
|
98
196
|
}
|
|
99
197
|
|
|
100
198
|
// lib/pcb/svg-object-fns/create-svg-objects-from-pcb-plated-hole.ts
|
|
101
|
-
import { applyToPoint as
|
|
199
|
+
import { applyToPoint as applyToPoint4 } from "transformation-matrix";
|
|
102
200
|
function createSvgObjectsFromPcbPlatedHole(hole, transform) {
|
|
103
|
-
const [x, y] =
|
|
201
|
+
const [x, y] = applyToPoint4(transform, [hole.x, hole.y]);
|
|
104
202
|
if (hole.shape === "pill") {
|
|
105
203
|
const scaledOuterWidth = hole.outer_width * Math.abs(transform.a);
|
|
106
204
|
const scaledOuterHeight = hole.outer_height * Math.abs(transform.a);
|
|
@@ -190,11 +288,11 @@ function createSvgObjectsFromPcbPlatedHole(hole, transform) {
|
|
|
190
288
|
}
|
|
191
289
|
|
|
192
290
|
// lib/pcb/svg-object-fns/create-svg-objects-from-pcb-silkscreen-path.ts
|
|
193
|
-
import { applyToPoint as
|
|
291
|
+
import { applyToPoint as applyToPoint5 } from "transformation-matrix";
|
|
194
292
|
function createSvgObjectsFromPcbSilkscreenPath(silkscreenPath, transform) {
|
|
195
293
|
if (!silkscreenPath.route || !Array.isArray(silkscreenPath.route)) return [];
|
|
196
294
|
let path = silkscreenPath.route.map((point, index) => {
|
|
197
|
-
const [x, y] =
|
|
295
|
+
const [x, y] = applyToPoint5(transform, [point.x, point.y]);
|
|
198
296
|
return index === 0 ? `M ${x} ${y}` : `L ${x} ${y}`;
|
|
199
297
|
}).join(" ");
|
|
200
298
|
const firstPoint = silkscreenPath.route[0];
|
|
@@ -221,7 +319,7 @@ function createSvgObjectsFromPcbSilkscreenPath(silkscreenPath, transform) {
|
|
|
221
319
|
|
|
222
320
|
// lib/pcb/svg-object-fns/create-svg-objects-from-pcb-silkscreen-text.ts
|
|
223
321
|
import {
|
|
224
|
-
applyToPoint as
|
|
322
|
+
applyToPoint as applyToPoint6,
|
|
225
323
|
compose as compose2,
|
|
226
324
|
rotate as rotate2,
|
|
227
325
|
translate as translate2,
|
|
@@ -238,7 +336,7 @@ function createSvgObjectsFromPcbSilkscreenText(pcbSilkscreenText, transform) {
|
|
|
238
336
|
console.error("Invalid anchor_position:", anchor_position);
|
|
239
337
|
return [];
|
|
240
338
|
}
|
|
241
|
-
const [transformedX, transformedY] =
|
|
339
|
+
const [transformedX, transformedY] = applyToPoint6(transform, [
|
|
242
340
|
anchor_position.x,
|
|
243
341
|
anchor_position.y
|
|
244
342
|
]);
|
|
@@ -286,7 +384,7 @@ function pairs(arr) {
|
|
|
286
384
|
}
|
|
287
385
|
|
|
288
386
|
// lib/pcb/svg-object-fns/create-svg-objects-from-pcb-trace.ts
|
|
289
|
-
import { applyToPoint as
|
|
387
|
+
import { applyToPoint as applyToPoint7 } from "transformation-matrix";
|
|
290
388
|
|
|
291
389
|
// lib/pcb/layer-name-to-color.ts
|
|
292
390
|
var LAYER_NAME_TO_COLOR = {
|
|
@@ -304,8 +402,8 @@ function createSvgObjectsFromPcbTrace(trace, transform) {
|
|
|
304
402
|
const segments = pairs(trace.route);
|
|
305
403
|
const svgObjects = [];
|
|
306
404
|
for (const [start, end] of segments) {
|
|
307
|
-
const startPoint =
|
|
308
|
-
const endPoint =
|
|
405
|
+
const startPoint = applyToPoint7(transform, [start.x, start.y]);
|
|
406
|
+
const endPoint = applyToPoint7(transform, [end.x, end.y]);
|
|
309
407
|
const layer = "layer" in start ? start.layer : "layer" in end ? end.layer : null;
|
|
310
408
|
if (!layer) continue;
|
|
311
409
|
const layerColor = LAYER_NAME_TO_COLOR[layer] ?? "white";
|
|
@@ -330,9 +428,9 @@ function createSvgObjectsFromPcbTrace(trace, transform) {
|
|
|
330
428
|
}
|
|
331
429
|
|
|
332
430
|
// lib/pcb/svg-object-fns/create-svg-objects-from-smt-pads.ts
|
|
333
|
-
import { applyToPoint as
|
|
431
|
+
import { applyToPoint as applyToPoint8 } from "transformation-matrix";
|
|
334
432
|
function createSvgObjectsFromSmtPad(pad, transform) {
|
|
335
|
-
const [x, y] =
|
|
433
|
+
const [x, y] = applyToPoint8(transform, [pad.x, pad.y]);
|
|
336
434
|
if (pad.shape === "rect") {
|
|
337
435
|
const width = pad.width * Math.abs(transform.a);
|
|
338
436
|
const height = pad.height * Math.abs(transform.d);
|
|
@@ -355,31 +453,31 @@ function createSvgObjectsFromSmtPad(pad, transform) {
|
|
|
355
453
|
}
|
|
356
454
|
|
|
357
455
|
// lib/pcb/svg-object-fns/create-svg-objects-from-pcb-board.ts
|
|
358
|
-
import { applyToPoint as
|
|
456
|
+
import { applyToPoint as applyToPoint9 } from "transformation-matrix";
|
|
359
457
|
function createSvgObjectsFromPcbBoard(pcbBoard, transform) {
|
|
360
458
|
const { width, height, center, outline } = pcbBoard;
|
|
361
459
|
let path;
|
|
362
460
|
if (outline && Array.isArray(outline) && outline.length >= 3) {
|
|
363
461
|
path = outline.map((point, index) => {
|
|
364
|
-
const [x, y] =
|
|
462
|
+
const [x, y] = applyToPoint9(transform, [point.x, point.y]);
|
|
365
463
|
return index === 0 ? `M ${x} ${y}` : `L ${x} ${y}`;
|
|
366
464
|
}).join(" ");
|
|
367
465
|
} else {
|
|
368
466
|
const halfWidth = width / 2;
|
|
369
467
|
const halfHeight = height / 2;
|
|
370
|
-
const topLeft =
|
|
468
|
+
const topLeft = applyToPoint9(transform, [
|
|
371
469
|
center.x - halfWidth,
|
|
372
470
|
center.y - halfHeight
|
|
373
471
|
]);
|
|
374
|
-
const topRight =
|
|
472
|
+
const topRight = applyToPoint9(transform, [
|
|
375
473
|
center.x + halfWidth,
|
|
376
474
|
center.y - halfHeight
|
|
377
475
|
]);
|
|
378
|
-
const bottomRight =
|
|
476
|
+
const bottomRight = applyToPoint9(transform, [
|
|
379
477
|
center.x + halfWidth,
|
|
380
478
|
center.y + halfHeight
|
|
381
479
|
]);
|
|
382
|
-
const bottomLeft =
|
|
480
|
+
const bottomLeft = applyToPoint9(transform, [
|
|
383
481
|
center.x - halfWidth,
|
|
384
482
|
center.y + halfHeight
|
|
385
483
|
]);
|
|
@@ -403,9 +501,9 @@ function createSvgObjectsFromPcbBoard(pcbBoard, transform) {
|
|
|
403
501
|
}
|
|
404
502
|
|
|
405
503
|
// lib/pcb/svg-object-fns/create-svg-objects-from-pcb-via.ts
|
|
406
|
-
import { applyToPoint as
|
|
504
|
+
import { applyToPoint as applyToPoint10 } from "transformation-matrix";
|
|
407
505
|
function createSvgObjectsFromPcbVia(hole, transform) {
|
|
408
|
-
const [x, y] =
|
|
506
|
+
const [x, y] = applyToPoint10(transform, [hole.x, hole.y]);
|
|
409
507
|
const scaledOuterWidth = hole.outer_diameter * Math.abs(transform.a);
|
|
410
508
|
const scaledOuterHeight = hole.outer_diameter * Math.abs(transform.a);
|
|
411
509
|
const scaledHoleWidth = hole.hole_diameter * Math.abs(transform.a);
|
|
@@ -441,14 +539,14 @@ function createSvgObjectsFromPcbVia(hole, transform) {
|
|
|
441
539
|
}
|
|
442
540
|
|
|
443
541
|
// lib/pcb/svg-object-fns/create-svg-objects-from-pcb-hole.ts
|
|
444
|
-
import { applyToPoint as
|
|
542
|
+
import { applyToPoint as applyToPoint11 } from "transformation-matrix";
|
|
445
543
|
|
|
446
544
|
// lib/pcb/colors.ts
|
|
447
545
|
var HOLE_COLOR = "#FF26E2";
|
|
448
546
|
|
|
449
547
|
// lib/pcb/svg-object-fns/create-svg-objects-from-pcb-hole.ts
|
|
450
548
|
function createSvgObjectsFromPcbHole(hole, transform) {
|
|
451
|
-
const [x, y] =
|
|
549
|
+
const [x, y] = applyToPoint11(transform, [hole.x, hole.y]);
|
|
452
550
|
if (hole.hole_shape === "circle" || hole.hole_shape === "square") {
|
|
453
551
|
const scaledDiameter = hole.hole_diameter * Math.abs(transform.a);
|
|
454
552
|
const radius = scaledDiameter / 2;
|
|
@@ -513,6 +611,7 @@ function createSvgObjectsFromPcbHole(hole, transform) {
|
|
|
513
611
|
|
|
514
612
|
// lib/pcb/convert-circuit-json-to-pcb-svg.ts
|
|
515
613
|
var OBJECT_ORDER = [
|
|
614
|
+
"pcb_trace_error",
|
|
516
615
|
"pcb_plated_hole",
|
|
517
616
|
"pcb_fabrication_note_text",
|
|
518
617
|
"pcb_fabrication_note_path",
|
|
@@ -567,7 +666,9 @@ function convertCircuitJsonToPcbSvg(soup, options) {
|
|
|
567
666
|
);
|
|
568
667
|
const svgObjects = soup.sort(
|
|
569
668
|
(a, b) => (OBJECT_ORDER.indexOf(b.type) ?? 9999) - (OBJECT_ORDER.indexOf(a.type) ?? 9999)
|
|
570
|
-
).flatMap(
|
|
669
|
+
).flatMap(
|
|
670
|
+
(item) => createSvgObjects(item, transform, soup, options?.shouldDrawErrors)
|
|
671
|
+
);
|
|
571
672
|
let strokeWidth = String(0.05 * scaleFactor);
|
|
572
673
|
for (const element of soup) {
|
|
573
674
|
if ("stroke_width" in element) {
|
|
@@ -653,8 +754,15 @@ function convertCircuitJsonToPcbSvg(soup, options) {
|
|
|
653
754
|
}
|
|
654
755
|
}
|
|
655
756
|
}
|
|
656
|
-
function createSvgObjects(elm, transform) {
|
|
757
|
+
function createSvgObjects(elm, transform, soup, shouldDrawErrors) {
|
|
657
758
|
switch (elm.type) {
|
|
759
|
+
case "pcb_trace_error":
|
|
760
|
+
return createSvgObjectsFromPcbTraceError(
|
|
761
|
+
elm,
|
|
762
|
+
transform,
|
|
763
|
+
soup,
|
|
764
|
+
shouldDrawErrors
|
|
765
|
+
).filter(Boolean);
|
|
658
766
|
case "pcb_component":
|
|
659
767
|
return [createSvgObjectsFromPcbComponent(elm, transform)].filter(Boolean);
|
|
660
768
|
case "pcb_trace":
|
|
@@ -683,7 +791,7 @@ function createSvgObjects(elm, transform) {
|
|
|
683
791
|
}
|
|
684
792
|
function createSvgObjectsFromPcbComponent(component, transform) {
|
|
685
793
|
const { center, width, height, rotation = 0 } = component;
|
|
686
|
-
const [x, y] =
|
|
794
|
+
const [x, y] = applyToPoint12(transform, [center.x, center.y]);
|
|
687
795
|
const scaledWidth = width * Math.abs(transform.a);
|
|
688
796
|
const scaledHeight = height * Math.abs(transform.d);
|
|
689
797
|
const transformStr = `translate(${x}, ${y}) rotate(${-rotation}) scale(1, -1)`;
|
|
@@ -718,8 +826,8 @@ function createSvgObjectsFromPcbComponent(component, transform) {
|
|
|
718
826
|
};
|
|
719
827
|
}
|
|
720
828
|
function createSvgObjectFromPcbBoundary(transform, minX, minY, maxX, maxY) {
|
|
721
|
-
const [x1, y1] =
|
|
722
|
-
const [x2, y2] =
|
|
829
|
+
const [x1, y1] = applyToPoint12(transform, [minX, minY]);
|
|
830
|
+
const [x2, y2] = applyToPoint12(transform, [maxX, maxY]);
|
|
723
831
|
const width = Math.abs(x2 - x1);
|
|
724
832
|
const height = Math.abs(y2 - y1);
|
|
725
833
|
const x = Math.min(x1, x2);
|
|
@@ -984,14 +1092,14 @@ import {
|
|
|
984
1092
|
} from "transformation-matrix";
|
|
985
1093
|
|
|
986
1094
|
// lib/sch/draw-schematic-grid.ts
|
|
987
|
-
import { applyToPoint as
|
|
1095
|
+
import { applyToPoint as applyToPoint13 } from "transformation-matrix";
|
|
988
1096
|
function drawSchematicGrid(params) {
|
|
989
1097
|
const { minX, minY, maxX, maxY } = params.bounds;
|
|
990
1098
|
const cellSize = params.cellSize ?? 1;
|
|
991
1099
|
const labelCells = params.labelCells ?? false;
|
|
992
1100
|
const gridLines = [];
|
|
993
1101
|
const transformPoint = (x, y) => {
|
|
994
|
-
const [transformedX, transformedY] =
|
|
1102
|
+
const [transformedX, transformedY] = applyToPoint13(params.transform, [x, y]);
|
|
995
1103
|
return { x: transformedX, y: transformedY };
|
|
996
1104
|
};
|
|
997
1105
|
for (let x = Math.ceil(minX); x <= Math.floor(maxX); x += cellSize) {
|
|
@@ -1068,15 +1176,15 @@ function drawSchematicGrid(params) {
|
|
|
1068
1176
|
}
|
|
1069
1177
|
|
|
1070
1178
|
// lib/sch/draw-schematic-labeled-points.ts
|
|
1071
|
-
import { applyToPoint as
|
|
1179
|
+
import { applyToPoint as applyToPoint14 } from "transformation-matrix";
|
|
1072
1180
|
function drawSchematicLabeledPoints(params) {
|
|
1073
1181
|
const { points, transform } = params;
|
|
1074
1182
|
const labeledPointsGroup = [];
|
|
1075
1183
|
for (const point of points) {
|
|
1076
|
-
const [x1, y1] =
|
|
1077
|
-
const [x2, y2] =
|
|
1078
|
-
const [x3, y3] =
|
|
1079
|
-
const [x4, y4] =
|
|
1184
|
+
const [x1, y1] = applyToPoint14(transform, [point.x - 0.1, point.y - 0.1]);
|
|
1185
|
+
const [x2, y2] = applyToPoint14(transform, [point.x + 0.1, point.y + 0.1]);
|
|
1186
|
+
const [x3, y3] = applyToPoint14(transform, [point.x - 0.1, point.y + 0.1]);
|
|
1187
|
+
const [x4, y4] = applyToPoint14(transform, [point.x + 0.1, point.y - 0.1]);
|
|
1080
1188
|
labeledPointsGroup.push({
|
|
1081
1189
|
name: "path",
|
|
1082
1190
|
type: "element",
|
|
@@ -1087,7 +1195,7 @@ function drawSchematicLabeledPoints(params) {
|
|
|
1087
1195
|
"stroke-opacity": "0.7"
|
|
1088
1196
|
}
|
|
1089
1197
|
});
|
|
1090
|
-
const [labelX, labelY] =
|
|
1198
|
+
const [labelX, labelY] = applyToPoint14(transform, [
|
|
1091
1199
|
point.x + 0.15,
|
|
1092
1200
|
point.y - 0.15
|
|
1093
1201
|
]);
|
|
@@ -1175,7 +1283,7 @@ import { su } from "@tscircuit/soup-util";
|
|
|
1175
1283
|
import { symbols } from "schematic-symbols";
|
|
1176
1284
|
import "svgson";
|
|
1177
1285
|
import {
|
|
1178
|
-
applyToPoint as
|
|
1286
|
+
applyToPoint as applyToPoint16,
|
|
1179
1287
|
compose as compose5
|
|
1180
1288
|
} from "transformation-matrix";
|
|
1181
1289
|
|
|
@@ -1260,8 +1368,11 @@ function pointPairsToMatrix(a1, a2, b1, b2) {
|
|
|
1260
1368
|
|
|
1261
1369
|
// lib/utils/get-sch-font-size.ts
|
|
1262
1370
|
import "transformation-matrix";
|
|
1263
|
-
var
|
|
1264
|
-
return
|
|
1371
|
+
var getSchMmFontSize = (textType) => {
|
|
1372
|
+
return textType === "pin_number" ? 0.15 : 0.18;
|
|
1373
|
+
};
|
|
1374
|
+
var getSchScreenFontSize = (transform, textType) => {
|
|
1375
|
+
return Math.abs(transform.a) * getSchMmFontSize(textType);
|
|
1265
1376
|
};
|
|
1266
1377
|
|
|
1267
1378
|
// lib/sch/svg-object-fns/create-svg-objects-from-sch-component-with-symbol.ts
|
|
@@ -1324,7 +1435,7 @@ var createSvgObjectsFromSchematicComponentWithSymbol = ({
|
|
|
1324
1435
|
name: "path",
|
|
1325
1436
|
attributes: {
|
|
1326
1437
|
d: points.map((p, i) => {
|
|
1327
|
-
const [x, y] =
|
|
1438
|
+
const [x, y] = applyToPoint16(
|
|
1328
1439
|
compose5(realToScreenTransform, transformFromSymbolToReal),
|
|
1329
1440
|
[p.x, p.y]
|
|
1330
1441
|
);
|
|
@@ -1339,7 +1450,7 @@ var createSvgObjectsFromSchematicComponentWithSymbol = ({
|
|
|
1339
1450
|
});
|
|
1340
1451
|
}
|
|
1341
1452
|
for (const text of texts) {
|
|
1342
|
-
const screenTextPos =
|
|
1453
|
+
const screenTextPos = applyToPoint16(
|
|
1343
1454
|
compose5(realToScreenTransform, transformFromSymbolToReal),
|
|
1344
1455
|
text
|
|
1345
1456
|
);
|
|
@@ -1358,7 +1469,7 @@ var createSvgObjectsFromSchematicComponentWithSymbol = ({
|
|
|
1358
1469
|
"dominant-baseline": ninePointAnchorToDominantBaseline[text.anchor],
|
|
1359
1470
|
"text-anchor": ninePointAnchorToTextAnchor[text.anchor],
|
|
1360
1471
|
"font-family": "sans-serif",
|
|
1361
|
-
"font-size": `${
|
|
1472
|
+
"font-size": `${getSchScreenFontSize(realToScreenTransform, "reference_designator")}px`
|
|
1362
1473
|
},
|
|
1363
1474
|
value: "",
|
|
1364
1475
|
children: [
|
|
@@ -1373,7 +1484,7 @@ var createSvgObjectsFromSchematicComponentWithSymbol = ({
|
|
|
1373
1484
|
});
|
|
1374
1485
|
}
|
|
1375
1486
|
for (const box of boxes) {
|
|
1376
|
-
const screenBoxPos =
|
|
1487
|
+
const screenBoxPos = applyToPoint16(
|
|
1377
1488
|
compose5(realToScreenTransform, transformFromSymbolToReal),
|
|
1378
1489
|
box
|
|
1379
1490
|
);
|
|
@@ -1396,7 +1507,7 @@ var createSvgObjectsFromSchematicComponentWithSymbol = ({
|
|
|
1396
1507
|
});
|
|
1397
1508
|
}
|
|
1398
1509
|
for (const port of symbol.ports) {
|
|
1399
|
-
const screenPortPos =
|
|
1510
|
+
const screenPortPos = applyToPoint16(
|
|
1400
1511
|
compose5(realToScreenTransform, transformFromSymbolToReal),
|
|
1401
1512
|
port
|
|
1402
1513
|
);
|
|
@@ -1421,14 +1532,14 @@ var createSvgObjectsFromSchematicComponentWithSymbol = ({
|
|
|
1421
1532
|
import { su as su4 } from "@tscircuit/soup-util";
|
|
1422
1533
|
import "schematic-symbols";
|
|
1423
1534
|
import "svgson";
|
|
1424
|
-
import { applyToPoint as
|
|
1535
|
+
import { applyToPoint as applyToPoint21 } from "transformation-matrix";
|
|
1425
1536
|
|
|
1426
1537
|
// lib/sch/svg-object-fns/create-svg-objects-from-sch-port-on-box.ts
|
|
1427
1538
|
import "transformation-matrix";
|
|
1428
1539
|
import "@tscircuit/soup-util";
|
|
1429
1540
|
|
|
1430
1541
|
// lib/sch/svg-object-fns/create-svg-objects-for-sch-port-box-line.ts
|
|
1431
|
-
import { applyToPoint as
|
|
1542
|
+
import { applyToPoint as applyToPoint17 } from "transformation-matrix";
|
|
1432
1543
|
import { su as su2 } from "@tscircuit/soup-util";
|
|
1433
1544
|
var PIN_CIRCLE_RADIUS_MM = 0.02;
|
|
1434
1545
|
var createSvgObjectsForSchPortBoxLine = ({
|
|
@@ -1458,8 +1569,8 @@ var createSvgObjectsForSchPortBoxLine = ({
|
|
|
1458
1569
|
realEdgePos.y += realPinLineLength;
|
|
1459
1570
|
break;
|
|
1460
1571
|
}
|
|
1461
|
-
const screenSchPortPos =
|
|
1462
|
-
const screenRealEdgePos =
|
|
1572
|
+
const screenSchPortPos = applyToPoint17(transform, schPort.center);
|
|
1573
|
+
const screenRealEdgePos = applyToPoint17(transform, realEdgePos);
|
|
1463
1574
|
const realLineEnd = { ...schPort.center };
|
|
1464
1575
|
switch (schPort.side_of_component) {
|
|
1465
1576
|
case "left":
|
|
@@ -1475,7 +1586,7 @@ var createSvgObjectsForSchPortBoxLine = ({
|
|
|
1475
1586
|
realLineEnd.y += PIN_CIRCLE_RADIUS_MM;
|
|
1476
1587
|
break;
|
|
1477
1588
|
}
|
|
1478
|
-
const screenLineEnd =
|
|
1589
|
+
const screenLineEnd = applyToPoint17(transform, realLineEnd);
|
|
1479
1590
|
svgObjects.push({
|
|
1480
1591
|
name: "line",
|
|
1481
1592
|
type: "element",
|
|
@@ -1522,7 +1633,7 @@ var getUnitVectorFromOutsideToEdge = (side) => {
|
|
|
1522
1633
|
};
|
|
1523
1634
|
|
|
1524
1635
|
// lib/sch/svg-object-fns/create-svg-objects-for-sch-port-pin-number-text.ts
|
|
1525
|
-
import { applyToPoint as
|
|
1636
|
+
import { applyToPoint as applyToPoint18 } from "transformation-matrix";
|
|
1526
1637
|
var createSvgObjectsForSchPortPinNumberText = (params) => {
|
|
1527
1638
|
const svgObjects = [];
|
|
1528
1639
|
const { schPort, schComponent, transform, circuitJson } = params;
|
|
@@ -1535,7 +1646,7 @@ var createSvgObjectsForSchPortPinNumberText = (params) => {
|
|
|
1535
1646
|
const realPinEdgeDistance = schPort.distance_from_component_edge ?? 0.4;
|
|
1536
1647
|
realPinNumberPos.x += vecToEdge.x * realPinEdgeDistance / 2;
|
|
1537
1648
|
realPinNumberPos.y += vecToEdge.y * realPinEdgeDistance / 2;
|
|
1538
|
-
const screenPinNumberTextPos =
|
|
1649
|
+
const screenPinNumberTextPos = applyToPoint18(transform, realPinNumberPos);
|
|
1539
1650
|
if (schPort.side_of_component === "top" || schPort.side_of_component === "bottom") {
|
|
1540
1651
|
screenPinNumberTextPos.x -= 2;
|
|
1541
1652
|
} else {
|
|
@@ -1552,7 +1663,7 @@ var createSvgObjectsForSchPortPinNumberText = (params) => {
|
|
|
1552
1663
|
fill: colorMap.schematic.pin_number,
|
|
1553
1664
|
"text-anchor": "middle",
|
|
1554
1665
|
"dominant-baseline": "auto",
|
|
1555
|
-
"font-size": `${
|
|
1666
|
+
"font-size": `${getSchScreenFontSize(transform, "pin_number")}px`,
|
|
1556
1667
|
transform: schPort.side_of_component === "top" || schPort.side_of_component === "bottom" ? `rotate(-90 ${screenPinNumberTextPos.x} ${screenPinNumberTextPos.y})` : ""
|
|
1557
1668
|
},
|
|
1558
1669
|
children: [
|
|
@@ -1570,7 +1681,7 @@ var createSvgObjectsForSchPortPinNumberText = (params) => {
|
|
|
1570
1681
|
};
|
|
1571
1682
|
|
|
1572
1683
|
// lib/sch/svg-object-fns/create-svg-objects-for-sch-port-pin-label.ts
|
|
1573
|
-
import { applyToPoint as
|
|
1684
|
+
import { applyToPoint as applyToPoint19 } from "transformation-matrix";
|
|
1574
1685
|
var LABEL_DIST_FROM_EDGE_MM = 0.1;
|
|
1575
1686
|
var createSvgObjectsForSchPortPinLabel = (params) => {
|
|
1576
1687
|
const svgObjects = [];
|
|
@@ -1584,7 +1695,7 @@ var createSvgObjectsForSchPortPinLabel = (params) => {
|
|
|
1584
1695
|
const realPinEdgeDistance = schPort.distance_from_component_edge ?? 0.4;
|
|
1585
1696
|
realPinNumberPos.x += vecToEdge.x * (realPinEdgeDistance + LABEL_DIST_FROM_EDGE_MM);
|
|
1586
1697
|
realPinNumberPos.y += vecToEdge.y * (realPinEdgeDistance + LABEL_DIST_FROM_EDGE_MM);
|
|
1587
|
-
const screenPinNumberTextPos =
|
|
1698
|
+
const screenPinNumberTextPos = applyToPoint19(transform, realPinNumberPos);
|
|
1588
1699
|
const label = schPort.display_pin_label ?? schComponent.port_labels?.[`pin${schPort.pin_number}`];
|
|
1589
1700
|
if (!label) return [];
|
|
1590
1701
|
svgObjects.push({
|
|
@@ -1598,7 +1709,7 @@ var createSvgObjectsForSchPortPinLabel = (params) => {
|
|
|
1598
1709
|
fill: colorMap.schematic.pin_number,
|
|
1599
1710
|
"text-anchor": schPort.side_of_component === "left" || schPort.side_of_component === "bottom" ? "start" : "end",
|
|
1600
1711
|
"dominant-baseline": "middle",
|
|
1601
|
-
"font-size": `${
|
|
1712
|
+
"font-size": `${getSchScreenFontSize(transform, "pin_number")}px`,
|
|
1602
1713
|
transform: schPort.side_of_component === "top" || schPort.side_of_component === "bottom" ? `rotate(-90 ${screenPinNumberTextPos.x} ${screenPinNumberTextPos.y})` : ""
|
|
1603
1714
|
},
|
|
1604
1715
|
children: [
|
|
@@ -1635,11 +1746,11 @@ var createSvgObjectsFromSchematicComponentWithBox = ({
|
|
|
1635
1746
|
schComponent.source_component_id
|
|
1636
1747
|
);
|
|
1637
1748
|
const svgObjects = [];
|
|
1638
|
-
const componentScreenTopLeft =
|
|
1749
|
+
const componentScreenTopLeft = applyToPoint21(transform, {
|
|
1639
1750
|
x: schComponent.center.x - schComponent.size.width / 2,
|
|
1640
1751
|
y: schComponent.center.y + schComponent.size.height / 2
|
|
1641
1752
|
});
|
|
1642
|
-
const componentScreenBottomRight =
|
|
1753
|
+
const componentScreenBottomRight = applyToPoint21(transform, {
|
|
1643
1754
|
x: schComponent.center.x + schComponent.size.width / 2,
|
|
1644
1755
|
y: schComponent.center.y - schComponent.size.height / 2
|
|
1645
1756
|
});
|
|
@@ -1659,12 +1770,12 @@ var createSvgObjectsFromSchematicComponentWithBox = ({
|
|
|
1659
1770
|
},
|
|
1660
1771
|
children: []
|
|
1661
1772
|
});
|
|
1662
|
-
const screenManufacturerNumberPos =
|
|
1773
|
+
const screenManufacturerNumberPos = applyToPoint21(transform, {
|
|
1663
1774
|
x: schComponent.center.x + schComponent.size.width / 2,
|
|
1664
1775
|
y: schComponent.center.y + schComponent.size.height / 2 + 0.5
|
|
1665
1776
|
// Above the component top edge
|
|
1666
1777
|
});
|
|
1667
|
-
const fontSizePx =
|
|
1778
|
+
const fontSizePx = getSchScreenFontSize(transform, "manufacturer_number");
|
|
1668
1779
|
if (srcComponent?.manufacturer_part_number) {
|
|
1669
1780
|
svgObjects.push({
|
|
1670
1781
|
name: "text",
|
|
@@ -1743,14 +1854,14 @@ function createSvgObjectsFromSchematicComponent(params) {
|
|
|
1743
1854
|
}
|
|
1744
1855
|
|
|
1745
1856
|
// lib/sch/svg-object-fns/create-svg-objects-from-sch-debug-object.ts
|
|
1746
|
-
import { applyToPoint as
|
|
1857
|
+
import { applyToPoint as applyToPoint22 } from "transformation-matrix";
|
|
1747
1858
|
function createSvgObjectsFromSchDebugObject(debugObject, transform) {
|
|
1748
1859
|
if (debugObject.shape === "rect") {
|
|
1749
|
-
let [screenLeft, screenTop] =
|
|
1860
|
+
let [screenLeft, screenTop] = applyToPoint22(transform, [
|
|
1750
1861
|
debugObject.center.x - debugObject.size.width / 2,
|
|
1751
1862
|
debugObject.center.y - debugObject.size.height / 2
|
|
1752
1863
|
]);
|
|
1753
|
-
let [screenRight, screenBottom] =
|
|
1864
|
+
let [screenRight, screenBottom] = applyToPoint22(transform, [
|
|
1754
1865
|
debugObject.center.x + debugObject.size.width / 2,
|
|
1755
1866
|
debugObject.center.y + debugObject.size.height / 2
|
|
1756
1867
|
]);
|
|
@@ -1760,7 +1871,7 @@ function createSvgObjectsFromSchDebugObject(debugObject, transform) {
|
|
|
1760
1871
|
];
|
|
1761
1872
|
const width = Math.abs(screenRight - screenLeft);
|
|
1762
1873
|
const height = Math.abs(screenBottom - screenTop);
|
|
1763
|
-
const [screenCenterX, screenCenterY] =
|
|
1874
|
+
const [screenCenterX, screenCenterY] = applyToPoint22(transform, [
|
|
1764
1875
|
debugObject.center.x,
|
|
1765
1876
|
debugObject.center.y
|
|
1766
1877
|
]);
|
|
@@ -1806,11 +1917,11 @@ function createSvgObjectsFromSchDebugObject(debugObject, transform) {
|
|
|
1806
1917
|
];
|
|
1807
1918
|
}
|
|
1808
1919
|
if (debugObject.shape === "line") {
|
|
1809
|
-
const [screenStartX, screenStartY] =
|
|
1920
|
+
const [screenStartX, screenStartY] = applyToPoint22(transform, [
|
|
1810
1921
|
debugObject.start.x,
|
|
1811
1922
|
debugObject.start.y
|
|
1812
1923
|
]);
|
|
1813
|
-
const [screenEndX, screenEndY] =
|
|
1924
|
+
const [screenEndX, screenEndY] = applyToPoint22(transform, [
|
|
1814
1925
|
debugObject.end.x,
|
|
1815
1926
|
debugObject.end.y
|
|
1816
1927
|
]);
|
|
@@ -1860,7 +1971,7 @@ function createSvgObjectsFromSchDebugObject(debugObject, transform) {
|
|
|
1860
1971
|
}
|
|
1861
1972
|
|
|
1862
1973
|
// lib/sch/svg-object-fns/create-svg-objects-from-sch-trace.ts
|
|
1863
|
-
import { applyToPoint as
|
|
1974
|
+
import { applyToPoint as applyToPoint23 } from "transformation-matrix";
|
|
1864
1975
|
function createSchematicTrace(trace, transform) {
|
|
1865
1976
|
const edges = trace.edges;
|
|
1866
1977
|
if (edges.length === 0) return [];
|
|
@@ -1869,11 +1980,11 @@ function createSchematicTrace(trace, transform) {
|
|
|
1869
1980
|
for (let edgeIndex = 0; edgeIndex < edges.length; edgeIndex++) {
|
|
1870
1981
|
const edge = edges[edgeIndex];
|
|
1871
1982
|
if (edge.is_crossing) continue;
|
|
1872
|
-
const [screenFromX, screenFromY] =
|
|
1983
|
+
const [screenFromX, screenFromY] = applyToPoint23(transform, [
|
|
1873
1984
|
edge.from.x,
|
|
1874
1985
|
edge.from.y
|
|
1875
1986
|
]);
|
|
1876
|
-
const [screenToX, screenToY] =
|
|
1987
|
+
const [screenToX, screenToY] = applyToPoint23(transform, [
|
|
1877
1988
|
edge.to.x,
|
|
1878
1989
|
edge.to.y
|
|
1879
1990
|
]);
|
|
@@ -1885,11 +1996,11 @@ function createSchematicTrace(trace, transform) {
|
|
|
1885
1996
|
}
|
|
1886
1997
|
for (const edge of edges) {
|
|
1887
1998
|
if (!edge.is_crossing) continue;
|
|
1888
|
-
const [screenFromX, screenFromY] =
|
|
1999
|
+
const [screenFromX, screenFromY] = applyToPoint23(transform, [
|
|
1889
2000
|
edge.from.x,
|
|
1890
2001
|
edge.from.y
|
|
1891
2002
|
]);
|
|
1892
|
-
const [screenToX, screenToY] =
|
|
2003
|
+
const [screenToX, screenToY] = applyToPoint23(transform, [
|
|
1893
2004
|
edge.to.x,
|
|
1894
2005
|
edge.to.y
|
|
1895
2006
|
]);
|
|
@@ -1948,7 +2059,7 @@ function createSchematicTrace(trace, transform) {
|
|
|
1948
2059
|
}
|
|
1949
2060
|
if (trace.junctions) {
|
|
1950
2061
|
for (const junction of trace.junctions) {
|
|
1951
|
-
const [screenX, screenY] =
|
|
2062
|
+
const [screenX, screenY] = applyToPoint23(transform, [
|
|
1952
2063
|
junction.x,
|
|
1953
2064
|
junction.y
|
|
1954
2065
|
]);
|
|
@@ -1970,62 +2081,867 @@ function createSchematicTrace(trace, transform) {
|
|
|
1970
2081
|
}
|
|
1971
2082
|
|
|
1972
2083
|
// lib/sch/svg-object-fns/create-svg-objects-for-sch-net-label.ts
|
|
1973
|
-
import {
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
|
|
1981
|
-
|
|
1982
|
-
|
|
1983
|
-
|
|
1984
|
-
|
|
1985
|
-
|
|
1986
|
-
|
|
1987
|
-
|
|
1988
|
-
|
|
1989
|
-
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
|
|
2084
|
+
import {
|
|
2085
|
+
applyToPoint as applyToPoint24,
|
|
2086
|
+
compose as compose6,
|
|
2087
|
+
rotate as rotate3,
|
|
2088
|
+
scale as scale3,
|
|
2089
|
+
translate as translate6
|
|
2090
|
+
} from "transformation-matrix";
|
|
2091
|
+
|
|
2092
|
+
// lib/sch/arial-text-metrics.ts
|
|
2093
|
+
var arialTextMetrics = {
|
|
2094
|
+
"0": {
|
|
2095
|
+
width: 13,
|
|
2096
|
+
height: 27,
|
|
2097
|
+
ascent: 22,
|
|
2098
|
+
descent: 5,
|
|
2099
|
+
left: -1,
|
|
2100
|
+
right: 12
|
|
2101
|
+
},
|
|
2102
|
+
"1": {
|
|
2103
|
+
width: 13,
|
|
2104
|
+
height: 27,
|
|
2105
|
+
ascent: 22,
|
|
2106
|
+
descent: 5,
|
|
2107
|
+
left: -3,
|
|
2108
|
+
right: 9
|
|
2109
|
+
},
|
|
2110
|
+
"2": {
|
|
2111
|
+
width: 13,
|
|
2112
|
+
height: 27,
|
|
2113
|
+
ascent: 22,
|
|
2114
|
+
descent: 5,
|
|
2115
|
+
left: -1,
|
|
2116
|
+
right: 12
|
|
2117
|
+
},
|
|
2118
|
+
"3": {
|
|
2119
|
+
width: 13,
|
|
2120
|
+
height: 27,
|
|
2121
|
+
ascent: 22,
|
|
2122
|
+
descent: 5,
|
|
2123
|
+
left: -1,
|
|
2124
|
+
right: 12
|
|
2125
|
+
},
|
|
2126
|
+
"4": {
|
|
2127
|
+
width: 13,
|
|
2128
|
+
height: 27,
|
|
2129
|
+
ascent: 22,
|
|
2130
|
+
descent: 5,
|
|
2131
|
+
left: 0,
|
|
2132
|
+
right: 12
|
|
2133
|
+
},
|
|
2134
|
+
"5": {
|
|
2135
|
+
width: 13,
|
|
2136
|
+
height: 27,
|
|
2137
|
+
ascent: 22,
|
|
2138
|
+
descent: 5,
|
|
2139
|
+
left: -1,
|
|
2140
|
+
right: 12
|
|
2141
|
+
},
|
|
2142
|
+
"6": {
|
|
2143
|
+
width: 13,
|
|
2144
|
+
height: 27,
|
|
2145
|
+
ascent: 22,
|
|
2146
|
+
descent: 5,
|
|
2147
|
+
left: -1,
|
|
2148
|
+
right: 12
|
|
2149
|
+
},
|
|
2150
|
+
"7": {
|
|
2151
|
+
width: 13,
|
|
2152
|
+
height: 27,
|
|
2153
|
+
ascent: 22,
|
|
2154
|
+
descent: 5,
|
|
2155
|
+
left: -1,
|
|
2156
|
+
right: 12
|
|
2157
|
+
},
|
|
2158
|
+
"8": {
|
|
2159
|
+
width: 13,
|
|
2160
|
+
height: 27,
|
|
2161
|
+
ascent: 22,
|
|
2162
|
+
descent: 5,
|
|
2163
|
+
left: -1,
|
|
2164
|
+
right: 12
|
|
2165
|
+
},
|
|
2166
|
+
"9": {
|
|
2167
|
+
width: 13,
|
|
2168
|
+
height: 27,
|
|
2169
|
+
ascent: 22,
|
|
2170
|
+
descent: 5,
|
|
2171
|
+
left: -1,
|
|
2172
|
+
right: 12
|
|
2173
|
+
},
|
|
2174
|
+
" ": {
|
|
2175
|
+
width: 7,
|
|
2176
|
+
height: 27,
|
|
2177
|
+
ascent: 22,
|
|
2178
|
+
descent: 5,
|
|
2179
|
+
left: 0,
|
|
2180
|
+
right: 0
|
|
2181
|
+
},
|
|
2182
|
+
"!": {
|
|
2183
|
+
width: 7,
|
|
2184
|
+
height: 27,
|
|
2185
|
+
ascent: 22,
|
|
2186
|
+
descent: 5,
|
|
2187
|
+
left: -2,
|
|
2188
|
+
right: 5
|
|
2189
|
+
},
|
|
2190
|
+
'"': {
|
|
2191
|
+
width: 9,
|
|
2192
|
+
height: 27,
|
|
2193
|
+
ascent: 22,
|
|
2194
|
+
descent: 5,
|
|
2195
|
+
left: -1,
|
|
2196
|
+
right: 7
|
|
2197
|
+
},
|
|
2198
|
+
"#": {
|
|
2199
|
+
width: 13,
|
|
2200
|
+
height: 27,
|
|
2201
|
+
ascent: 22,
|
|
2202
|
+
descent: 5,
|
|
2203
|
+
left: 0,
|
|
2204
|
+
right: 13
|
|
2205
|
+
},
|
|
2206
|
+
$: {
|
|
2207
|
+
width: 13,
|
|
2208
|
+
height: 27,
|
|
2209
|
+
ascent: 22,
|
|
2210
|
+
descent: 5,
|
|
2211
|
+
left: -1,
|
|
2212
|
+
right: 12
|
|
2213
|
+
},
|
|
2214
|
+
"%": {
|
|
2215
|
+
width: 21,
|
|
2216
|
+
height: 27,
|
|
2217
|
+
ascent: 22,
|
|
2218
|
+
descent: 5,
|
|
2219
|
+
left: -1,
|
|
2220
|
+
right: 20
|
|
2221
|
+
},
|
|
2222
|
+
"&": {
|
|
2223
|
+
width: 16,
|
|
2224
|
+
height: 27,
|
|
2225
|
+
ascent: 22,
|
|
2226
|
+
descent: 5,
|
|
2227
|
+
left: -1,
|
|
2228
|
+
right: 15
|
|
2229
|
+
},
|
|
2230
|
+
"'": {
|
|
2231
|
+
width: 5,
|
|
2232
|
+
height: 27,
|
|
2233
|
+
ascent: 22,
|
|
2234
|
+
descent: 5,
|
|
2235
|
+
left: -1,
|
|
2236
|
+
right: 3
|
|
2237
|
+
},
|
|
2238
|
+
"(": {
|
|
2239
|
+
width: 8,
|
|
2240
|
+
height: 27,
|
|
2241
|
+
ascent: 22,
|
|
2242
|
+
descent: 5,
|
|
2243
|
+
left: -1,
|
|
2244
|
+
right: 7
|
|
2245
|
+
},
|
|
2246
|
+
")": {
|
|
2247
|
+
width: 8,
|
|
2248
|
+
height: 27,
|
|
2249
|
+
ascent: 22,
|
|
2250
|
+
descent: 5,
|
|
2251
|
+
left: -1,
|
|
2252
|
+
right: 7
|
|
2253
|
+
},
|
|
2254
|
+
"*": {
|
|
2255
|
+
width: 9,
|
|
2256
|
+
height: 27,
|
|
2257
|
+
ascent: 22,
|
|
2258
|
+
descent: 5,
|
|
2259
|
+
left: -1,
|
|
2260
|
+
right: 8
|
|
2261
|
+
},
|
|
2262
|
+
"+": {
|
|
2263
|
+
width: 14,
|
|
2264
|
+
height: 27,
|
|
2265
|
+
ascent: 22,
|
|
2266
|
+
descent: 5,
|
|
2267
|
+
left: -1,
|
|
2268
|
+
right: 13
|
|
2269
|
+
},
|
|
2270
|
+
",": {
|
|
2271
|
+
width: 7,
|
|
2272
|
+
height: 27,
|
|
2273
|
+
ascent: 22,
|
|
2274
|
+
descent: 5,
|
|
2275
|
+
left: -2,
|
|
2276
|
+
right: 5
|
|
2277
|
+
},
|
|
2278
|
+
"-": {
|
|
2279
|
+
width: 8,
|
|
2280
|
+
height: 27,
|
|
2281
|
+
ascent: 22,
|
|
2282
|
+
descent: 5,
|
|
2283
|
+
left: -1,
|
|
2284
|
+
right: 7
|
|
2285
|
+
},
|
|
2286
|
+
".": {
|
|
2287
|
+
width: 7,
|
|
2288
|
+
height: 27,
|
|
2289
|
+
ascent: 22,
|
|
2290
|
+
descent: 5,
|
|
2291
|
+
left: -2,
|
|
2292
|
+
right: 5
|
|
2293
|
+
},
|
|
2294
|
+
"/": {
|
|
2295
|
+
width: 7,
|
|
2296
|
+
height: 27,
|
|
2297
|
+
ascent: 22,
|
|
2298
|
+
descent: 5,
|
|
2299
|
+
left: 0,
|
|
2300
|
+
right: 7
|
|
2301
|
+
},
|
|
2302
|
+
":": {
|
|
2303
|
+
width: 7,
|
|
2304
|
+
height: 27,
|
|
2305
|
+
ascent: 22,
|
|
2306
|
+
descent: 5,
|
|
2307
|
+
left: -2,
|
|
2308
|
+
right: 5
|
|
2309
|
+
},
|
|
2310
|
+
";": {
|
|
2311
|
+
width: 7,
|
|
2312
|
+
height: 27,
|
|
2313
|
+
ascent: 22,
|
|
2314
|
+
descent: 5,
|
|
2315
|
+
left: -2,
|
|
2316
|
+
right: 5
|
|
2317
|
+
},
|
|
2318
|
+
"<": {
|
|
2319
|
+
width: 14,
|
|
2320
|
+
height: 27,
|
|
2321
|
+
ascent: 22,
|
|
2322
|
+
descent: 5,
|
|
2323
|
+
left: -1,
|
|
2324
|
+
right: 13
|
|
2325
|
+
},
|
|
2326
|
+
"=": {
|
|
2327
|
+
width: 14,
|
|
2328
|
+
height: 27,
|
|
2329
|
+
ascent: 22,
|
|
2330
|
+
descent: 5,
|
|
2331
|
+
left: -1,
|
|
2332
|
+
right: 13
|
|
2333
|
+
},
|
|
2334
|
+
">": {
|
|
2335
|
+
width: 14,
|
|
2336
|
+
height: 27,
|
|
2337
|
+
ascent: 22,
|
|
2338
|
+
descent: 5,
|
|
2339
|
+
left: -1,
|
|
2340
|
+
right: 13
|
|
2341
|
+
},
|
|
2342
|
+
"?": {
|
|
2343
|
+
width: 13,
|
|
2344
|
+
height: 27,
|
|
2345
|
+
ascent: 22,
|
|
2346
|
+
descent: 5,
|
|
2347
|
+
left: -1,
|
|
2348
|
+
right: 12
|
|
2349
|
+
},
|
|
2350
|
+
"@": {
|
|
2351
|
+
width: 24,
|
|
2352
|
+
height: 27,
|
|
2353
|
+
ascent: 22,
|
|
2354
|
+
descent: 5,
|
|
2355
|
+
left: -1,
|
|
2356
|
+
right: 23
|
|
2357
|
+
},
|
|
2358
|
+
A: {
|
|
2359
|
+
width: 16,
|
|
2360
|
+
height: 27,
|
|
2361
|
+
ascent: 22,
|
|
2362
|
+
descent: 5,
|
|
2363
|
+
left: 0,
|
|
2364
|
+
right: 16
|
|
2365
|
+
},
|
|
2366
|
+
B: {
|
|
2367
|
+
width: 16,
|
|
2368
|
+
height: 27,
|
|
2369
|
+
ascent: 22,
|
|
2370
|
+
descent: 5,
|
|
2371
|
+
left: -2,
|
|
2372
|
+
right: 15
|
|
2373
|
+
},
|
|
2374
|
+
C: {
|
|
2375
|
+
width: 17,
|
|
2376
|
+
height: 27,
|
|
2377
|
+
ascent: 22,
|
|
2378
|
+
descent: 5,
|
|
2379
|
+
left: -1,
|
|
2380
|
+
right: 16
|
|
2381
|
+
},
|
|
2382
|
+
D: {
|
|
2383
|
+
width: 17,
|
|
2384
|
+
height: 27,
|
|
2385
|
+
ascent: 22,
|
|
2386
|
+
descent: 5,
|
|
2387
|
+
left: -2,
|
|
2388
|
+
right: 16
|
|
2389
|
+
},
|
|
2390
|
+
E: {
|
|
2391
|
+
width: 16,
|
|
2392
|
+
height: 27,
|
|
2393
|
+
ascent: 22,
|
|
2394
|
+
descent: 5,
|
|
2395
|
+
left: -2,
|
|
2396
|
+
right: 15
|
|
2397
|
+
},
|
|
2398
|
+
F: {
|
|
2399
|
+
width: 15,
|
|
2400
|
+
height: 27,
|
|
2401
|
+
ascent: 22,
|
|
2402
|
+
descent: 5,
|
|
2403
|
+
left: -2,
|
|
2404
|
+
right: 14
|
|
2405
|
+
},
|
|
2406
|
+
G: {
|
|
2407
|
+
width: 19,
|
|
2408
|
+
height: 27,
|
|
2409
|
+
ascent: 22,
|
|
2410
|
+
descent: 5,
|
|
2411
|
+
left: -1,
|
|
2412
|
+
right: 17
|
|
2413
|
+
},
|
|
2414
|
+
H: {
|
|
2415
|
+
width: 17,
|
|
2416
|
+
height: 27,
|
|
2417
|
+
ascent: 22,
|
|
2418
|
+
descent: 5,
|
|
2419
|
+
left: -2,
|
|
2420
|
+
right: 15
|
|
2421
|
+
},
|
|
2422
|
+
I: {
|
|
2423
|
+
width: 7,
|
|
2424
|
+
height: 27,
|
|
2425
|
+
ascent: 22,
|
|
2426
|
+
descent: 5,
|
|
2427
|
+
left: -2,
|
|
2428
|
+
right: 5
|
|
2429
|
+
},
|
|
2430
|
+
J: {
|
|
2431
|
+
width: 12,
|
|
2432
|
+
height: 27,
|
|
2433
|
+
ascent: 22,
|
|
2434
|
+
descent: 5,
|
|
2435
|
+
left: -1,
|
|
2436
|
+
right: 10
|
|
2437
|
+
},
|
|
2438
|
+
K: {
|
|
2439
|
+
width: 16,
|
|
2440
|
+
height: 27,
|
|
2441
|
+
ascent: 22,
|
|
2442
|
+
descent: 5,
|
|
2443
|
+
left: -2,
|
|
2444
|
+
right: 16
|
|
2445
|
+
},
|
|
2446
|
+
L: {
|
|
2447
|
+
width: 13,
|
|
2448
|
+
height: 27,
|
|
2449
|
+
ascent: 22,
|
|
2450
|
+
descent: 5,
|
|
2451
|
+
left: -2,
|
|
2452
|
+
right: 12
|
|
2453
|
+
},
|
|
2454
|
+
M: {
|
|
2455
|
+
width: 20,
|
|
2456
|
+
height: 27,
|
|
2457
|
+
ascent: 22,
|
|
2458
|
+
descent: 5,
|
|
2459
|
+
left: -2,
|
|
2460
|
+
right: 18
|
|
2461
|
+
},
|
|
2462
|
+
N: {
|
|
2463
|
+
width: 17,
|
|
2464
|
+
height: 27,
|
|
2465
|
+
ascent: 22,
|
|
2466
|
+
descent: 5,
|
|
2467
|
+
left: -2,
|
|
2468
|
+
right: 15
|
|
2469
|
+
},
|
|
2470
|
+
O: {
|
|
2471
|
+
width: 19,
|
|
2472
|
+
height: 27,
|
|
2473
|
+
ascent: 22,
|
|
2474
|
+
descent: 5,
|
|
2475
|
+
left: -1,
|
|
2476
|
+
right: 18
|
|
2477
|
+
},
|
|
2478
|
+
P: {
|
|
2479
|
+
width: 16,
|
|
2480
|
+
height: 27,
|
|
2481
|
+
ascent: 22,
|
|
2482
|
+
descent: 5,
|
|
2483
|
+
left: -2,
|
|
2484
|
+
right: 15
|
|
2485
|
+
},
|
|
2486
|
+
Q: {
|
|
2487
|
+
width: 19,
|
|
2488
|
+
height: 27,
|
|
2489
|
+
ascent: 22,
|
|
2490
|
+
descent: 5,
|
|
2491
|
+
left: -1,
|
|
2492
|
+
right: 18
|
|
2493
|
+
},
|
|
2494
|
+
R: {
|
|
2495
|
+
width: 17,
|
|
2496
|
+
height: 27,
|
|
2497
|
+
ascent: 22,
|
|
2498
|
+
descent: 5,
|
|
2499
|
+
left: -2,
|
|
2500
|
+
right: 17
|
|
2501
|
+
},
|
|
2502
|
+
S: {
|
|
2503
|
+
width: 16,
|
|
2504
|
+
height: 27,
|
|
2505
|
+
ascent: 22,
|
|
2506
|
+
descent: 5,
|
|
2507
|
+
left: -1,
|
|
2508
|
+
right: 15
|
|
2509
|
+
},
|
|
2510
|
+
T: {
|
|
2511
|
+
width: 15,
|
|
2512
|
+
height: 27,
|
|
2513
|
+
ascent: 22,
|
|
2514
|
+
descent: 5,
|
|
2515
|
+
left: -1,
|
|
2516
|
+
right: 14
|
|
2517
|
+
},
|
|
2518
|
+
U: {
|
|
2519
|
+
width: 17,
|
|
2520
|
+
height: 27,
|
|
2521
|
+
ascent: 22,
|
|
2522
|
+
descent: 5,
|
|
2523
|
+
left: -2,
|
|
2524
|
+
right: 15
|
|
2525
|
+
},
|
|
2526
|
+
V: {
|
|
2527
|
+
width: 16,
|
|
2528
|
+
height: 27,
|
|
2529
|
+
ascent: 22,
|
|
2530
|
+
descent: 5,
|
|
2531
|
+
left: 0,
|
|
2532
|
+
right: 16
|
|
2533
|
+
},
|
|
2534
|
+
W: {
|
|
2535
|
+
width: 23,
|
|
2536
|
+
height: 27,
|
|
2537
|
+
ascent: 22,
|
|
2538
|
+
descent: 5,
|
|
2539
|
+
left: 0,
|
|
2540
|
+
right: 22
|
|
2541
|
+
},
|
|
2542
|
+
X: {
|
|
2543
|
+
width: 16,
|
|
2544
|
+
height: 27,
|
|
2545
|
+
ascent: 22,
|
|
2546
|
+
descent: 5,
|
|
2547
|
+
left: 0,
|
|
2548
|
+
right: 16
|
|
2549
|
+
},
|
|
2550
|
+
Y: {
|
|
2551
|
+
width: 16,
|
|
2552
|
+
height: 27,
|
|
2553
|
+
ascent: 22,
|
|
2554
|
+
descent: 5,
|
|
2555
|
+
left: 0,
|
|
2556
|
+
right: 16
|
|
2557
|
+
},
|
|
2558
|
+
Z: {
|
|
2559
|
+
width: 15,
|
|
2560
|
+
height: 27,
|
|
2561
|
+
ascent: 22,
|
|
2562
|
+
descent: 5,
|
|
2563
|
+
left: 0,
|
|
2564
|
+
right: 14
|
|
2565
|
+
},
|
|
2566
|
+
"[": {
|
|
2567
|
+
width: 7,
|
|
2568
|
+
height: 27,
|
|
2569
|
+
ascent: 22,
|
|
2570
|
+
descent: 5,
|
|
2571
|
+
left: -2,
|
|
2572
|
+
right: 6
|
|
2573
|
+
},
|
|
2574
|
+
"\\": {
|
|
2575
|
+
width: 7,
|
|
2576
|
+
height: 27,
|
|
2577
|
+
ascent: 22,
|
|
2578
|
+
descent: 5,
|
|
2579
|
+
left: 0,
|
|
2580
|
+
right: 7
|
|
2581
|
+
},
|
|
2582
|
+
"]": {
|
|
2583
|
+
width: 7,
|
|
2584
|
+
height: 27,
|
|
2585
|
+
ascent: 22,
|
|
2586
|
+
descent: 5,
|
|
2587
|
+
left: 0,
|
|
2588
|
+
right: 5
|
|
2589
|
+
},
|
|
2590
|
+
"^": {
|
|
2591
|
+
width: 11,
|
|
2592
|
+
height: 27,
|
|
2593
|
+
ascent: 22,
|
|
2594
|
+
descent: 5,
|
|
2595
|
+
left: -1,
|
|
2596
|
+
right: 11
|
|
2597
|
+
},
|
|
2598
|
+
_: {
|
|
2599
|
+
width: 13,
|
|
2600
|
+
height: 27,
|
|
2601
|
+
ascent: 22,
|
|
2602
|
+
descent: 5,
|
|
2603
|
+
left: 0,
|
|
2604
|
+
right: 14
|
|
2605
|
+
},
|
|
2606
|
+
"`": {
|
|
2607
|
+
width: 8,
|
|
2608
|
+
height: 27,
|
|
2609
|
+
ascent: 22,
|
|
2610
|
+
descent: 5,
|
|
2611
|
+
left: -1,
|
|
2612
|
+
right: 5
|
|
2613
|
+
},
|
|
2614
|
+
a: {
|
|
2615
|
+
width: 13,
|
|
2616
|
+
height: 27,
|
|
2617
|
+
ascent: 22,
|
|
2618
|
+
descent: 5,
|
|
2619
|
+
left: -1,
|
|
2620
|
+
right: 12
|
|
2621
|
+
},
|
|
2622
|
+
b: {
|
|
2623
|
+
width: 13,
|
|
2624
|
+
height: 27,
|
|
2625
|
+
ascent: 22,
|
|
2626
|
+
descent: 5,
|
|
2627
|
+
left: -2,
|
|
2628
|
+
right: 12
|
|
2629
|
+
},
|
|
2630
|
+
c: {
|
|
2631
|
+
width: 12,
|
|
2632
|
+
height: 27,
|
|
2633
|
+
ascent: 22,
|
|
2634
|
+
descent: 5,
|
|
2635
|
+
left: -1,
|
|
2636
|
+
right: 12
|
|
2637
|
+
},
|
|
2638
|
+
d: {
|
|
2639
|
+
width: 13,
|
|
2640
|
+
height: 27,
|
|
2641
|
+
ascent: 22,
|
|
2642
|
+
descent: 5,
|
|
2643
|
+
left: -1,
|
|
2644
|
+
right: 12
|
|
2645
|
+
},
|
|
2646
|
+
e: {
|
|
2647
|
+
width: 13,
|
|
2648
|
+
height: 27,
|
|
2649
|
+
ascent: 22,
|
|
2650
|
+
descent: 5,
|
|
2651
|
+
left: -1,
|
|
2652
|
+
right: 12
|
|
2653
|
+
},
|
|
2654
|
+
f: {
|
|
2655
|
+
width: 7,
|
|
2656
|
+
height: 27,
|
|
2657
|
+
ascent: 22,
|
|
2658
|
+
descent: 5,
|
|
2659
|
+
left: 0,
|
|
2660
|
+
right: 8
|
|
2661
|
+
},
|
|
2662
|
+
g: {
|
|
2663
|
+
width: 13,
|
|
2664
|
+
height: 27,
|
|
2665
|
+
ascent: 22,
|
|
2666
|
+
descent: 5,
|
|
2667
|
+
left: -1,
|
|
2668
|
+
right: 12
|
|
2669
|
+
},
|
|
2670
|
+
h: {
|
|
2671
|
+
width: 13,
|
|
2672
|
+
height: 27,
|
|
2673
|
+
ascent: 22,
|
|
2674
|
+
descent: 5,
|
|
2675
|
+
left: -2,
|
|
2676
|
+
right: 12
|
|
2677
|
+
},
|
|
2678
|
+
i: {
|
|
2679
|
+
width: 5,
|
|
2680
|
+
height: 27,
|
|
2681
|
+
ascent: 22,
|
|
2682
|
+
descent: 5,
|
|
2683
|
+
left: -2,
|
|
2684
|
+
right: 4
|
|
2685
|
+
},
|
|
2686
|
+
j: {
|
|
2687
|
+
width: 5,
|
|
2688
|
+
height: 27,
|
|
2689
|
+
ascent: 22,
|
|
2690
|
+
descent: 5,
|
|
2691
|
+
left: 1,
|
|
2692
|
+
right: 4
|
|
2693
|
+
},
|
|
2694
|
+
k: {
|
|
2695
|
+
width: 12,
|
|
2696
|
+
height: 27,
|
|
2697
|
+
ascent: 22,
|
|
2698
|
+
descent: 5,
|
|
2699
|
+
left: -2,
|
|
2700
|
+
right: 12
|
|
2701
|
+
},
|
|
2702
|
+
l: {
|
|
2703
|
+
width: 5,
|
|
2704
|
+
height: 27,
|
|
2705
|
+
ascent: 22,
|
|
2706
|
+
descent: 5,
|
|
2707
|
+
left: -2,
|
|
2708
|
+
right: 4
|
|
2709
|
+
},
|
|
2710
|
+
m: {
|
|
2711
|
+
width: 20,
|
|
2712
|
+
height: 27,
|
|
2713
|
+
ascent: 22,
|
|
2714
|
+
descent: 5,
|
|
2715
|
+
left: -2,
|
|
2716
|
+
right: 18
|
|
2717
|
+
},
|
|
2718
|
+
n: {
|
|
2719
|
+
width: 13,
|
|
2720
|
+
height: 27,
|
|
2721
|
+
ascent: 22,
|
|
2722
|
+
descent: 5,
|
|
2723
|
+
left: -2,
|
|
2724
|
+
right: 12
|
|
2725
|
+
},
|
|
2726
|
+
o: {
|
|
2727
|
+
width: 13,
|
|
2728
|
+
height: 27,
|
|
2729
|
+
ascent: 22,
|
|
2730
|
+
descent: 5,
|
|
2731
|
+
left: -1,
|
|
2732
|
+
right: 12
|
|
2733
|
+
},
|
|
2734
|
+
p: {
|
|
2735
|
+
width: 13,
|
|
2736
|
+
height: 27,
|
|
2737
|
+
ascent: 22,
|
|
2738
|
+
descent: 5,
|
|
2739
|
+
left: -2,
|
|
2740
|
+
right: 12
|
|
2741
|
+
},
|
|
2742
|
+
q: {
|
|
2743
|
+
width: 13,
|
|
2744
|
+
height: 27,
|
|
2745
|
+
ascent: 22,
|
|
2746
|
+
descent: 5,
|
|
2747
|
+
left: -1,
|
|
2748
|
+
right: 12
|
|
2749
|
+
},
|
|
2750
|
+
r: {
|
|
2751
|
+
width: 8,
|
|
2752
|
+
height: 27,
|
|
2753
|
+
ascent: 22,
|
|
2754
|
+
descent: 5,
|
|
2755
|
+
left: -2,
|
|
2756
|
+
right: 8
|
|
2757
|
+
},
|
|
2758
|
+
s: {
|
|
2759
|
+
width: 12,
|
|
2760
|
+
height: 27,
|
|
2761
|
+
ascent: 22,
|
|
2762
|
+
descent: 5,
|
|
2763
|
+
left: -1,
|
|
2764
|
+
right: 11
|
|
2765
|
+
},
|
|
2766
|
+
t: {
|
|
2767
|
+
width: 7,
|
|
2768
|
+
height: 27,
|
|
2769
|
+
ascent: 22,
|
|
2770
|
+
descent: 5,
|
|
2771
|
+
left: 0,
|
|
2772
|
+
right: 6
|
|
2773
|
+
},
|
|
2774
|
+
u: {
|
|
2775
|
+
width: 13,
|
|
2776
|
+
height: 27,
|
|
2777
|
+
ascent: 22,
|
|
2778
|
+
descent: 5,
|
|
2779
|
+
left: -2,
|
|
2780
|
+
right: 12
|
|
2781
|
+
},
|
|
2782
|
+
v: {
|
|
2783
|
+
width: 12,
|
|
2784
|
+
height: 27,
|
|
2785
|
+
ascent: 22,
|
|
2786
|
+
descent: 5,
|
|
2787
|
+
left: 0,
|
|
2788
|
+
right: 12
|
|
2789
|
+
},
|
|
2790
|
+
w: {
|
|
2791
|
+
width: 17,
|
|
2792
|
+
height: 27,
|
|
2793
|
+
ascent: 22,
|
|
2794
|
+
descent: 5,
|
|
2795
|
+
left: 0,
|
|
2796
|
+
right: 17
|
|
2797
|
+
},
|
|
2798
|
+
x: {
|
|
2799
|
+
width: 12,
|
|
2800
|
+
height: 27,
|
|
2801
|
+
ascent: 22,
|
|
2802
|
+
descent: 5,
|
|
2803
|
+
left: 0,
|
|
2804
|
+
right: 12
|
|
2805
|
+
},
|
|
2806
|
+
y: {
|
|
2807
|
+
width: 12,
|
|
2808
|
+
height: 27,
|
|
2809
|
+
ascent: 22,
|
|
2810
|
+
descent: 5,
|
|
2811
|
+
left: 0,
|
|
2812
|
+
right: 12
|
|
2813
|
+
},
|
|
2814
|
+
z: {
|
|
2815
|
+
width: 12,
|
|
2816
|
+
height: 27,
|
|
2817
|
+
ascent: 22,
|
|
2818
|
+
descent: 5,
|
|
2819
|
+
left: 0,
|
|
2820
|
+
right: 11
|
|
2821
|
+
},
|
|
2822
|
+
"{": {
|
|
2823
|
+
width: 8,
|
|
2824
|
+
height: 27,
|
|
2825
|
+
ascent: 22,
|
|
2826
|
+
descent: 5,
|
|
2827
|
+
left: -1,
|
|
2828
|
+
right: 7
|
|
2829
|
+
},
|
|
2830
|
+
"|": {
|
|
2831
|
+
width: 6,
|
|
2832
|
+
height: 27,
|
|
2833
|
+
ascent: 22,
|
|
2834
|
+
descent: 5,
|
|
2835
|
+
left: -2,
|
|
2836
|
+
right: 4
|
|
2837
|
+
},
|
|
2838
|
+
"}": {
|
|
2839
|
+
width: 8,
|
|
2840
|
+
height: 27,
|
|
2841
|
+
ascent: 22,
|
|
2842
|
+
descent: 5,
|
|
2843
|
+
left: -1,
|
|
2844
|
+
right: 7
|
|
2845
|
+
},
|
|
2846
|
+
"~": {
|
|
2847
|
+
width: 14,
|
|
2848
|
+
height: 27,
|
|
2849
|
+
ascent: 22,
|
|
2850
|
+
descent: 5,
|
|
2851
|
+
left: -1,
|
|
2852
|
+
right: 13
|
|
2006
2853
|
}
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
|
|
2854
|
+
};
|
|
2855
|
+
|
|
2856
|
+
// lib/sch/estimate-text-width.ts
|
|
2857
|
+
var estimateTextWidth = (text) => {
|
|
2858
|
+
if (!text) return 0;
|
|
2859
|
+
let totalWidth = 0;
|
|
2860
|
+
for (const char of text) {
|
|
2861
|
+
const metrics = arialTextMetrics[char];
|
|
2862
|
+
if (metrics) {
|
|
2863
|
+
totalWidth += metrics.width;
|
|
2864
|
+
} else {
|
|
2865
|
+
totalWidth += arialTextMetrics["?"].width;
|
|
2866
|
+
}
|
|
2867
|
+
}
|
|
2868
|
+
return totalWidth / 27;
|
|
2869
|
+
};
|
|
2870
|
+
|
|
2871
|
+
// lib/sch/svg-object-fns/create-svg-objects-for-sch-net-label.ts
|
|
2872
|
+
var ARROW_POINT_WIDTH_FSR = 0.3;
|
|
2873
|
+
var END_PADDING_FSR = 0.3;
|
|
2874
|
+
var END_PADDING_EXTRA_PER_CHARACTER_FSR = 0.06;
|
|
2875
|
+
var createSvgObjectsForSchNetLabel = (schNetLabel, realToScreenTransform) => {
|
|
2876
|
+
if (!schNetLabel.text) return [];
|
|
2877
|
+
const svgObjects = [];
|
|
2878
|
+
const fontSizePx = getSchScreenFontSize(realToScreenTransform, "net_label");
|
|
2879
|
+
const fontSizeMm = getSchMmFontSize("net_label");
|
|
2880
|
+
const textWidthFSR = estimateTextWidth(schNetLabel.text || "");
|
|
2881
|
+
const screenCenter = applyToPoint24(realToScreenTransform, schNetLabel.center);
|
|
2882
|
+
const realTextGrowthVec = getUnitVectorFromOutsideToEdge(
|
|
2883
|
+
schNetLabel.anchor_side
|
|
2884
|
+
);
|
|
2885
|
+
const screenTextGrowthVec = { ...realTextGrowthVec };
|
|
2886
|
+
screenTextGrowthVec.y *= -1;
|
|
2887
|
+
const fullWidthFsr = textWidthFSR + ARROW_POINT_WIDTH_FSR * 2 + END_PADDING_EXTRA_PER_CHARACTER_FSR * schNetLabel.text.length + END_PADDING_FSR;
|
|
2888
|
+
const screenAnchorPosition = schNetLabel.anchor_position ? applyToPoint24(realToScreenTransform, schNetLabel.anchor_position) : {
|
|
2889
|
+
x: screenCenter.x - screenTextGrowthVec.x * fullWidthFsr * fontSizePx / 2,
|
|
2890
|
+
y: screenCenter.y - screenTextGrowthVec.y * fullWidthFsr * fontSizePx / 2
|
|
2891
|
+
};
|
|
2892
|
+
const realAnchorPosition = schNetLabel.anchor_position ?? {
|
|
2893
|
+
x: schNetLabel.center.x - realTextGrowthVec.x * fullWidthFsr * fontSizeMm / 2,
|
|
2894
|
+
y: schNetLabel.center.y - realTextGrowthVec.y * fullWidthFsr * fontSizeMm / 2
|
|
2895
|
+
};
|
|
2896
|
+
const pathRotation = {
|
|
2897
|
+
left: 0,
|
|
2898
|
+
top: -90,
|
|
2899
|
+
bottom: 90,
|
|
2900
|
+
right: 180
|
|
2901
|
+
}[schNetLabel.anchor_side];
|
|
2902
|
+
const screenOutlinePoints = [
|
|
2903
|
+
// Arrow point in font-relative coordinates
|
|
2015
2904
|
{
|
|
2016
|
-
x:
|
|
2017
|
-
y:
|
|
2905
|
+
x: 0,
|
|
2906
|
+
y: 0
|
|
2018
2907
|
},
|
|
2019
|
-
//
|
|
2020
|
-
{
|
|
2021
|
-
|
|
2022
|
-
|
|
2908
|
+
// Top left corner in font-relative coordinates
|
|
2909
|
+
{
|
|
2910
|
+
x: ARROW_POINT_WIDTH_FSR,
|
|
2911
|
+
y: 0.6
|
|
2912
|
+
},
|
|
2913
|
+
// Top right corner in font-relative coordinates
|
|
2914
|
+
{
|
|
2915
|
+
x: ARROW_POINT_WIDTH_FSR * 2 + END_PADDING_FSR + END_PADDING_EXTRA_PER_CHARACTER_FSR * schNetLabel.text.length + textWidthFSR,
|
|
2916
|
+
y: 0.6
|
|
2917
|
+
},
|
|
2918
|
+
// Bottom right corner in font-relative coordinates
|
|
2919
|
+
{
|
|
2920
|
+
x: ARROW_POINT_WIDTH_FSR * 2 + END_PADDING_FSR + END_PADDING_EXTRA_PER_CHARACTER_FSR * schNetLabel.text.length + textWidthFSR,
|
|
2921
|
+
y: -0.6
|
|
2922
|
+
},
|
|
2923
|
+
// Bottom left corner in font-relative coordinates
|
|
2924
|
+
{
|
|
2925
|
+
x: ARROW_POINT_WIDTH_FSR,
|
|
2926
|
+
y: -0.6
|
|
2927
|
+
}
|
|
2928
|
+
].map(
|
|
2929
|
+
(fontRelativePoint) => applyToPoint24(
|
|
2930
|
+
compose6(
|
|
2931
|
+
realToScreenTransform,
|
|
2932
|
+
translate6(realAnchorPosition.x, realAnchorPosition.y),
|
|
2933
|
+
scale3(fontSizeMm),
|
|
2934
|
+
rotate3(pathRotation / 180 * Math.PI)
|
|
2935
|
+
),
|
|
2936
|
+
fontRelativePoint
|
|
2937
|
+
)
|
|
2938
|
+
);
|
|
2023
2939
|
const pathD = `
|
|
2024
|
-
M ${
|
|
2025
|
-
L ${
|
|
2026
|
-
L ${
|
|
2027
|
-
L ${
|
|
2028
|
-
L ${
|
|
2940
|
+
M ${screenOutlinePoints[0].x},${screenOutlinePoints[0].y}
|
|
2941
|
+
L ${screenOutlinePoints[1].x},${screenOutlinePoints[1].y}
|
|
2942
|
+
L ${screenOutlinePoints[2].x},${screenOutlinePoints[2].y}
|
|
2943
|
+
L ${screenOutlinePoints[3].x},${screenOutlinePoints[3].y}
|
|
2944
|
+
L ${screenOutlinePoints[4].x},${screenOutlinePoints[4].y}
|
|
2029
2945
|
Z
|
|
2030
2946
|
`;
|
|
2031
2947
|
svgObjects.push({
|
|
@@ -2036,28 +2952,41 @@ var createSvgObjectsForSchNetLabel = (schNetLabel, transform) => {
|
|
|
2036
2952
|
d: pathD,
|
|
2037
2953
|
fill: "white",
|
|
2038
2954
|
stroke: colorMap.schematic.label_global,
|
|
2039
|
-
"stroke-width": `${getSchStrokeSize(
|
|
2040
|
-
transform: transformString
|
|
2955
|
+
"stroke-width": `${getSchStrokeSize(realToScreenTransform)}px`
|
|
2041
2956
|
},
|
|
2042
2957
|
value: "",
|
|
2043
2958
|
children: []
|
|
2044
2959
|
});
|
|
2045
|
-
const
|
|
2046
|
-
|
|
2960
|
+
const screenTextPos = {
|
|
2961
|
+
x: screenAnchorPosition.x + screenTextGrowthVec.x * fontSizePx * 0.5,
|
|
2962
|
+
y: screenAnchorPosition.y + screenTextGrowthVec.y * fontSizePx * 0.5
|
|
2963
|
+
};
|
|
2964
|
+
const textAnchor = {
|
|
2965
|
+
left: "start",
|
|
2966
|
+
top: "start",
|
|
2967
|
+
bottom: "start",
|
|
2968
|
+
right: "end"
|
|
2969
|
+
}[schNetLabel.anchor_side];
|
|
2970
|
+
const textTransformString = {
|
|
2971
|
+
left: "",
|
|
2972
|
+
right: "",
|
|
2973
|
+
top: `rotate(90 ${screenTextPos.x} ${screenTextPos.y})`,
|
|
2974
|
+
bottom: `rotate(-90 ${screenTextPos.x} ${screenTextPos.y})`
|
|
2975
|
+
}[schNetLabel.anchor_side];
|
|
2047
2976
|
svgObjects.push({
|
|
2048
2977
|
name: "text",
|
|
2049
2978
|
type: "element",
|
|
2050
2979
|
attributes: {
|
|
2051
2980
|
class: "net-label-text",
|
|
2052
|
-
x:
|
|
2053
|
-
y:
|
|
2981
|
+
x: screenTextPos.x.toString(),
|
|
2982
|
+
y: screenTextPos.y.toString(),
|
|
2054
2983
|
fill: colorMap.schematic.label_global,
|
|
2055
|
-
"text-anchor":
|
|
2984
|
+
"text-anchor": textAnchor,
|
|
2056
2985
|
"dominant-baseline": "central",
|
|
2057
|
-
// Changed to central for better vertical alignment
|
|
2058
2986
|
"font-family": "sans-serif",
|
|
2059
|
-
"font-
|
|
2060
|
-
|
|
2987
|
+
"font-variant-numeric": "tabular-nums",
|
|
2988
|
+
"font-size": `${fontSizePx}px`,
|
|
2989
|
+
transform: textTransformString
|
|
2061
2990
|
},
|
|
2062
2991
|
children: [
|
|
2063
2992
|
{
|
|
@@ -2128,14 +3057,6 @@ function convertCircuitJsonToSchematicSvg(circuitJson, options) {
|
|
|
2128
3057
|
drawSchematicGrid({ bounds: realBounds, transform, ...gridConfig })
|
|
2129
3058
|
);
|
|
2130
3059
|
}
|
|
2131
|
-
if (options?.labeledPoints) {
|
|
2132
|
-
svgChildren.push(
|
|
2133
|
-
drawSchematicLabeledPoints({
|
|
2134
|
-
points: options.labeledPoints,
|
|
2135
|
-
transform
|
|
2136
|
-
})
|
|
2137
|
-
);
|
|
2138
|
-
}
|
|
2139
3060
|
const schDebugObjectSvgs = [];
|
|
2140
3061
|
const schComponentSvgs = [];
|
|
2141
3062
|
const schTraceSvgs = [];
|
|
@@ -2165,6 +3086,14 @@ function convertCircuitJsonToSchematicSvg(circuitJson, options) {
|
|
|
2165
3086
|
...schTraceSvgs,
|
|
2166
3087
|
...schNetLabel
|
|
2167
3088
|
);
|
|
3089
|
+
if (options?.labeledPoints) {
|
|
3090
|
+
svgChildren.push(
|
|
3091
|
+
drawSchematicLabeledPoints({
|
|
3092
|
+
points: options.labeledPoints,
|
|
3093
|
+
transform
|
|
3094
|
+
})
|
|
3095
|
+
);
|
|
3096
|
+
}
|
|
2168
3097
|
const svgObject = {
|
|
2169
3098
|
name: "svg",
|
|
2170
3099
|
type: "element",
|