circuit-to-svg 0.0.197 → 0.0.199
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 +37 -5
- package/dist/index.js +1166 -144
- package/dist/index.js.map +1 -1
- package/package.json +2 -1
package/dist/index.js
CHANGED
|
@@ -1743,7 +1743,7 @@ function getSoftwareUsedString(circuitJson) {
|
|
|
1743
1743
|
var package_default = {
|
|
1744
1744
|
name: "circuit-to-svg",
|
|
1745
1745
|
type: "module",
|
|
1746
|
-
version: "0.0.
|
|
1746
|
+
version: "0.0.198",
|
|
1747
1747
|
description: "Convert Circuit JSON to SVG",
|
|
1748
1748
|
main: "dist/index.js",
|
|
1749
1749
|
files: [
|
|
@@ -1783,6 +1783,7 @@ var package_default = {
|
|
|
1783
1783
|
dependencies: {
|
|
1784
1784
|
"@types/node": "^22.5.5",
|
|
1785
1785
|
"bun-types": "^1.1.40",
|
|
1786
|
+
"calculate-elbow": "0.0.12",
|
|
1786
1787
|
svgson: "^5.3.1",
|
|
1787
1788
|
"transformation-matrix": "^2.16.1"
|
|
1788
1789
|
}
|
|
@@ -3070,6 +3071,1026 @@ function createSvgObjectFromAssemblyBoundary(transform, minX, minY, maxX, maxY)
|
|
|
3070
3071
|
};
|
|
3071
3072
|
}
|
|
3072
3073
|
|
|
3074
|
+
// lib/pinout/convert-circuit-json-to-pinout-svg.ts
|
|
3075
|
+
import { stringify as stringify3 } from "svgson";
|
|
3076
|
+
import "@tscircuit/circuit-json-util";
|
|
3077
|
+
import {
|
|
3078
|
+
compose as compose7,
|
|
3079
|
+
scale as scale4,
|
|
3080
|
+
translate as translate7
|
|
3081
|
+
} from "transformation-matrix";
|
|
3082
|
+
|
|
3083
|
+
// lib/pinout/svg-object-fns/create-svg-objects-from-pinout-board.ts
|
|
3084
|
+
import { applyToPoint as applyToPoint28 } from "transformation-matrix";
|
|
3085
|
+
import { su as su4 } from "@tscircuit/circuit-json-util";
|
|
3086
|
+
var BOARD_FILL_COLOR = "rgb(26, 115, 143)";
|
|
3087
|
+
var BOARD_STROKE_COLOR = "rgba(0,0,0,0.9)";
|
|
3088
|
+
function createSvgObjectsFromPinoutBoard(pcbBoard, ctx) {
|
|
3089
|
+
const { transform, soup } = ctx;
|
|
3090
|
+
const { width, height, center, outline } = pcbBoard;
|
|
3091
|
+
let path;
|
|
3092
|
+
if (outline && Array.isArray(outline) && outline.length >= 3) {
|
|
3093
|
+
path = outline.map((point, index) => {
|
|
3094
|
+
const [x, y] = applyToPoint28(transform, [point.x, point.y]);
|
|
3095
|
+
return index === 0 ? `M ${x} ${y}` : `L ${x} ${y}`;
|
|
3096
|
+
}).join(" ");
|
|
3097
|
+
} else {
|
|
3098
|
+
const halfWidth = width / 2;
|
|
3099
|
+
const halfHeight = height / 2;
|
|
3100
|
+
const topLeft = applyToPoint28(transform, [
|
|
3101
|
+
center.x - halfWidth,
|
|
3102
|
+
center.y - halfHeight
|
|
3103
|
+
]);
|
|
3104
|
+
const topRight = applyToPoint28(transform, [
|
|
3105
|
+
center.x + halfWidth,
|
|
3106
|
+
center.y - halfHeight
|
|
3107
|
+
]);
|
|
3108
|
+
const bottomRight = applyToPoint28(transform, [
|
|
3109
|
+
center.x + halfWidth,
|
|
3110
|
+
center.y + halfHeight
|
|
3111
|
+
]);
|
|
3112
|
+
const bottomLeft = applyToPoint28(transform, [
|
|
3113
|
+
center.x - halfWidth,
|
|
3114
|
+
center.y + halfHeight
|
|
3115
|
+
]);
|
|
3116
|
+
path = `M ${topLeft[0]} ${topLeft[1]} L ${topRight[0]} ${topRight[1]} L ${bottomRight[0]} ${bottomRight[1]} L ${bottomLeft[0]} ${bottomLeft[1]}`;
|
|
3117
|
+
}
|
|
3118
|
+
path += " Z";
|
|
3119
|
+
const cutlery = su4(soup).pcb_cutout.list();
|
|
3120
|
+
for (const cutout of cutlery) {
|
|
3121
|
+
if (cutout.shape === "rect") {
|
|
3122
|
+
const { x, y, width: width2, height: height2 } = cutout.center ? (() => {
|
|
3123
|
+
const { x: x2, y: y2 } = cutout.center;
|
|
3124
|
+
const { width: width3, height: height3 } = cutout;
|
|
3125
|
+
return { x: x2, y: y2, width: width3, height: height3 };
|
|
3126
|
+
})() : { x: 0, y: 0, width: 0, height: 0 };
|
|
3127
|
+
const halfWidth = width2 / 2;
|
|
3128
|
+
const halfHeight = height2 / 2;
|
|
3129
|
+
const [tl, tr, br, bl] = [
|
|
3130
|
+
applyToPoint28(transform, [x - halfWidth, y - halfHeight]),
|
|
3131
|
+
applyToPoint28(transform, [x + halfWidth, y - halfHeight]),
|
|
3132
|
+
applyToPoint28(transform, [x + halfWidth, y + halfHeight]),
|
|
3133
|
+
applyToPoint28(transform, [x - halfWidth, y + halfHeight])
|
|
3134
|
+
];
|
|
3135
|
+
path += ` M ${tl[0]} ${tl[1]} L ${tr[0]} ${tr[1]} L ${br[0]} ${br[1]} L ${bl[0]} ${bl[1]} Z`;
|
|
3136
|
+
} else if (cutout.shape === "circle") {
|
|
3137
|
+
}
|
|
3138
|
+
}
|
|
3139
|
+
return [
|
|
3140
|
+
{
|
|
3141
|
+
name: "path",
|
|
3142
|
+
type: "element",
|
|
3143
|
+
value: "",
|
|
3144
|
+
children: [],
|
|
3145
|
+
attributes: {
|
|
3146
|
+
class: "pinout-board",
|
|
3147
|
+
d: path,
|
|
3148
|
+
fill: BOARD_FILL_COLOR,
|
|
3149
|
+
stroke: BOARD_STROKE_COLOR,
|
|
3150
|
+
"fill-rule": "evenodd",
|
|
3151
|
+
"stroke-opacity": "0.8",
|
|
3152
|
+
"stroke-width": (0.2 * Math.abs(transform.a)).toString()
|
|
3153
|
+
}
|
|
3154
|
+
}
|
|
3155
|
+
];
|
|
3156
|
+
}
|
|
3157
|
+
|
|
3158
|
+
// lib/pinout/svg-object-fns/create-svg-objects-from-pinout-component.ts
|
|
3159
|
+
import { su as su5 } from "@tscircuit/circuit-json-util";
|
|
3160
|
+
import { applyToPoint as applyToPoint29 } from "transformation-matrix";
|
|
3161
|
+
var COMPONENT_FILL_COLOR = "rgba(120, 120, 120, 0.6)";
|
|
3162
|
+
var COMPONENT_LABEL_COLOR = "rgba(255, 255, 255, 0.9)";
|
|
3163
|
+
function createSvgObjectsFromPinoutComponent(elm, ctx) {
|
|
3164
|
+
const { transform, soup } = ctx;
|
|
3165
|
+
const { center, width, height, rotation = 0, source_component_id } = elm;
|
|
3166
|
+
const sourceComponent = su5(soup).source_component.get(source_component_id);
|
|
3167
|
+
if (!center || typeof width !== "number" || typeof height !== "number" || width === 0 || height === 0) {
|
|
3168
|
+
return [];
|
|
3169
|
+
}
|
|
3170
|
+
const [x, y] = applyToPoint29(transform, [center.x, center.y]);
|
|
3171
|
+
const scaledWidth = width * Math.abs(transform.a);
|
|
3172
|
+
const scaledHeight = height * Math.abs(transform.d);
|
|
3173
|
+
const transformStr = `translate(${x}, ${y}) rotate(${-rotation})`;
|
|
3174
|
+
const children = [
|
|
3175
|
+
{
|
|
3176
|
+
name: "rect",
|
|
3177
|
+
type: "element",
|
|
3178
|
+
attributes: {
|
|
3179
|
+
class: "pinout-component-box",
|
|
3180
|
+
x: (-scaledWidth / 2).toString(),
|
|
3181
|
+
y: (-scaledHeight / 2).toString(),
|
|
3182
|
+
width: scaledWidth.toString(),
|
|
3183
|
+
height: scaledHeight.toString(),
|
|
3184
|
+
fill: COMPONENT_FILL_COLOR
|
|
3185
|
+
},
|
|
3186
|
+
value: "",
|
|
3187
|
+
children: []
|
|
3188
|
+
}
|
|
3189
|
+
];
|
|
3190
|
+
if (sourceComponent?.name) {
|
|
3191
|
+
const isTall = scaledHeight > scaledWidth * 1.5;
|
|
3192
|
+
const labelFontSize = Math.min(scaledWidth, scaledHeight) * 0.4;
|
|
3193
|
+
children.push({
|
|
3194
|
+
name: "text",
|
|
3195
|
+
type: "element",
|
|
3196
|
+
attributes: {
|
|
3197
|
+
x: "0",
|
|
3198
|
+
y: "0",
|
|
3199
|
+
fill: COMPONENT_LABEL_COLOR,
|
|
3200
|
+
"font-size": `${labelFontSize}px`,
|
|
3201
|
+
"font-family": "sans-serif",
|
|
3202
|
+
"text-anchor": "middle",
|
|
3203
|
+
"dominant-baseline": "middle",
|
|
3204
|
+
transform: isTall ? "rotate(90)" : ""
|
|
3205
|
+
},
|
|
3206
|
+
children: [
|
|
3207
|
+
{
|
|
3208
|
+
type: "text",
|
|
3209
|
+
value: sourceComponent.name,
|
|
3210
|
+
name: "",
|
|
3211
|
+
attributes: {},
|
|
3212
|
+
children: []
|
|
3213
|
+
}
|
|
3214
|
+
],
|
|
3215
|
+
value: ""
|
|
3216
|
+
});
|
|
3217
|
+
}
|
|
3218
|
+
return [
|
|
3219
|
+
{
|
|
3220
|
+
name: "g",
|
|
3221
|
+
type: "element",
|
|
3222
|
+
attributes: {
|
|
3223
|
+
transform: transformStr
|
|
3224
|
+
},
|
|
3225
|
+
children,
|
|
3226
|
+
value: ""
|
|
3227
|
+
}
|
|
3228
|
+
];
|
|
3229
|
+
}
|
|
3230
|
+
|
|
3231
|
+
// lib/pinout/svg-object-fns/create-svg-objects-from-pinout-hole.ts
|
|
3232
|
+
import { applyToPoint as applyToPoint30 } from "transformation-matrix";
|
|
3233
|
+
var HOLE_COLOR4 = "rgb(50, 50, 50)";
|
|
3234
|
+
function createSvgObjectsFromPinoutHole(hole, ctx) {
|
|
3235
|
+
const { transform } = ctx;
|
|
3236
|
+
const [x, y] = applyToPoint30(transform, [hole.x, hole.y]);
|
|
3237
|
+
if (hole.hole_shape === "circle" || hole.hole_shape === "square") {
|
|
3238
|
+
const scaledDiameter = hole.hole_diameter * Math.abs(transform.a);
|
|
3239
|
+
const radius = scaledDiameter / 2;
|
|
3240
|
+
if (hole.hole_shape === "circle") {
|
|
3241
|
+
return [
|
|
3242
|
+
{
|
|
3243
|
+
name: "circle",
|
|
3244
|
+
type: "element",
|
|
3245
|
+
attributes: {
|
|
3246
|
+
class: "pinout-hole",
|
|
3247
|
+
cx: x.toString(),
|
|
3248
|
+
cy: y.toString(),
|
|
3249
|
+
r: radius.toString(),
|
|
3250
|
+
fill: HOLE_COLOR4
|
|
3251
|
+
},
|
|
3252
|
+
children: [],
|
|
3253
|
+
value: ""
|
|
3254
|
+
}
|
|
3255
|
+
];
|
|
3256
|
+
}
|
|
3257
|
+
return [
|
|
3258
|
+
{
|
|
3259
|
+
name: "rect",
|
|
3260
|
+
type: "element",
|
|
3261
|
+
attributes: {
|
|
3262
|
+
class: "pinout-hole",
|
|
3263
|
+
x: (x - radius).toString(),
|
|
3264
|
+
y: (y - radius).toString(),
|
|
3265
|
+
width: scaledDiameter.toString(),
|
|
3266
|
+
height: scaledDiameter.toString(),
|
|
3267
|
+
fill: HOLE_COLOR4
|
|
3268
|
+
},
|
|
3269
|
+
children: [],
|
|
3270
|
+
value: ""
|
|
3271
|
+
}
|
|
3272
|
+
];
|
|
3273
|
+
}
|
|
3274
|
+
if (hole.hole_shape === "oval") {
|
|
3275
|
+
const scaledWidth = hole.hole_width * Math.abs(transform.a);
|
|
3276
|
+
const scaledHeight = hole.hole_height * Math.abs(transform.a);
|
|
3277
|
+
const rx = scaledWidth / 2;
|
|
3278
|
+
const ry = scaledHeight / 2;
|
|
3279
|
+
return [
|
|
3280
|
+
{
|
|
3281
|
+
name: "ellipse",
|
|
3282
|
+
type: "element",
|
|
3283
|
+
attributes: {
|
|
3284
|
+
class: "pinout-hole",
|
|
3285
|
+
cx: x.toString(),
|
|
3286
|
+
cy: y.toString(),
|
|
3287
|
+
rx: rx.toString(),
|
|
3288
|
+
ry: ry.toString(),
|
|
3289
|
+
fill: HOLE_COLOR4
|
|
3290
|
+
},
|
|
3291
|
+
children: [],
|
|
3292
|
+
value: ""
|
|
3293
|
+
}
|
|
3294
|
+
];
|
|
3295
|
+
}
|
|
3296
|
+
return [];
|
|
3297
|
+
}
|
|
3298
|
+
|
|
3299
|
+
// lib/pinout/svg-object-fns/create-svg-objects-from-pinout-plated-hole.ts
|
|
3300
|
+
import { applyToPoint as applyToPoint31 } from "transformation-matrix";
|
|
3301
|
+
var PAD_COLOR3 = "rgb(218, 165, 32)";
|
|
3302
|
+
var HOLE_COLOR5 = "rgb(40, 40, 40)";
|
|
3303
|
+
function createSvgObjectsFromPinoutPlatedHole(hole, ctx) {
|
|
3304
|
+
const { transform } = ctx;
|
|
3305
|
+
const [x, y] = applyToPoint31(transform, [hole.x, hole.y]);
|
|
3306
|
+
if (hole.shape === "pill") {
|
|
3307
|
+
const scaledOuterWidth = hole.outer_width * Math.abs(transform.a);
|
|
3308
|
+
const scaledOuterHeight = hole.outer_height * Math.abs(transform.a);
|
|
3309
|
+
const scaledHoleWidth = hole.hole_width * Math.abs(transform.a);
|
|
3310
|
+
const scaledHoleHeight = hole.hole_height * Math.abs(transform.a);
|
|
3311
|
+
const outerRadiusX = scaledOuterWidth / 2;
|
|
3312
|
+
const straightLength = scaledOuterHeight - scaledOuterWidth;
|
|
3313
|
+
const innerRadiusX = scaledHoleWidth / 2;
|
|
3314
|
+
return [
|
|
3315
|
+
{
|
|
3316
|
+
name: "g",
|
|
3317
|
+
type: "element",
|
|
3318
|
+
children: [
|
|
3319
|
+
// Outer pill shape
|
|
3320
|
+
{
|
|
3321
|
+
name: "path",
|
|
3322
|
+
type: "element",
|
|
3323
|
+
attributes: {
|
|
3324
|
+
class: "pinout-hole-outer",
|
|
3325
|
+
fill: PAD_COLOR3,
|
|
3326
|
+
d: `M${x - outerRadiusX},${y - straightLength / 2} v${straightLength} a${outerRadiusX},${outerRadiusX} 0 0 0 ${scaledOuterWidth},0 v-${straightLength} a${outerRadiusX},${outerRadiusX} 0 0 0 -${scaledOuterWidth},0 z`
|
|
3327
|
+
},
|
|
3328
|
+
value: "",
|
|
3329
|
+
children: []
|
|
3330
|
+
},
|
|
3331
|
+
// Inner pill shape
|
|
3332
|
+
{
|
|
3333
|
+
name: "path",
|
|
3334
|
+
type: "element",
|
|
3335
|
+
attributes: {
|
|
3336
|
+
class: "pinout-hole-inner",
|
|
3337
|
+
fill: HOLE_COLOR5,
|
|
3338
|
+
d: `M${x - innerRadiusX},${y - (scaledHoleHeight - scaledHoleWidth) / 2} v${scaledHoleHeight - scaledHoleWidth} a${innerRadiusX},${innerRadiusX} 0 0 0 ${scaledHoleWidth},0 v-${scaledHoleHeight - scaledHoleWidth} a${innerRadiusX},${innerRadiusX} 0 0 0 -${scaledHoleWidth},0 z`
|
|
3339
|
+
},
|
|
3340
|
+
value: "",
|
|
3341
|
+
children: []
|
|
3342
|
+
}
|
|
3343
|
+
],
|
|
3344
|
+
value: "",
|
|
3345
|
+
attributes: {}
|
|
3346
|
+
}
|
|
3347
|
+
];
|
|
3348
|
+
}
|
|
3349
|
+
if (hole.shape === "circle") {
|
|
3350
|
+
const scaledOuterWidth = hole.outer_diameter * Math.abs(transform.a);
|
|
3351
|
+
const scaledOuterHeight = hole.outer_diameter * Math.abs(transform.a);
|
|
3352
|
+
const scaledHoleWidth = hole.hole_diameter * Math.abs(transform.a);
|
|
3353
|
+
const scaledHoleHeight = hole.hole_diameter * Math.abs(transform.a);
|
|
3354
|
+
const outerRadius = Math.min(scaledOuterWidth, scaledOuterHeight) / 2;
|
|
3355
|
+
const innerRadius = Math.min(scaledHoleWidth, scaledHoleHeight) / 2;
|
|
3356
|
+
return [
|
|
3357
|
+
{
|
|
3358
|
+
name: "g",
|
|
3359
|
+
type: "element",
|
|
3360
|
+
children: [
|
|
3361
|
+
{
|
|
3362
|
+
name: "circle",
|
|
3363
|
+
type: "element",
|
|
3364
|
+
attributes: {
|
|
3365
|
+
class: "pinout-hole-outer",
|
|
3366
|
+
fill: PAD_COLOR3,
|
|
3367
|
+
cx: x.toString(),
|
|
3368
|
+
cy: y.toString(),
|
|
3369
|
+
r: outerRadius.toString()
|
|
3370
|
+
},
|
|
3371
|
+
value: "",
|
|
3372
|
+
children: []
|
|
3373
|
+
},
|
|
3374
|
+
{
|
|
3375
|
+
name: "circle",
|
|
3376
|
+
type: "element",
|
|
3377
|
+
attributes: {
|
|
3378
|
+
class: "pinout-hole-inner",
|
|
3379
|
+
fill: HOLE_COLOR5,
|
|
3380
|
+
cx: x.toString(),
|
|
3381
|
+
cy: y.toString(),
|
|
3382
|
+
r: innerRadius.toString()
|
|
3383
|
+
},
|
|
3384
|
+
value: "",
|
|
3385
|
+
children: []
|
|
3386
|
+
}
|
|
3387
|
+
],
|
|
3388
|
+
value: "",
|
|
3389
|
+
attributes: {}
|
|
3390
|
+
}
|
|
3391
|
+
];
|
|
3392
|
+
}
|
|
3393
|
+
if (hole.shape === "circular_hole_with_rect_pad") {
|
|
3394
|
+
const scaledHoleDiameter = hole.hole_diameter * Math.abs(transform.a);
|
|
3395
|
+
const scaledRectPadWidth = hole.rect_pad_width * Math.abs(transform.a);
|
|
3396
|
+
const scaledRectPadHeight = hole.rect_pad_height * Math.abs(transform.a);
|
|
3397
|
+
const holeRadius = scaledHoleDiameter / 2;
|
|
3398
|
+
return [
|
|
3399
|
+
{
|
|
3400
|
+
name: "g",
|
|
3401
|
+
type: "element",
|
|
3402
|
+
children: [
|
|
3403
|
+
// Rectangular pad (outer shape)
|
|
3404
|
+
{
|
|
3405
|
+
name: "rect",
|
|
3406
|
+
type: "element",
|
|
3407
|
+
attributes: {
|
|
3408
|
+
class: "pinout-hole-outer-pad",
|
|
3409
|
+
fill: PAD_COLOR3,
|
|
3410
|
+
x: (x - scaledRectPadWidth / 2).toString(),
|
|
3411
|
+
y: (y - scaledRectPadHeight / 2).toString(),
|
|
3412
|
+
width: scaledRectPadWidth.toString(),
|
|
3413
|
+
height: scaledRectPadHeight.toString()
|
|
3414
|
+
},
|
|
3415
|
+
value: "",
|
|
3416
|
+
children: []
|
|
3417
|
+
},
|
|
3418
|
+
// Circular hole inside the rectangle
|
|
3419
|
+
{
|
|
3420
|
+
name: "circle",
|
|
3421
|
+
type: "element",
|
|
3422
|
+
attributes: {
|
|
3423
|
+
class: "pinout-hole-inner",
|
|
3424
|
+
fill: HOLE_COLOR5,
|
|
3425
|
+
cx: x.toString(),
|
|
3426
|
+
cy: y.toString(),
|
|
3427
|
+
r: holeRadius.toString()
|
|
3428
|
+
},
|
|
3429
|
+
value: "",
|
|
3430
|
+
children: []
|
|
3431
|
+
}
|
|
3432
|
+
],
|
|
3433
|
+
value: "",
|
|
3434
|
+
attributes: {}
|
|
3435
|
+
}
|
|
3436
|
+
];
|
|
3437
|
+
}
|
|
3438
|
+
if (hole.shape === "pill_hole_with_rect_pad") {
|
|
3439
|
+
const scaledRectPadWidth = hole.rect_pad_width * Math.abs(transform.a);
|
|
3440
|
+
const scaledRectPadHeight = hole.rect_pad_height * Math.abs(transform.a);
|
|
3441
|
+
const scaledHoleHeight = hole.hole_height * Math.abs(transform.a);
|
|
3442
|
+
const scaledHoleWidth = hole.hole_width * Math.abs(transform.a);
|
|
3443
|
+
const holeRadius = Math.min(scaledHoleHeight, scaledHoleWidth) / 2;
|
|
3444
|
+
return [
|
|
3445
|
+
{
|
|
3446
|
+
name: "g",
|
|
3447
|
+
type: "element",
|
|
3448
|
+
children: [
|
|
3449
|
+
// Rectangular pad (outer shape)
|
|
3450
|
+
{
|
|
3451
|
+
name: "rect",
|
|
3452
|
+
type: "element",
|
|
3453
|
+
attributes: {
|
|
3454
|
+
class: "pinout-hole-outer-pad",
|
|
3455
|
+
fill: PAD_COLOR3,
|
|
3456
|
+
x: (x - scaledRectPadWidth / 2).toString(),
|
|
3457
|
+
y: (y - scaledRectPadHeight / 2).toString(),
|
|
3458
|
+
width: scaledRectPadWidth.toString(),
|
|
3459
|
+
height: scaledRectPadHeight.toString()
|
|
3460
|
+
},
|
|
3461
|
+
value: "",
|
|
3462
|
+
children: []
|
|
3463
|
+
},
|
|
3464
|
+
// pill hole inside the rectangle
|
|
3465
|
+
{
|
|
3466
|
+
name: "rect",
|
|
3467
|
+
type: "element",
|
|
3468
|
+
attributes: {
|
|
3469
|
+
class: "pinout-hole-inner",
|
|
3470
|
+
fill: HOLE_COLOR5,
|
|
3471
|
+
x: (x - scaledHoleWidth / 2).toString(),
|
|
3472
|
+
y: (y - scaledHoleHeight / 2).toString(),
|
|
3473
|
+
width: scaledHoleWidth.toString(),
|
|
3474
|
+
height: scaledHoleHeight.toString(),
|
|
3475
|
+
rx: holeRadius.toString(),
|
|
3476
|
+
ry: holeRadius.toString()
|
|
3477
|
+
},
|
|
3478
|
+
value: "",
|
|
3479
|
+
children: []
|
|
3480
|
+
}
|
|
3481
|
+
],
|
|
3482
|
+
value: "",
|
|
3483
|
+
attributes: {}
|
|
3484
|
+
}
|
|
3485
|
+
];
|
|
3486
|
+
}
|
|
3487
|
+
if (hole.shape === "rotated_pill_hole_with_rect_pad") {
|
|
3488
|
+
const scaledRectPadWidth = hole.rect_pad_width * Math.abs(transform.a);
|
|
3489
|
+
const scaledRectPadHeight = hole.rect_pad_height * Math.abs(transform.a);
|
|
3490
|
+
const scaledHoleHeight = hole.hole_height * Math.abs(transform.a);
|
|
3491
|
+
const scaledHoleWidth = hole.hole_width * Math.abs(transform.a);
|
|
3492
|
+
const holeRadius = Math.min(scaledHoleHeight, scaledHoleWidth) / 2;
|
|
3493
|
+
return [
|
|
3494
|
+
{
|
|
3495
|
+
name: "g",
|
|
3496
|
+
type: "element",
|
|
3497
|
+
children: [
|
|
3498
|
+
{
|
|
3499
|
+
name: "rect",
|
|
3500
|
+
type: "element",
|
|
3501
|
+
attributes: {
|
|
3502
|
+
class: "pinout-hole-outer-pad",
|
|
3503
|
+
fill: PAD_COLOR3,
|
|
3504
|
+
x: (-scaledRectPadWidth / 2).toString(),
|
|
3505
|
+
y: (-scaledRectPadHeight / 2).toString(),
|
|
3506
|
+
width: scaledRectPadWidth.toString(),
|
|
3507
|
+
height: scaledRectPadHeight.toString(),
|
|
3508
|
+
transform: `translate(${x} ${y}) rotate(${-hole.rect_ccw_rotation})`
|
|
3509
|
+
},
|
|
3510
|
+
value: "",
|
|
3511
|
+
children: []
|
|
3512
|
+
},
|
|
3513
|
+
{
|
|
3514
|
+
name: "rect",
|
|
3515
|
+
type: "element",
|
|
3516
|
+
attributes: {
|
|
3517
|
+
class: "pinout-hole-inner",
|
|
3518
|
+
fill: HOLE_COLOR5,
|
|
3519
|
+
x: (-scaledHoleWidth / 2).toString(),
|
|
3520
|
+
y: (-scaledHoleHeight / 2).toString(),
|
|
3521
|
+
width: scaledHoleWidth.toString(),
|
|
3522
|
+
height: scaledHoleHeight.toString(),
|
|
3523
|
+
rx: holeRadius.toString(),
|
|
3524
|
+
ry: holeRadius.toString(),
|
|
3525
|
+
transform: `translate(${x} ${y}) rotate(${-hole.hole_ccw_rotation})`
|
|
3526
|
+
},
|
|
3527
|
+
value: "",
|
|
3528
|
+
children: []
|
|
3529
|
+
}
|
|
3530
|
+
],
|
|
3531
|
+
value: "",
|
|
3532
|
+
attributes: {}
|
|
3533
|
+
}
|
|
3534
|
+
];
|
|
3535
|
+
}
|
|
3536
|
+
return [];
|
|
3537
|
+
}
|
|
3538
|
+
|
|
3539
|
+
// lib/pinout/svg-object-fns/create-svg-objects-from-pinout-smt-pad.ts
|
|
3540
|
+
import { applyToPoint as applyToPoint32 } from "transformation-matrix";
|
|
3541
|
+
var PAD_COLOR4 = "rgb(218, 165, 32)";
|
|
3542
|
+
function createSvgObjectsFromPinoutSmtPad(pad, ctx) {
|
|
3543
|
+
const { transform } = ctx;
|
|
3544
|
+
if (pad.shape === "rect" || pad.shape === "rotated_rect") {
|
|
3545
|
+
const width = pad.width * Math.abs(transform.a);
|
|
3546
|
+
const height = pad.height * Math.abs(transform.d);
|
|
3547
|
+
const [x, y] = applyToPoint32(transform, [pad.x, pad.y]);
|
|
3548
|
+
if (pad.shape === "rotated_rect" && pad.ccw_rotation) {
|
|
3549
|
+
return [
|
|
3550
|
+
{
|
|
3551
|
+
name: "rect",
|
|
3552
|
+
type: "element",
|
|
3553
|
+
attributes: {
|
|
3554
|
+
class: "pinout-pad",
|
|
3555
|
+
fill: PAD_COLOR4,
|
|
3556
|
+
x: (-width / 2).toString(),
|
|
3557
|
+
y: (-height / 2).toString(),
|
|
3558
|
+
width: width.toString(),
|
|
3559
|
+
height: height.toString(),
|
|
3560
|
+
transform: `translate(${x} ${y}) rotate(${-pad.ccw_rotation})`,
|
|
3561
|
+
"data-layer": pad.layer
|
|
3562
|
+
},
|
|
3563
|
+
value: "",
|
|
3564
|
+
children: []
|
|
3565
|
+
}
|
|
3566
|
+
];
|
|
3567
|
+
}
|
|
3568
|
+
return [
|
|
3569
|
+
{
|
|
3570
|
+
name: "rect",
|
|
3571
|
+
type: "element",
|
|
3572
|
+
attributes: {
|
|
3573
|
+
class: "pinout-pad",
|
|
3574
|
+
fill: PAD_COLOR4,
|
|
3575
|
+
x: (x - width / 2).toString(),
|
|
3576
|
+
y: (y - height / 2).toString(),
|
|
3577
|
+
width: width.toString(),
|
|
3578
|
+
height: height.toString(),
|
|
3579
|
+
"data-layer": pad.layer
|
|
3580
|
+
},
|
|
3581
|
+
value: "",
|
|
3582
|
+
children: []
|
|
3583
|
+
}
|
|
3584
|
+
];
|
|
3585
|
+
}
|
|
3586
|
+
if (pad.shape === "pill") {
|
|
3587
|
+
const width = pad.width * Math.abs(transform.a);
|
|
3588
|
+
const height = pad.height * Math.abs(transform.d);
|
|
3589
|
+
const radius = pad.radius * Math.abs(transform.a);
|
|
3590
|
+
const [x, y] = applyToPoint32(transform, [pad.x, pad.y]);
|
|
3591
|
+
return [
|
|
3592
|
+
{
|
|
3593
|
+
name: "rect",
|
|
3594
|
+
type: "element",
|
|
3595
|
+
attributes: {
|
|
3596
|
+
class: "pinout-pad",
|
|
3597
|
+
fill: PAD_COLOR4,
|
|
3598
|
+
x: (x - width / 2).toString(),
|
|
3599
|
+
y: (y - height / 2).toString(),
|
|
3600
|
+
width: width.toString(),
|
|
3601
|
+
height: height.toString(),
|
|
3602
|
+
rx: radius.toString(),
|
|
3603
|
+
ry: radius.toString(),
|
|
3604
|
+
"data-layer": pad.layer
|
|
3605
|
+
},
|
|
3606
|
+
value: "",
|
|
3607
|
+
children: []
|
|
3608
|
+
}
|
|
3609
|
+
];
|
|
3610
|
+
}
|
|
3611
|
+
if (pad.shape === "circle") {
|
|
3612
|
+
const radius = pad.radius * Math.abs(transform.a);
|
|
3613
|
+
const [x, y] = applyToPoint32(transform, [pad.x, pad.y]);
|
|
3614
|
+
return [
|
|
3615
|
+
{
|
|
3616
|
+
name: "circle",
|
|
3617
|
+
type: "element",
|
|
3618
|
+
attributes: {
|
|
3619
|
+
class: "pinout-pad",
|
|
3620
|
+
fill: PAD_COLOR4,
|
|
3621
|
+
cx: x.toString(),
|
|
3622
|
+
cy: y.toString(),
|
|
3623
|
+
r: radius.toString(),
|
|
3624
|
+
"data-layer": pad.layer
|
|
3625
|
+
},
|
|
3626
|
+
value: "",
|
|
3627
|
+
children: []
|
|
3628
|
+
}
|
|
3629
|
+
];
|
|
3630
|
+
}
|
|
3631
|
+
if (pad.shape === "polygon") {
|
|
3632
|
+
const points = (pad.points ?? []).map(
|
|
3633
|
+
(point) => applyToPoint32(transform, [point.x, point.y])
|
|
3634
|
+
);
|
|
3635
|
+
return [
|
|
3636
|
+
{
|
|
3637
|
+
name: "polygon",
|
|
3638
|
+
type: "element",
|
|
3639
|
+
attributes: {
|
|
3640
|
+
class: "pinout-pad",
|
|
3641
|
+
fill: PAD_COLOR4,
|
|
3642
|
+
points: points.map((p) => p.join(",")).join(" "),
|
|
3643
|
+
"data-layer": pad.layer
|
|
3644
|
+
},
|
|
3645
|
+
value: "",
|
|
3646
|
+
children: []
|
|
3647
|
+
}
|
|
3648
|
+
];
|
|
3649
|
+
}
|
|
3650
|
+
return [];
|
|
3651
|
+
}
|
|
3652
|
+
|
|
3653
|
+
// lib/pinout/svg-object-fns/create-svg-objects-from-pinout-port.ts
|
|
3654
|
+
import { applyToPoint as applyToPoint33 } from "transformation-matrix";
|
|
3655
|
+
import { calculateElbow } from "calculate-elbow";
|
|
3656
|
+
var LABEL_COLOR = "rgb(255, 255, 255)";
|
|
3657
|
+
var LABEL_BACKGROUND = "rgb(0, 0, 0)";
|
|
3658
|
+
var LINE_COLOR = "rgba(0, 0, 0, 0.6)";
|
|
3659
|
+
function createSvgObjectsFromPinoutPort(pcb_port, ctx) {
|
|
3660
|
+
const label_info = ctx.label_positions.get(pcb_port.pcb_port_id);
|
|
3661
|
+
if (!label_info) return [];
|
|
3662
|
+
const { text: label, aliases, elbow_end, label_pos, edge } = label_info;
|
|
3663
|
+
const [port_x, port_y] = applyToPoint33(ctx.transform, [pcb_port.x, pcb_port.y]);
|
|
3664
|
+
const start_facing_direction = edge === "left" ? "x-" : edge === "right" ? "x+" : edge === "top" ? "y-" : "y+";
|
|
3665
|
+
const end_facing_direction = edge === "left" ? "x+" : edge === "right" ? "x-" : edge === "top" ? "y+" : "y-";
|
|
3666
|
+
const elbow_path = calculateElbow(
|
|
3667
|
+
{
|
|
3668
|
+
x: port_x,
|
|
3669
|
+
y: port_y,
|
|
3670
|
+
facingDirection: start_facing_direction
|
|
3671
|
+
},
|
|
3672
|
+
{
|
|
3673
|
+
x: elbow_end.x,
|
|
3674
|
+
y: elbow_end.y,
|
|
3675
|
+
facingDirection: end_facing_direction
|
|
3676
|
+
},
|
|
3677
|
+
{}
|
|
3678
|
+
);
|
|
3679
|
+
const line_points = [...elbow_path, label_pos].map((p) => `${p.x},${p.y}`).join(" ");
|
|
3680
|
+
const full_label = [label, ...aliases].join(" | ");
|
|
3681
|
+
const fontSize = 11;
|
|
3682
|
+
const textWidth = full_label.length * fontSize * 0.6;
|
|
3683
|
+
const bgPadding = 5;
|
|
3684
|
+
const rectHeight = fontSize + 2 * bgPadding;
|
|
3685
|
+
const rectWidth = textWidth + 2 * bgPadding;
|
|
3686
|
+
const text_y = label_pos.y;
|
|
3687
|
+
let rectX;
|
|
3688
|
+
let text_x;
|
|
3689
|
+
if (edge === "left") {
|
|
3690
|
+
rectX = label_pos.x - rectWidth;
|
|
3691
|
+
text_x = label_pos.x - rectWidth / 2;
|
|
3692
|
+
} else if (edge === "right") {
|
|
3693
|
+
rectX = label_pos.x;
|
|
3694
|
+
text_x = label_pos.x + rectWidth / 2;
|
|
3695
|
+
} else {
|
|
3696
|
+
rectX = label_pos.x - rectWidth / 2;
|
|
3697
|
+
text_x = label_pos.x;
|
|
3698
|
+
}
|
|
3699
|
+
return [
|
|
3700
|
+
{
|
|
3701
|
+
name: "polyline",
|
|
3702
|
+
type: "element",
|
|
3703
|
+
attributes: {
|
|
3704
|
+
points: line_points,
|
|
3705
|
+
stroke: LINE_COLOR,
|
|
3706
|
+
"stroke-width": "1.5",
|
|
3707
|
+
fill: "none"
|
|
3708
|
+
},
|
|
3709
|
+
children: [],
|
|
3710
|
+
value: ""
|
|
3711
|
+
},
|
|
3712
|
+
{
|
|
3713
|
+
name: "rect",
|
|
3714
|
+
type: "element",
|
|
3715
|
+
attributes: {
|
|
3716
|
+
x: rectX.toString(),
|
|
3717
|
+
y: (text_y - rectHeight / 2).toString(),
|
|
3718
|
+
width: rectWidth.toString(),
|
|
3719
|
+
height: rectHeight.toString(),
|
|
3720
|
+
fill: LABEL_BACKGROUND,
|
|
3721
|
+
rx: "8",
|
|
3722
|
+
// More rounded corners
|
|
3723
|
+
ry: "8",
|
|
3724
|
+
stroke: "none"
|
|
3725
|
+
},
|
|
3726
|
+
children: [],
|
|
3727
|
+
value: ""
|
|
3728
|
+
},
|
|
3729
|
+
{
|
|
3730
|
+
name: "text",
|
|
3731
|
+
type: "element",
|
|
3732
|
+
attributes: {
|
|
3733
|
+
x: text_x.toString(),
|
|
3734
|
+
y: text_y.toString(),
|
|
3735
|
+
fill: LABEL_COLOR,
|
|
3736
|
+
"font-size": `${fontSize}px`,
|
|
3737
|
+
"font-family": "Arial, sans-serif",
|
|
3738
|
+
"font-weight": "bold",
|
|
3739
|
+
"text-anchor": "middle",
|
|
3740
|
+
"dominant-baseline": "middle"
|
|
3741
|
+
},
|
|
3742
|
+
children: [
|
|
3743
|
+
{
|
|
3744
|
+
type: "text",
|
|
3745
|
+
value: full_label,
|
|
3746
|
+
name: "",
|
|
3747
|
+
attributes: {},
|
|
3748
|
+
children: []
|
|
3749
|
+
}
|
|
3750
|
+
],
|
|
3751
|
+
value: ""
|
|
3752
|
+
}
|
|
3753
|
+
];
|
|
3754
|
+
}
|
|
3755
|
+
|
|
3756
|
+
// lib/pinout/calculate-label-positions.ts
|
|
3757
|
+
import { applyToPoint as applyToPoint34 } from "transformation-matrix";
|
|
3758
|
+
|
|
3759
|
+
// lib/pinout/pinout-utils.ts
|
|
3760
|
+
import { su as su6 } from "@tscircuit/circuit-json-util";
|
|
3761
|
+
function getPortLabelInfo(port, soup) {
|
|
3762
|
+
const source_port = su6(soup).source_port.get(port.source_port_id);
|
|
3763
|
+
if (!source_port) return null;
|
|
3764
|
+
const eligible_hints = source_port.port_hints?.filter(
|
|
3765
|
+
(h) => !/^\d+$/.test(h) && !["left", "right", "top", "bottom"].includes(h)
|
|
3766
|
+
) ?? [];
|
|
3767
|
+
let label = eligible_hints[0];
|
|
3768
|
+
if (!label) label = source_port.name;
|
|
3769
|
+
if (!label) return null;
|
|
3770
|
+
const aliases = eligible_hints.filter((h) => h !== label);
|
|
3771
|
+
return { text: label, aliases };
|
|
3772
|
+
}
|
|
3773
|
+
function getClosestEdge(port_pos_real, board_bounds) {
|
|
3774
|
+
const dists = {
|
|
3775
|
+
left: port_pos_real.x - board_bounds.minX,
|
|
3776
|
+
right: board_bounds.maxX - port_pos_real.x,
|
|
3777
|
+
top: board_bounds.maxY - port_pos_real.y,
|
|
3778
|
+
bottom: port_pos_real.y - board_bounds.minY
|
|
3779
|
+
};
|
|
3780
|
+
let closest_edge = "left";
|
|
3781
|
+
let min_dist = dists.left;
|
|
3782
|
+
if (dists.right < min_dist) {
|
|
3783
|
+
min_dist = dists.right;
|
|
3784
|
+
closest_edge = "right";
|
|
3785
|
+
}
|
|
3786
|
+
if (dists.top < min_dist) {
|
|
3787
|
+
min_dist = dists.top;
|
|
3788
|
+
closest_edge = "top";
|
|
3789
|
+
}
|
|
3790
|
+
if (dists.bottom < min_dist) {
|
|
3791
|
+
min_dist = dists.bottom;
|
|
3792
|
+
closest_edge = "bottom";
|
|
3793
|
+
}
|
|
3794
|
+
return closest_edge;
|
|
3795
|
+
}
|
|
3796
|
+
|
|
3797
|
+
// lib/pinout/calculate-label-positions.ts
|
|
3798
|
+
var STAGGER_OFFSET_MIN = 20;
|
|
3799
|
+
var STAGGER_OFFSET_PER_PIN = 2;
|
|
3800
|
+
var STAGGER_OFFSET_STEP = 15;
|
|
3801
|
+
var ALIGNED_OFFSET_MARGIN = 10;
|
|
3802
|
+
var FONT_SIZE = 11;
|
|
3803
|
+
var BG_PADDING = 5;
|
|
3804
|
+
var LABEL_RECT_HEIGHT = FONT_SIZE + 2 * BG_PADDING;
|
|
3805
|
+
var LABEL_MARGIN = 5;
|
|
3806
|
+
function calculateVerticalEdgeLabels(edge, ports, {
|
|
3807
|
+
transform,
|
|
3808
|
+
soup,
|
|
3809
|
+
board_bounds,
|
|
3810
|
+
svgHeight
|
|
3811
|
+
}, label_positions) {
|
|
3812
|
+
const edge_ports = ports.map((port) => ({
|
|
3813
|
+
port,
|
|
3814
|
+
y: applyToPoint34(transform, [port.x, port.y])[1],
|
|
3815
|
+
label_info: getPortLabelInfo(port, soup)
|
|
3816
|
+
})).filter((p) => p.label_info).sort((a, b) => a.y - b.y);
|
|
3817
|
+
if (edge_ports.length === 0) return;
|
|
3818
|
+
const board_edge_x = applyToPoint34(transform, [
|
|
3819
|
+
edge === "left" ? board_bounds.minX : board_bounds.maxX,
|
|
3820
|
+
0
|
|
3821
|
+
])[0];
|
|
3822
|
+
const num_labels = edge_ports.length;
|
|
3823
|
+
const middle_index = (num_labels - 1) / 2;
|
|
3824
|
+
const stagger_offset_base = STAGGER_OFFSET_MIN + num_labels * STAGGER_OFFSET_PER_PIN;
|
|
3825
|
+
const max_stagger_offset = stagger_offset_base + middle_index * STAGGER_OFFSET_STEP;
|
|
3826
|
+
const aligned_label_offset = max_stagger_offset + ALIGNED_OFFSET_MARGIN;
|
|
3827
|
+
const total_labels_height = num_labels * LABEL_RECT_HEIGHT + Math.max(0, num_labels - 1) * LABEL_MARGIN;
|
|
3828
|
+
let current_y = (svgHeight - total_labels_height) / 2 + LABEL_RECT_HEIGHT / 2;
|
|
3829
|
+
edge_ports.forEach(({ port, label_info }, i) => {
|
|
3830
|
+
const dist_from_middle = Math.abs(i - middle_index);
|
|
3831
|
+
const stagger_rank = middle_index - dist_from_middle;
|
|
3832
|
+
const stagger_offset = stagger_offset_base + stagger_rank * STAGGER_OFFSET_STEP;
|
|
3833
|
+
const sign = edge === "left" ? -1 : 1;
|
|
3834
|
+
const elbow_end = {
|
|
3835
|
+
x: board_edge_x + sign * stagger_offset,
|
|
3836
|
+
y: current_y
|
|
3837
|
+
};
|
|
3838
|
+
const label_pos = {
|
|
3839
|
+
x: board_edge_x + sign * aligned_label_offset,
|
|
3840
|
+
y: current_y
|
|
3841
|
+
};
|
|
3842
|
+
label_positions.set(port.pcb_port_id, {
|
|
3843
|
+
text: label_info.text,
|
|
3844
|
+
aliases: label_info.aliases,
|
|
3845
|
+
elbow_end,
|
|
3846
|
+
label_pos,
|
|
3847
|
+
edge
|
|
3848
|
+
});
|
|
3849
|
+
current_y += LABEL_RECT_HEIGHT + LABEL_MARGIN;
|
|
3850
|
+
});
|
|
3851
|
+
}
|
|
3852
|
+
function calculateHorizontalEdgeLabels(edge, ports, {
|
|
3853
|
+
transform,
|
|
3854
|
+
soup,
|
|
3855
|
+
board_bounds,
|
|
3856
|
+
svgWidth
|
|
3857
|
+
}, label_positions) {
|
|
3858
|
+
const edge_ports = ports.map((port) => ({
|
|
3859
|
+
port,
|
|
3860
|
+
x: applyToPoint34(transform, [port.x, port.y])[0],
|
|
3861
|
+
label_info: getPortLabelInfo(port, soup)
|
|
3862
|
+
})).filter((p) => p.label_info).sort((a, b) => a.x - b.x);
|
|
3863
|
+
if (edge_ports.length === 0) return;
|
|
3864
|
+
const board_edge_y = applyToPoint34(transform, [
|
|
3865
|
+
0,
|
|
3866
|
+
edge === "top" ? board_bounds.maxY : board_bounds.minY
|
|
3867
|
+
])[1];
|
|
3868
|
+
const labels_with_widths = edge_ports.map((p) => {
|
|
3869
|
+
const label = [p.label_info.text, ...p.label_info.aliases].join(" | ");
|
|
3870
|
+
const textWidth = label.length * FONT_SIZE * 0.6;
|
|
3871
|
+
const rectWidth = textWidth + 2 * BG_PADDING;
|
|
3872
|
+
return { ...p, rectWidth };
|
|
3873
|
+
});
|
|
3874
|
+
const num_labels = labels_with_widths.length;
|
|
3875
|
+
const middle_index = (num_labels - 1) / 2;
|
|
3876
|
+
const stagger_offset_base = STAGGER_OFFSET_MIN + num_labels * STAGGER_OFFSET_PER_PIN;
|
|
3877
|
+
const max_stagger_offset = stagger_offset_base + middle_index * STAGGER_OFFSET_STEP;
|
|
3878
|
+
const aligned_label_offset = max_stagger_offset + ALIGNED_OFFSET_MARGIN;
|
|
3879
|
+
const total_labels_width = labels_with_widths.reduce((sum, l) => sum + l.rectWidth, 0) + Math.max(0, num_labels - 1) * LABEL_MARGIN;
|
|
3880
|
+
let current_x = (svgWidth - total_labels_width) / 2;
|
|
3881
|
+
labels_with_widths.forEach(({ port, label_info, rectWidth }, i) => {
|
|
3882
|
+
const dist_from_middle = Math.abs(i - middle_index);
|
|
3883
|
+
const stagger_rank = middle_index - dist_from_middle;
|
|
3884
|
+
const stagger_offset = stagger_offset_base + stagger_rank * STAGGER_OFFSET_STEP;
|
|
3885
|
+
const sign = edge === "top" ? -1 : 1;
|
|
3886
|
+
const label_center_x = current_x + rectWidth / 2;
|
|
3887
|
+
const elbow_end = {
|
|
3888
|
+
x: label_center_x,
|
|
3889
|
+
y: board_edge_y + sign * stagger_offset
|
|
3890
|
+
};
|
|
3891
|
+
const label_pos = {
|
|
3892
|
+
x: label_center_x,
|
|
3893
|
+
y: board_edge_y + sign * aligned_label_offset
|
|
3894
|
+
};
|
|
3895
|
+
label_positions.set(port.pcb_port_id, {
|
|
3896
|
+
text: label_info.text,
|
|
3897
|
+
aliases: label_info.aliases,
|
|
3898
|
+
elbow_end,
|
|
3899
|
+
label_pos,
|
|
3900
|
+
edge
|
|
3901
|
+
});
|
|
3902
|
+
current_x += rectWidth + LABEL_MARGIN;
|
|
3903
|
+
});
|
|
3904
|
+
}
|
|
3905
|
+
var calculateLabelPositions = ({
|
|
3906
|
+
ports_by_edge,
|
|
3907
|
+
transform,
|
|
3908
|
+
soup,
|
|
3909
|
+
board_bounds,
|
|
3910
|
+
svgWidth,
|
|
3911
|
+
svgHeight
|
|
3912
|
+
}) => {
|
|
3913
|
+
const label_positions = /* @__PURE__ */ new Map();
|
|
3914
|
+
const shared_params = { transform, soup, board_bounds };
|
|
3915
|
+
calculateVerticalEdgeLabels(
|
|
3916
|
+
"left",
|
|
3917
|
+
ports_by_edge.left,
|
|
3918
|
+
{
|
|
3919
|
+
...shared_params,
|
|
3920
|
+
svgHeight
|
|
3921
|
+
},
|
|
3922
|
+
label_positions
|
|
3923
|
+
);
|
|
3924
|
+
calculateVerticalEdgeLabels(
|
|
3925
|
+
"right",
|
|
3926
|
+
ports_by_edge.right,
|
|
3927
|
+
{
|
|
3928
|
+
...shared_params,
|
|
3929
|
+
svgHeight
|
|
3930
|
+
},
|
|
3931
|
+
label_positions
|
|
3932
|
+
);
|
|
3933
|
+
calculateHorizontalEdgeLabels(
|
|
3934
|
+
"top",
|
|
3935
|
+
ports_by_edge.top,
|
|
3936
|
+
{
|
|
3937
|
+
...shared_params,
|
|
3938
|
+
svgWidth
|
|
3939
|
+
},
|
|
3940
|
+
label_positions
|
|
3941
|
+
);
|
|
3942
|
+
calculateHorizontalEdgeLabels(
|
|
3943
|
+
"bottom",
|
|
3944
|
+
ports_by_edge.bottom,
|
|
3945
|
+
{
|
|
3946
|
+
...shared_params,
|
|
3947
|
+
svgWidth
|
|
3948
|
+
},
|
|
3949
|
+
label_positions
|
|
3950
|
+
);
|
|
3951
|
+
return label_positions;
|
|
3952
|
+
};
|
|
3953
|
+
|
|
3954
|
+
// lib/pinout/convert-circuit-json-to-pinout-svg.ts
|
|
3955
|
+
var OBJECT_ORDER3 = [
|
|
3956
|
+
"pcb_board",
|
|
3957
|
+
"pcb_smtpad",
|
|
3958
|
+
"pcb_hole",
|
|
3959
|
+
"pcb_plated_hole",
|
|
3960
|
+
"pcb_component",
|
|
3961
|
+
"pcb_port"
|
|
3962
|
+
];
|
|
3963
|
+
function convertCircuitJsonToPinoutSvg(soup, options) {
|
|
3964
|
+
let minX = Number.POSITIVE_INFINITY;
|
|
3965
|
+
let minY = Number.POSITIVE_INFINITY;
|
|
3966
|
+
let maxX = Number.NEGATIVE_INFINITY;
|
|
3967
|
+
let maxY = Number.NEGATIVE_INFINITY;
|
|
3968
|
+
for (const item of soup) {
|
|
3969
|
+
if (item.type === "pcb_board") {
|
|
3970
|
+
if ("outline" in item && item.outline && Array.isArray(item.outline) && item.outline.length > 0) {
|
|
3971
|
+
for (const point of item.outline) {
|
|
3972
|
+
minX = Math.min(minX, point.x);
|
|
3973
|
+
minY = Math.min(minY, point.y);
|
|
3974
|
+
maxX = Math.max(maxX, point.x);
|
|
3975
|
+
maxY = Math.max(maxY, point.y);
|
|
3976
|
+
}
|
|
3977
|
+
} else {
|
|
3978
|
+
const center = item.center;
|
|
3979
|
+
const width = item.width || 0;
|
|
3980
|
+
const height = item.height || 0;
|
|
3981
|
+
minX = Math.min(minX, center.x - width / 2);
|
|
3982
|
+
minY = Math.min(minY, center.y - height / 2);
|
|
3983
|
+
maxX = Math.max(maxX, center.x + width / 2);
|
|
3984
|
+
maxY = Math.max(maxY, center.y + height / 2);
|
|
3985
|
+
}
|
|
3986
|
+
}
|
|
3987
|
+
}
|
|
3988
|
+
const padding = 20;
|
|
3989
|
+
const circuitWidth = maxX - minX + 2 * padding;
|
|
3990
|
+
const circuitHeight = maxY - minY + 2 * padding;
|
|
3991
|
+
const svgWidth = options?.width ?? 800;
|
|
3992
|
+
const svgHeight = options?.height ?? 600;
|
|
3993
|
+
const scaleX = svgWidth / circuitWidth;
|
|
3994
|
+
const scaleY = svgHeight / circuitHeight;
|
|
3995
|
+
const scaleFactor = Math.min(scaleX, scaleY);
|
|
3996
|
+
const offsetX = (svgWidth - circuitWidth * scaleFactor) / 2;
|
|
3997
|
+
const offsetY = (svgHeight - circuitHeight * scaleFactor) / 2;
|
|
3998
|
+
const transform = compose7(
|
|
3999
|
+
translate7(
|
|
4000
|
+
offsetX - minX * scaleFactor + padding * scaleFactor,
|
|
4001
|
+
svgHeight - offsetY + minY * scaleFactor - padding * scaleFactor
|
|
4002
|
+
),
|
|
4003
|
+
scale4(scaleFactor, -scaleFactor)
|
|
4004
|
+
);
|
|
4005
|
+
const board_bounds = { minX, minY, maxX, maxY };
|
|
4006
|
+
const pinout_ports = soup.filter(
|
|
4007
|
+
(elm) => elm.type === "pcb_port" && elm.is_board_pinout
|
|
4008
|
+
);
|
|
4009
|
+
const ports_by_edge = {
|
|
4010
|
+
left: [],
|
|
4011
|
+
right: [],
|
|
4012
|
+
top: [],
|
|
4013
|
+
bottom: []
|
|
4014
|
+
};
|
|
4015
|
+
for (const port of pinout_ports) {
|
|
4016
|
+
const edge = getClosestEdge({ x: port.x, y: port.y }, board_bounds);
|
|
4017
|
+
ports_by_edge[edge].push(port);
|
|
4018
|
+
}
|
|
4019
|
+
const label_positions = calculateLabelPositions({
|
|
4020
|
+
ports_by_edge,
|
|
4021
|
+
transform,
|
|
4022
|
+
soup,
|
|
4023
|
+
board_bounds,
|
|
4024
|
+
svgWidth,
|
|
4025
|
+
svgHeight
|
|
4026
|
+
});
|
|
4027
|
+
const ctx = {
|
|
4028
|
+
transform,
|
|
4029
|
+
soup,
|
|
4030
|
+
board_bounds,
|
|
4031
|
+
label_positions
|
|
4032
|
+
};
|
|
4033
|
+
const svgObjects = soup.sort(
|
|
4034
|
+
(a, b) => (OBJECT_ORDER3.indexOf(a.type) ?? 9999) - (OBJECT_ORDER3.indexOf(b.type) ?? 9999)
|
|
4035
|
+
).flatMap((item) => createSvgObjects3(item, ctx, soup));
|
|
4036
|
+
const softwareUsedString = getSoftwareUsedString(soup);
|
|
4037
|
+
const version = CIRCUIT_TO_SVG_VERSION;
|
|
4038
|
+
const svgObject = {
|
|
4039
|
+
name: "svg",
|
|
4040
|
+
type: "element",
|
|
4041
|
+
attributes: {
|
|
4042
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
4043
|
+
width: svgWidth.toString(),
|
|
4044
|
+
height: svgHeight.toString(),
|
|
4045
|
+
...softwareUsedString && {
|
|
4046
|
+
"data-software-used-string": softwareUsedString
|
|
4047
|
+
},
|
|
4048
|
+
...options?.includeVersion && {
|
|
4049
|
+
"data-circuit-to-svg-version": version
|
|
4050
|
+
}
|
|
4051
|
+
},
|
|
4052
|
+
value: "",
|
|
4053
|
+
children: [
|
|
4054
|
+
{
|
|
4055
|
+
name: "rect",
|
|
4056
|
+
type: "element",
|
|
4057
|
+
attributes: {
|
|
4058
|
+
fill: "rgb(255, 255, 255)",
|
|
4059
|
+
x: "0",
|
|
4060
|
+
y: "0",
|
|
4061
|
+
width: svgWidth.toString(),
|
|
4062
|
+
height: svgHeight.toString()
|
|
4063
|
+
},
|
|
4064
|
+
value: "",
|
|
4065
|
+
children: []
|
|
4066
|
+
},
|
|
4067
|
+
...svgObjects
|
|
4068
|
+
].filter((child) => child !== null)
|
|
4069
|
+
};
|
|
4070
|
+
return stringify3(svgObject);
|
|
4071
|
+
}
|
|
4072
|
+
function createSvgObjects3(elm, ctx, soup) {
|
|
4073
|
+
switch (elm.type) {
|
|
4074
|
+
case "pcb_board":
|
|
4075
|
+
return createSvgObjectsFromPinoutBoard(elm, ctx);
|
|
4076
|
+
case "pcb_component":
|
|
4077
|
+
return createSvgObjectsFromPinoutComponent(elm, ctx);
|
|
4078
|
+
case "pcb_smtpad":
|
|
4079
|
+
return createSvgObjectsFromPinoutSmtPad(elm, ctx);
|
|
4080
|
+
case "pcb_hole":
|
|
4081
|
+
return createSvgObjectsFromPinoutHole(elm, ctx);
|
|
4082
|
+
case "pcb_plated_hole":
|
|
4083
|
+
return createSvgObjectsFromPinoutPlatedHole(elm, ctx);
|
|
4084
|
+
case "pcb_port":
|
|
4085
|
+
if (elm.is_board_pinout) {
|
|
4086
|
+
return createSvgObjectsFromPinoutPort(elm, ctx);
|
|
4087
|
+
}
|
|
4088
|
+
return [];
|
|
4089
|
+
default:
|
|
4090
|
+
return [];
|
|
4091
|
+
}
|
|
4092
|
+
}
|
|
4093
|
+
|
|
3073
4094
|
// lib/utils/colors.ts
|
|
3074
4095
|
var colorMap = {
|
|
3075
4096
|
"3d_viewer": {
|
|
@@ -3310,21 +4331,21 @@ var colorMap = {
|
|
|
3310
4331
|
};
|
|
3311
4332
|
|
|
3312
4333
|
// lib/sch/convert-circuit-json-to-schematic-svg.ts
|
|
3313
|
-
import { stringify as
|
|
4334
|
+
import { stringify as stringify4 } from "svgson";
|
|
3314
4335
|
import {
|
|
3315
4336
|
fromTriangles,
|
|
3316
4337
|
toSVG
|
|
3317
4338
|
} from "transformation-matrix";
|
|
3318
4339
|
|
|
3319
4340
|
// lib/sch/draw-schematic-grid.ts
|
|
3320
|
-
import { applyToPoint as
|
|
4341
|
+
import { applyToPoint as applyToPoint36 } from "transformation-matrix";
|
|
3321
4342
|
function drawSchematicGrid(params) {
|
|
3322
4343
|
const { minX, minY, maxX, maxY } = params.bounds;
|
|
3323
4344
|
const cellSize = params.cellSize ?? 1;
|
|
3324
4345
|
const labelCells = params.labelCells ?? false;
|
|
3325
4346
|
const gridLines = [];
|
|
3326
4347
|
const transformPoint = (x, y) => {
|
|
3327
|
-
const [transformedX, transformedY] =
|
|
4348
|
+
const [transformedX, transformedY] = applyToPoint36(params.transform, [x, y]);
|
|
3328
4349
|
return { x: transformedX, y: transformedY };
|
|
3329
4350
|
};
|
|
3330
4351
|
for (let x = Math.floor(minX); x <= Math.ceil(maxX); x += cellSize) {
|
|
@@ -3405,15 +4426,15 @@ function drawSchematicGrid(params) {
|
|
|
3405
4426
|
}
|
|
3406
4427
|
|
|
3407
4428
|
// lib/sch/draw-schematic-labeled-points.ts
|
|
3408
|
-
import { applyToPoint as
|
|
4429
|
+
import { applyToPoint as applyToPoint37 } from "transformation-matrix";
|
|
3409
4430
|
function drawSchematicLabeledPoints(params) {
|
|
3410
4431
|
const { points, transform } = params;
|
|
3411
4432
|
const labeledPointsGroup = [];
|
|
3412
4433
|
for (const point of points) {
|
|
3413
|
-
const [x1, y1] =
|
|
3414
|
-
const [x2, y2] =
|
|
3415
|
-
const [x3, y3] =
|
|
3416
|
-
const [x4, y4] =
|
|
4434
|
+
const [x1, y1] = applyToPoint37(transform, [point.x - 0.1, point.y - 0.1]);
|
|
4435
|
+
const [x2, y2] = applyToPoint37(transform, [point.x + 0.1, point.y + 0.1]);
|
|
4436
|
+
const [x3, y3] = applyToPoint37(transform, [point.x - 0.1, point.y + 0.1]);
|
|
4437
|
+
const [x4, y4] = applyToPoint37(transform, [point.x + 0.1, point.y - 0.1]);
|
|
3417
4438
|
labeledPointsGroup.push({
|
|
3418
4439
|
name: "path",
|
|
3419
4440
|
type: "element",
|
|
@@ -3424,7 +4445,7 @@ function drawSchematicLabeledPoints(params) {
|
|
|
3424
4445
|
"stroke-opacity": "0.7"
|
|
3425
4446
|
}
|
|
3426
4447
|
});
|
|
3427
|
-
const [labelX, labelY] =
|
|
4448
|
+
const [labelX, labelY] = applyToPoint37(transform, [
|
|
3428
4449
|
point.x + 0.15,
|
|
3429
4450
|
point.y - 0.15
|
|
3430
4451
|
]);
|
|
@@ -4514,12 +5535,12 @@ function getSchematicBoundsFromCircuitJson(soup, padding = 0.5) {
|
|
|
4514
5535
|
}
|
|
4515
5536
|
|
|
4516
5537
|
// lib/sch/svg-object-fns/create-svg-objects-from-sch-component-with-symbol.ts
|
|
4517
|
-
import { su as
|
|
5538
|
+
import { su as su8 } from "@tscircuit/circuit-json-util";
|
|
4518
5539
|
import { symbols } from "schematic-symbols";
|
|
4519
5540
|
import "svgson";
|
|
4520
5541
|
import {
|
|
4521
|
-
applyToPoint as
|
|
4522
|
-
compose as
|
|
5542
|
+
applyToPoint as applyToPoint39,
|
|
5543
|
+
compose as compose9
|
|
4523
5544
|
} from "transformation-matrix";
|
|
4524
5545
|
|
|
4525
5546
|
// lib/utils/get-sch-stroke-size.ts
|
|
@@ -4589,26 +5610,26 @@ var matchSchPortsToSymbolPorts = ({
|
|
|
4589
5610
|
};
|
|
4590
5611
|
|
|
4591
5612
|
// lib/utils/point-pairs-to-matrix.ts
|
|
4592
|
-
import { compose as
|
|
5613
|
+
import { compose as compose8, scale as scale5, translate as translate8 } from "transformation-matrix";
|
|
4593
5614
|
function pointPairsToMatrix(a1, a2, b1, b2) {
|
|
4594
5615
|
const tx = a2.x - a1.x;
|
|
4595
5616
|
const ty = a2.y - a1.y;
|
|
4596
5617
|
const originalDistance = Math.sqrt((b1.x - a1.x) ** 2 + (b1.y - a1.y) ** 2);
|
|
4597
5618
|
const transformedDistance = Math.sqrt((b2.x - a2.x) ** 2 + (b2.y - a2.y) ** 2);
|
|
4598
5619
|
const a = transformedDistance / originalDistance;
|
|
4599
|
-
const translateMatrix =
|
|
4600
|
-
const scaleMatrix =
|
|
4601
|
-
return
|
|
5620
|
+
const translateMatrix = translate8(tx, ty);
|
|
5621
|
+
const scaleMatrix = scale5(a, a);
|
|
5622
|
+
return compose8(translateMatrix, scaleMatrix);
|
|
4602
5623
|
}
|
|
4603
5624
|
|
|
4604
5625
|
// lib/sch/svg-object-fns/create-svg-error-text.ts
|
|
4605
|
-
import { applyToPoint as
|
|
5626
|
+
import { applyToPoint as applyToPoint38 } from "transformation-matrix";
|
|
4606
5627
|
var createSvgSchErrorText = ({
|
|
4607
5628
|
text,
|
|
4608
5629
|
realCenter,
|
|
4609
5630
|
realToScreenTransform
|
|
4610
5631
|
}) => {
|
|
4611
|
-
const screenCenter =
|
|
5632
|
+
const screenCenter = applyToPoint38(realToScreenTransform, realCenter);
|
|
4612
5633
|
return {
|
|
4613
5634
|
type: "element",
|
|
4614
5635
|
name: "text",
|
|
@@ -4675,10 +5696,10 @@ var createSvgObjectsFromSchematicComponentWithSymbol = ({
|
|
|
4675
5696
|
})
|
|
4676
5697
|
];
|
|
4677
5698
|
}
|
|
4678
|
-
const schPorts =
|
|
5699
|
+
const schPorts = su8(circuitJson).schematic_port.list({
|
|
4679
5700
|
schematic_component_id: schComponent.schematic_component_id
|
|
4680
5701
|
});
|
|
4681
|
-
const srcComponent =
|
|
5702
|
+
const srcComponent = su8(circuitJson).source_component.get(
|
|
4682
5703
|
schComponent.source_component_id
|
|
4683
5704
|
);
|
|
4684
5705
|
const schPortsWithSymbolPorts = matchSchPortsToSymbolPorts({
|
|
@@ -4717,12 +5738,12 @@ var createSvgObjectsFromSchematicComponentWithSymbol = ({
|
|
|
4717
5738
|
minY: Math.min(...paths.flatMap((p) => p.points.map((pt) => pt.y))),
|
|
4718
5739
|
maxY: Math.max(...paths.flatMap((p) => p.points.map((pt) => pt.y)))
|
|
4719
5740
|
};
|
|
4720
|
-
const [screenMinX, screenMinY] =
|
|
4721
|
-
|
|
5741
|
+
const [screenMinX, screenMinY] = applyToPoint39(
|
|
5742
|
+
compose9(realToScreenTransform, transformFromSymbolToReal),
|
|
4722
5743
|
[bounds.minX, bounds.minY]
|
|
4723
5744
|
);
|
|
4724
|
-
const [screenMaxX, screenMaxY] =
|
|
4725
|
-
|
|
5745
|
+
const [screenMaxX, screenMaxY] = applyToPoint39(
|
|
5746
|
+
compose9(realToScreenTransform, transformFromSymbolToReal),
|
|
4726
5747
|
[bounds.maxX, bounds.maxY]
|
|
4727
5748
|
);
|
|
4728
5749
|
const rectHeight = Math.abs(screenMaxY - screenMinY);
|
|
@@ -4750,8 +5771,8 @@ var createSvgObjectsFromSchematicComponentWithSymbol = ({
|
|
|
4750
5771
|
name: "path",
|
|
4751
5772
|
attributes: {
|
|
4752
5773
|
d: points.map((p, i) => {
|
|
4753
|
-
const [x, y] =
|
|
4754
|
-
|
|
5774
|
+
const [x, y] = applyToPoint39(
|
|
5775
|
+
compose9(realToScreenTransform, transformFromSymbolToReal),
|
|
4755
5776
|
[p.x, p.y]
|
|
4756
5777
|
);
|
|
4757
5778
|
return `${i === 0 ? "M" : "L"} ${x} ${y}`;
|
|
@@ -4766,8 +5787,8 @@ var createSvgObjectsFromSchematicComponentWithSymbol = ({
|
|
|
4766
5787
|
});
|
|
4767
5788
|
}
|
|
4768
5789
|
for (const text of texts) {
|
|
4769
|
-
const screenTextPos =
|
|
4770
|
-
|
|
5790
|
+
const screenTextPos = applyToPoint39(
|
|
5791
|
+
compose9(realToScreenTransform, transformFromSymbolToReal),
|
|
4771
5792
|
text
|
|
4772
5793
|
);
|
|
4773
5794
|
let textValue = "";
|
|
@@ -4818,11 +5839,11 @@ var createSvgObjectsFromSchematicComponentWithSymbol = ({
|
|
|
4818
5839
|
});
|
|
4819
5840
|
}
|
|
4820
5841
|
for (const box of boxes) {
|
|
4821
|
-
const screenBoxPos =
|
|
4822
|
-
|
|
5842
|
+
const screenBoxPos = applyToPoint39(
|
|
5843
|
+
compose9(realToScreenTransform, transformFromSymbolToReal),
|
|
4823
5844
|
box
|
|
4824
5845
|
);
|
|
4825
|
-
const symbolToScreenScale =
|
|
5846
|
+
const symbolToScreenScale = compose9(
|
|
4826
5847
|
realToScreenTransform,
|
|
4827
5848
|
transformFromSymbolToReal
|
|
4828
5849
|
).a;
|
|
@@ -4842,8 +5863,8 @@ var createSvgObjectsFromSchematicComponentWithSymbol = ({
|
|
|
4842
5863
|
}
|
|
4843
5864
|
for (const port of symbol.ports) {
|
|
4844
5865
|
if (connectedSymbolPorts.has(port)) continue;
|
|
4845
|
-
const screenPortPos =
|
|
4846
|
-
|
|
5866
|
+
const screenPortPos = applyToPoint39(
|
|
5867
|
+
compose9(realToScreenTransform, transformFromSymbolToReal),
|
|
4847
5868
|
port
|
|
4848
5869
|
);
|
|
4849
5870
|
svgObjects.push({
|
|
@@ -4862,8 +5883,8 @@ var createSvgObjectsFromSchematicComponentWithSymbol = ({
|
|
|
4862
5883
|
});
|
|
4863
5884
|
}
|
|
4864
5885
|
for (const circle of circles) {
|
|
4865
|
-
const screenCirclePos =
|
|
4866
|
-
|
|
5886
|
+
const screenCirclePos = applyToPoint39(
|
|
5887
|
+
compose9(realToScreenTransform, transformFromSymbolToReal),
|
|
4867
5888
|
circle
|
|
4868
5889
|
);
|
|
4869
5890
|
const screenRadius = Math.abs(circle.radius * realToScreenTransform.a);
|
|
@@ -4886,18 +5907,18 @@ var createSvgObjectsFromSchematicComponentWithSymbol = ({
|
|
|
4886
5907
|
};
|
|
4887
5908
|
|
|
4888
5909
|
// lib/sch/svg-object-fns/create-svg-objects-from-sch-component-with-box.ts
|
|
4889
|
-
import { su as
|
|
5910
|
+
import { su as su11 } from "@tscircuit/circuit-json-util";
|
|
4890
5911
|
import "schematic-symbols";
|
|
4891
5912
|
import "svgson";
|
|
4892
|
-
import { applyToPoint as
|
|
5913
|
+
import { applyToPoint as applyToPoint45 } from "transformation-matrix";
|
|
4893
5914
|
|
|
4894
5915
|
// lib/sch/svg-object-fns/create-svg-objects-from-sch-port-on-box.ts
|
|
4895
5916
|
import "transformation-matrix";
|
|
4896
5917
|
import "@tscircuit/circuit-json-util";
|
|
4897
5918
|
|
|
4898
5919
|
// lib/sch/svg-object-fns/create-svg-objects-for-sch-port-box-line.ts
|
|
4899
|
-
import { applyToPoint as
|
|
4900
|
-
import { su as
|
|
5920
|
+
import { applyToPoint as applyToPoint40 } from "transformation-matrix";
|
|
5921
|
+
import { su as su9 } from "@tscircuit/circuit-json-util";
|
|
4901
5922
|
var PIN_CIRCLE_RADIUS_MM = 0.02;
|
|
4902
5923
|
var createArrow = (tip, angle, size, color, strokeWidth) => {
|
|
4903
5924
|
const arrowAngle = Math.PI / 6;
|
|
@@ -4929,7 +5950,7 @@ var createSvgObjectsForSchPortBoxLine = ({
|
|
|
4929
5950
|
circuitJson
|
|
4930
5951
|
}) => {
|
|
4931
5952
|
const svgObjects = [];
|
|
4932
|
-
const srcPort =
|
|
5953
|
+
const srcPort = su9(circuitJson).source_port.get(schPort.source_port_id);
|
|
4933
5954
|
const realEdgePos = {
|
|
4934
5955
|
x: schPort.center.x,
|
|
4935
5956
|
y: schPort.center.y
|
|
@@ -4949,8 +5970,8 @@ var createSvgObjectsForSchPortBoxLine = ({
|
|
|
4949
5970
|
realEdgePos.y += realPinLineLength;
|
|
4950
5971
|
break;
|
|
4951
5972
|
}
|
|
4952
|
-
const screenSchPortPos =
|
|
4953
|
-
const screenRealEdgePos =
|
|
5973
|
+
const screenSchPortPos = applyToPoint40(transform, schPort.center);
|
|
5974
|
+
const screenRealEdgePos = applyToPoint40(transform, realEdgePos);
|
|
4954
5975
|
const realLineEnd = { ...schPort.center };
|
|
4955
5976
|
switch (schPort.side_of_component) {
|
|
4956
5977
|
case "left":
|
|
@@ -4966,7 +5987,7 @@ var createSvgObjectsForSchPortBoxLine = ({
|
|
|
4966
5987
|
realLineEnd.y += PIN_CIRCLE_RADIUS_MM;
|
|
4967
5988
|
break;
|
|
4968
5989
|
}
|
|
4969
|
-
const screenLineEnd =
|
|
5990
|
+
const screenLineEnd = applyToPoint40(transform, realLineEnd);
|
|
4970
5991
|
svgObjects.push({
|
|
4971
5992
|
name: "line",
|
|
4972
5993
|
type: "element",
|
|
@@ -5088,7 +6109,7 @@ var createSvgObjectsForSchPortBoxLine = ({
|
|
|
5088
6109
|
};
|
|
5089
6110
|
|
|
5090
6111
|
// lib/sch/svg-object-fns/create-svg-objects-for-sch-port-pin-number-text.ts
|
|
5091
|
-
import { applyToPoint as
|
|
6112
|
+
import { applyToPoint as applyToPoint41 } from "transformation-matrix";
|
|
5092
6113
|
var createSvgObjectsForSchPortPinNumberText = (params) => {
|
|
5093
6114
|
const svgObjects = [];
|
|
5094
6115
|
const { schPort, schComponent, transform, circuitJson } = params;
|
|
@@ -5106,7 +6127,7 @@ var createSvgObjectsForSchPortPinNumberText = (params) => {
|
|
|
5106
6127
|
} else {
|
|
5107
6128
|
realPinNumberPos.y += 0.02;
|
|
5108
6129
|
}
|
|
5109
|
-
const screenPinNumberTextPos =
|
|
6130
|
+
const screenPinNumberTextPos = applyToPoint41(transform, realPinNumberPos);
|
|
5110
6131
|
svgObjects.push({
|
|
5111
6132
|
name: "text",
|
|
5112
6133
|
type: "element",
|
|
@@ -5136,7 +6157,7 @@ var createSvgObjectsForSchPortPinNumberText = (params) => {
|
|
|
5136
6157
|
};
|
|
5137
6158
|
|
|
5138
6159
|
// lib/sch/svg-object-fns/create-svg-objects-for-sch-port-pin-label.ts
|
|
5139
|
-
import { applyToPoint as
|
|
6160
|
+
import { applyToPoint as applyToPoint42 } from "transformation-matrix";
|
|
5140
6161
|
var LABEL_DIST_FROM_EDGE_MM = 0.1;
|
|
5141
6162
|
var createSvgObjectsForSchPortPinLabel = (params) => {
|
|
5142
6163
|
const svgObjects = [];
|
|
@@ -5150,7 +6171,7 @@ var createSvgObjectsForSchPortPinLabel = (params) => {
|
|
|
5150
6171
|
const realPinEdgeDistance = schPort.distance_from_component_edge ?? 0.4;
|
|
5151
6172
|
realPinNumberPos.x += vecToEdge.x * (realPinEdgeDistance + LABEL_DIST_FROM_EDGE_MM);
|
|
5152
6173
|
realPinNumberPos.y += vecToEdge.y * (realPinEdgeDistance + LABEL_DIST_FROM_EDGE_MM);
|
|
5153
|
-
const screenPinNumberTextPos =
|
|
6174
|
+
const screenPinNumberTextPos = applyToPoint42(transform, realPinNumberPos);
|
|
5154
6175
|
const label = schPort.display_pin_label ?? schComponent.port_labels?.[`${schPort.pin_number}`];
|
|
5155
6176
|
if (!label) return [];
|
|
5156
6177
|
const isNegated = label.startsWith("N_");
|
|
@@ -5198,13 +6219,13 @@ var createSvgObjectsFromSchPortOnBox = (params) => {
|
|
|
5198
6219
|
};
|
|
5199
6220
|
|
|
5200
6221
|
// lib/sch/svg-object-fns/create-svg-objects-for-sch-text.ts
|
|
5201
|
-
import { applyToPoint as
|
|
6222
|
+
import { applyToPoint as applyToPoint44 } from "transformation-matrix";
|
|
5202
6223
|
var createSvgSchText = ({
|
|
5203
6224
|
elm,
|
|
5204
6225
|
transform,
|
|
5205
6226
|
colorMap: colorMap2
|
|
5206
6227
|
}) => {
|
|
5207
|
-
const center =
|
|
6228
|
+
const center = applyToPoint44(transform, elm.position);
|
|
5208
6229
|
const textAnchorMap = {
|
|
5209
6230
|
center: "middle",
|
|
5210
6231
|
center_right: "end",
|
|
@@ -5288,11 +6309,11 @@ var createSvgObjectsFromSchematicComponentWithBox = ({
|
|
|
5288
6309
|
colorMap: colorMap2
|
|
5289
6310
|
}) => {
|
|
5290
6311
|
const svgObjects = [];
|
|
5291
|
-
const componentScreenTopLeft =
|
|
6312
|
+
const componentScreenTopLeft = applyToPoint45(transform, {
|
|
5292
6313
|
x: schComponent.center.x - schComponent.size.width / 2,
|
|
5293
6314
|
y: schComponent.center.y + schComponent.size.height / 2
|
|
5294
6315
|
});
|
|
5295
|
-
const componentScreenBottomRight =
|
|
6316
|
+
const componentScreenBottomRight = applyToPoint45(transform, {
|
|
5296
6317
|
x: schComponent.center.x + schComponent.size.width / 2,
|
|
5297
6318
|
y: schComponent.center.y - schComponent.size.height / 2
|
|
5298
6319
|
});
|
|
@@ -5328,7 +6349,7 @@ var createSvgObjectsFromSchematicComponentWithBox = ({
|
|
|
5328
6349
|
},
|
|
5329
6350
|
children: []
|
|
5330
6351
|
});
|
|
5331
|
-
const schTexts =
|
|
6352
|
+
const schTexts = su11(circuitJson).schematic_text.list();
|
|
5332
6353
|
for (const schText of schTexts) {
|
|
5333
6354
|
if (schText.schematic_component_id === schComponent.schematic_component_id) {
|
|
5334
6355
|
svgObjects.push(
|
|
@@ -5340,7 +6361,7 @@ var createSvgObjectsFromSchematicComponentWithBox = ({
|
|
|
5340
6361
|
);
|
|
5341
6362
|
}
|
|
5342
6363
|
}
|
|
5343
|
-
const schematicPorts =
|
|
6364
|
+
const schematicPorts = su11(circuitJson).schematic_port.list({
|
|
5344
6365
|
schematic_component_id: schComponent.schematic_component_id
|
|
5345
6366
|
});
|
|
5346
6367
|
for (const schPort of schematicPorts) {
|
|
@@ -5378,13 +6399,13 @@ function createSvgObjectsFromSchematicComponent(params) {
|
|
|
5378
6399
|
}
|
|
5379
6400
|
|
|
5380
6401
|
// lib/sch/svg-object-fns/create-svg-objects-from-sch-voltage-probe.ts
|
|
5381
|
-
import { applyToPoint as
|
|
6402
|
+
import { applyToPoint as applyToPoint46 } from "transformation-matrix";
|
|
5382
6403
|
function createSvgObjectsFromSchVoltageProbe({
|
|
5383
6404
|
probe,
|
|
5384
6405
|
transform,
|
|
5385
6406
|
colorMap: colorMap2
|
|
5386
6407
|
}) {
|
|
5387
|
-
const [screenX, screenY] =
|
|
6408
|
+
const [screenX, screenY] = applyToPoint46(transform, [
|
|
5388
6409
|
probe.position.x,
|
|
5389
6410
|
probe.position.y
|
|
5390
6411
|
]);
|
|
@@ -5444,17 +6465,17 @@ function createSvgObjectsFromSchVoltageProbe({
|
|
|
5444
6465
|
}
|
|
5445
6466
|
|
|
5446
6467
|
// lib/sch/svg-object-fns/create-svg-objects-from-sch-debug-object.ts
|
|
5447
|
-
import { applyToPoint as
|
|
6468
|
+
import { applyToPoint as applyToPoint47 } from "transformation-matrix";
|
|
5448
6469
|
function createSvgObjectsFromSchDebugObject({
|
|
5449
6470
|
debugObject,
|
|
5450
6471
|
transform
|
|
5451
6472
|
}) {
|
|
5452
6473
|
if (debugObject.shape === "rect") {
|
|
5453
|
-
let [screenLeft, screenTop] =
|
|
6474
|
+
let [screenLeft, screenTop] = applyToPoint47(transform, [
|
|
5454
6475
|
debugObject.center.x - debugObject.size.width / 2,
|
|
5455
6476
|
debugObject.center.y - debugObject.size.height / 2
|
|
5456
6477
|
]);
|
|
5457
|
-
let [screenRight, screenBottom] =
|
|
6478
|
+
let [screenRight, screenBottom] = applyToPoint47(transform, [
|
|
5458
6479
|
debugObject.center.x + debugObject.size.width / 2,
|
|
5459
6480
|
debugObject.center.y + debugObject.size.height / 2
|
|
5460
6481
|
]);
|
|
@@ -5464,7 +6485,7 @@ function createSvgObjectsFromSchDebugObject({
|
|
|
5464
6485
|
];
|
|
5465
6486
|
const width = Math.abs(screenRight - screenLeft);
|
|
5466
6487
|
const height = Math.abs(screenBottom - screenTop);
|
|
5467
|
-
const [screenCenterX, screenCenterY] =
|
|
6488
|
+
const [screenCenterX, screenCenterY] = applyToPoint47(transform, [
|
|
5468
6489
|
debugObject.center.x,
|
|
5469
6490
|
debugObject.center.y
|
|
5470
6491
|
]);
|
|
@@ -5510,11 +6531,11 @@ function createSvgObjectsFromSchDebugObject({
|
|
|
5510
6531
|
];
|
|
5511
6532
|
}
|
|
5512
6533
|
if (debugObject.shape === "line") {
|
|
5513
|
-
const [screenStartX, screenStartY] =
|
|
6534
|
+
const [screenStartX, screenStartY] = applyToPoint47(transform, [
|
|
5514
6535
|
debugObject.start.x,
|
|
5515
6536
|
debugObject.start.y
|
|
5516
6537
|
]);
|
|
5517
|
-
const [screenEndX, screenEndY] =
|
|
6538
|
+
const [screenEndX, screenEndY] = applyToPoint47(transform, [
|
|
5518
6539
|
debugObject.end.x,
|
|
5519
6540
|
debugObject.end.y
|
|
5520
6541
|
]);
|
|
@@ -5564,7 +6585,7 @@ function createSvgObjectsFromSchDebugObject({
|
|
|
5564
6585
|
}
|
|
5565
6586
|
|
|
5566
6587
|
// lib/sch/svg-object-fns/create-svg-objects-from-sch-trace.ts
|
|
5567
|
-
import { applyToPoint as
|
|
6588
|
+
import { applyToPoint as applyToPoint48 } from "transformation-matrix";
|
|
5568
6589
|
function createSchematicTrace({
|
|
5569
6590
|
trace,
|
|
5570
6591
|
transform,
|
|
@@ -5578,11 +6599,11 @@ function createSchematicTrace({
|
|
|
5578
6599
|
for (let edgeIndex = 0; edgeIndex < edges.length; edgeIndex++) {
|
|
5579
6600
|
const edge = edges[edgeIndex];
|
|
5580
6601
|
if (edge.is_crossing) continue;
|
|
5581
|
-
const [screenFromX, screenFromY] =
|
|
6602
|
+
const [screenFromX, screenFromY] = applyToPoint48(transform, [
|
|
5582
6603
|
edge.from.x,
|
|
5583
6604
|
edge.from.y
|
|
5584
6605
|
]);
|
|
5585
|
-
const [screenToX, screenToY] =
|
|
6606
|
+
const [screenToX, screenToY] = applyToPoint48(transform, [
|
|
5586
6607
|
edge.to.x,
|
|
5587
6608
|
edge.to.y
|
|
5588
6609
|
]);
|
|
@@ -5626,11 +6647,11 @@ function createSchematicTrace({
|
|
|
5626
6647
|
}
|
|
5627
6648
|
for (const edge of edges) {
|
|
5628
6649
|
if (!edge.is_crossing) continue;
|
|
5629
|
-
const [screenFromX, screenFromY] =
|
|
6650
|
+
const [screenFromX, screenFromY] = applyToPoint48(transform, [
|
|
5630
6651
|
edge.from.x,
|
|
5631
6652
|
edge.from.y
|
|
5632
6653
|
]);
|
|
5633
|
-
const [screenToX, screenToY] =
|
|
6654
|
+
const [screenToX, screenToY] = applyToPoint48(transform, [
|
|
5634
6655
|
edge.to.x,
|
|
5635
6656
|
edge.to.y
|
|
5636
6657
|
]);
|
|
@@ -5674,7 +6695,7 @@ function createSchematicTrace({
|
|
|
5674
6695
|
}
|
|
5675
6696
|
if (trace.junctions) {
|
|
5676
6697
|
for (const junction of trace.junctions) {
|
|
5677
|
-
const [screenX, screenY] =
|
|
6698
|
+
const [screenX, screenY] = applyToPoint48(transform, [
|
|
5678
6699
|
junction.x,
|
|
5679
6700
|
junction.y
|
|
5680
6701
|
]);
|
|
@@ -5729,20 +6750,20 @@ function createSchematicTrace({
|
|
|
5729
6750
|
|
|
5730
6751
|
// lib/sch/svg-object-fns/create-svg-objects-for-sch-net-label.ts
|
|
5731
6752
|
import {
|
|
5732
|
-
applyToPoint as
|
|
5733
|
-
compose as
|
|
6753
|
+
applyToPoint as applyToPoint50,
|
|
6754
|
+
compose as compose11,
|
|
5734
6755
|
rotate as rotate6,
|
|
5735
|
-
scale as
|
|
5736
|
-
translate as
|
|
6756
|
+
scale as scale7,
|
|
6757
|
+
translate as translate11
|
|
5737
6758
|
} from "transformation-matrix";
|
|
5738
6759
|
|
|
5739
6760
|
// lib/sch/svg-object-fns/create-svg-objects-for-sch-net-label-with-symbol.ts
|
|
5740
6761
|
import {
|
|
5741
|
-
applyToPoint as
|
|
5742
|
-
compose as
|
|
6762
|
+
applyToPoint as applyToPoint49,
|
|
6763
|
+
compose as compose10,
|
|
5743
6764
|
rotate as rotate5,
|
|
5744
|
-
scale as
|
|
5745
|
-
translate as
|
|
6765
|
+
scale as scale6,
|
|
6766
|
+
translate as translate10
|
|
5746
6767
|
} from "transformation-matrix";
|
|
5747
6768
|
import { symbols as symbols3 } from "schematic-symbols";
|
|
5748
6769
|
var createSvgObjectsForSchNetLabelWithSymbol = ({
|
|
@@ -5813,22 +6834,22 @@ var createSvgObjectsForSchNetLabelWithSymbol = ({
|
|
|
5813
6834
|
x: symbolBounds.minX,
|
|
5814
6835
|
y: (symbolBounds.minY + symbolBounds.maxY) / 2
|
|
5815
6836
|
};
|
|
5816
|
-
const rotatedSymbolEnd =
|
|
5817
|
-
const symbolToRealTransform =
|
|
5818
|
-
|
|
6837
|
+
const rotatedSymbolEnd = applyToPoint49(rotationMatrix, symbolEndPoint);
|
|
6838
|
+
const symbolToRealTransform = compose10(
|
|
6839
|
+
translate10(
|
|
5819
6840
|
realAnchorPosition.x - rotatedSymbolEnd.x,
|
|
5820
6841
|
realAnchorPosition.y - rotatedSymbolEnd.y
|
|
5821
6842
|
),
|
|
5822
6843
|
rotationMatrix,
|
|
5823
|
-
|
|
6844
|
+
scale6(1)
|
|
5824
6845
|
// Use full symbol size
|
|
5825
6846
|
);
|
|
5826
|
-
const [screenMinX, screenMinY] =
|
|
5827
|
-
|
|
6847
|
+
const [screenMinX, screenMinY] = applyToPoint49(
|
|
6848
|
+
compose10(realToScreenTransform, symbolToRealTransform),
|
|
5828
6849
|
[bounds.minX, bounds.minY]
|
|
5829
6850
|
);
|
|
5830
|
-
const [screenMaxX, screenMaxY] =
|
|
5831
|
-
|
|
6851
|
+
const [screenMaxX, screenMaxY] = applyToPoint49(
|
|
6852
|
+
compose10(realToScreenTransform, symbolToRealTransform),
|
|
5832
6853
|
[bounds.maxX, bounds.maxY]
|
|
5833
6854
|
);
|
|
5834
6855
|
const rectHeight = Math.abs(screenMaxY - screenMinY);
|
|
@@ -5851,8 +6872,8 @@ var createSvgObjectsForSchNetLabelWithSymbol = ({
|
|
|
5851
6872
|
});
|
|
5852
6873
|
for (const path of symbolPaths) {
|
|
5853
6874
|
const symbolPath = path.points.map((p, i) => {
|
|
5854
|
-
const [x, y] =
|
|
5855
|
-
|
|
6875
|
+
const [x, y] = applyToPoint49(
|
|
6876
|
+
compose10(realToScreenTransform, symbolToRealTransform),
|
|
5856
6877
|
[p.x, p.y]
|
|
5857
6878
|
);
|
|
5858
6879
|
return `${i === 0 ? "M" : "L"} ${x} ${y}`;
|
|
@@ -5872,8 +6893,8 @@ var createSvgObjectsForSchNetLabelWithSymbol = ({
|
|
|
5872
6893
|
});
|
|
5873
6894
|
}
|
|
5874
6895
|
for (const text of symbolTexts) {
|
|
5875
|
-
const screenTextPos =
|
|
5876
|
-
|
|
6896
|
+
const screenTextPos = applyToPoint49(
|
|
6897
|
+
compose10(realToScreenTransform, symbolToRealTransform),
|
|
5877
6898
|
text
|
|
5878
6899
|
);
|
|
5879
6900
|
let textValue = text.text;
|
|
@@ -5882,8 +6903,8 @@ var createSvgObjectsForSchNetLabelWithSymbol = ({
|
|
|
5882
6903
|
} else if (textValue === "{VAL}") {
|
|
5883
6904
|
textValue = "";
|
|
5884
6905
|
}
|
|
5885
|
-
const
|
|
5886
|
-
const baseOffset =
|
|
6906
|
+
const scale10 = Math.abs(realToScreenTransform.a);
|
|
6907
|
+
const baseOffset = scale10 * 0.1;
|
|
5887
6908
|
const offsetScreenPos = {
|
|
5888
6909
|
x: screenTextPos.x,
|
|
5889
6910
|
y: screenTextPos.y
|
|
@@ -5914,11 +6935,11 @@ var createSvgObjectsForSchNetLabelWithSymbol = ({
|
|
|
5914
6935
|
});
|
|
5915
6936
|
}
|
|
5916
6937
|
for (const box of symbolBoxes) {
|
|
5917
|
-
const screenBoxPos =
|
|
5918
|
-
|
|
6938
|
+
const screenBoxPos = applyToPoint49(
|
|
6939
|
+
compose10(realToScreenTransform, symbolToRealTransform),
|
|
5919
6940
|
box
|
|
5920
6941
|
);
|
|
5921
|
-
const symbolToScreenScale =
|
|
6942
|
+
const symbolToScreenScale = compose10(
|
|
5922
6943
|
realToScreenTransform,
|
|
5923
6944
|
symbolToRealTransform
|
|
5924
6945
|
).a;
|
|
@@ -5937,11 +6958,11 @@ var createSvgObjectsForSchNetLabelWithSymbol = ({
|
|
|
5937
6958
|
});
|
|
5938
6959
|
}
|
|
5939
6960
|
for (const circle of symbolCircles) {
|
|
5940
|
-
const screenCirclePos =
|
|
5941
|
-
|
|
6961
|
+
const screenCirclePos = applyToPoint49(
|
|
6962
|
+
compose10(realToScreenTransform, symbolToRealTransform),
|
|
5942
6963
|
circle
|
|
5943
6964
|
);
|
|
5944
|
-
const symbolToScreenScale =
|
|
6965
|
+
const symbolToScreenScale = compose10(
|
|
5945
6966
|
realToScreenTransform,
|
|
5946
6967
|
symbolToRealTransform
|
|
5947
6968
|
).a;
|
|
@@ -5982,14 +7003,14 @@ var createSvgObjectsForSchNetLabel = ({
|
|
|
5982
7003
|
const fontSizePx = getSchScreenFontSize(realToScreenTransform, "net_label");
|
|
5983
7004
|
const fontSizeMm = getSchMmFontSize("net_label");
|
|
5984
7005
|
const textWidthFSR = estimateTextWidth(labelText || "");
|
|
5985
|
-
const screenCenter =
|
|
7006
|
+
const screenCenter = applyToPoint50(realToScreenTransform, schNetLabel.center);
|
|
5986
7007
|
const realTextGrowthVec = getUnitVectorFromOutsideToEdge(
|
|
5987
7008
|
schNetLabel.anchor_side
|
|
5988
7009
|
);
|
|
5989
7010
|
const screenTextGrowthVec = { ...realTextGrowthVec };
|
|
5990
7011
|
screenTextGrowthVec.y *= -1;
|
|
5991
7012
|
const fullWidthFsr = textWidthFSR + ARROW_POINT_WIDTH_FSR * 2 + END_PADDING_EXTRA_PER_CHARACTER_FSR * labelText.length + END_PADDING_FSR;
|
|
5992
|
-
const screenAnchorPosition = schNetLabel.anchor_position ?
|
|
7013
|
+
const screenAnchorPosition = schNetLabel.anchor_position ? applyToPoint50(realToScreenTransform, schNetLabel.anchor_position) : {
|
|
5993
7014
|
x: screenCenter.x - screenTextGrowthVec.x * fullWidthFsr * fontSizePx / 2,
|
|
5994
7015
|
y: screenCenter.y - screenTextGrowthVec.y * fullWidthFsr * fontSizePx / 2
|
|
5995
7016
|
};
|
|
@@ -6030,11 +7051,11 @@ var createSvgObjectsForSchNetLabel = ({
|
|
|
6030
7051
|
y: -0.6
|
|
6031
7052
|
}
|
|
6032
7053
|
].map(
|
|
6033
|
-
(fontRelativePoint) =>
|
|
6034
|
-
|
|
7054
|
+
(fontRelativePoint) => applyToPoint50(
|
|
7055
|
+
compose11(
|
|
6035
7056
|
realToScreenTransform,
|
|
6036
|
-
|
|
6037
|
-
|
|
7057
|
+
translate11(realAnchorPosition.x, realAnchorPosition.y),
|
|
7058
|
+
scale7(fontSizeMm),
|
|
6038
7059
|
rotate6(pathRotation / 180 * Math.PI)
|
|
6039
7060
|
),
|
|
6040
7061
|
fontRelativePoint
|
|
@@ -6107,17 +7128,17 @@ var createSvgObjectsForSchNetLabel = ({
|
|
|
6107
7128
|
};
|
|
6108
7129
|
|
|
6109
7130
|
// lib/sch/svg-object-fns/create-svg-objects-from-sch-box.ts
|
|
6110
|
-
import { applyToPoint as
|
|
7131
|
+
import { applyToPoint as applyToPoint51 } from "transformation-matrix";
|
|
6111
7132
|
var createSvgObjectsFromSchematicBox = ({
|
|
6112
7133
|
schematicBox,
|
|
6113
7134
|
transform,
|
|
6114
7135
|
colorMap: colorMap2
|
|
6115
7136
|
}) => {
|
|
6116
|
-
const topLeft =
|
|
7137
|
+
const topLeft = applyToPoint51(transform, {
|
|
6117
7138
|
x: schematicBox.x,
|
|
6118
7139
|
y: schematicBox.y
|
|
6119
7140
|
});
|
|
6120
|
-
const bottomRight =
|
|
7141
|
+
const bottomRight = applyToPoint51(transform, {
|
|
6121
7142
|
x: schematicBox.x + schematicBox.width,
|
|
6122
7143
|
y: schematicBox.y + schematicBox.height
|
|
6123
7144
|
});
|
|
@@ -6153,7 +7174,7 @@ var createSvgObjectsFromSchematicBox = ({
|
|
|
6153
7174
|
};
|
|
6154
7175
|
|
|
6155
7176
|
// lib/sch/svg-object-fns/create-svg-objects-from-sch-table.ts
|
|
6156
|
-
import { applyToPoint as
|
|
7177
|
+
import { applyToPoint as applyToPoint52 } from "transformation-matrix";
|
|
6157
7178
|
var createSvgObjectsFromSchematicTable = ({
|
|
6158
7179
|
schematicTable,
|
|
6159
7180
|
transform,
|
|
@@ -6186,11 +7207,11 @@ var createSvgObjectsFromSchematicTable = ({
|
|
|
6186
7207
|
const svgObjects = [];
|
|
6187
7208
|
const borderStrokeWidth = border_width * Math.abs(transform.a);
|
|
6188
7209
|
const gridStrokeWidth = getSchStrokeSize(transform);
|
|
6189
|
-
const [screenTopLeftX, screenTopLeftY] =
|
|
7210
|
+
const [screenTopLeftX, screenTopLeftY] = applyToPoint52(transform, [
|
|
6190
7211
|
topLeftX,
|
|
6191
7212
|
topLeftY
|
|
6192
7213
|
]);
|
|
6193
|
-
const [screenBottomRightX, screenBottomRightY] =
|
|
7214
|
+
const [screenBottomRightX, screenBottomRightY] = applyToPoint52(transform, [
|
|
6194
7215
|
topLeftX + totalWidth,
|
|
6195
7216
|
topLeftY - totalHeight
|
|
6196
7217
|
]);
|
|
@@ -6222,8 +7243,8 @@ var createSvgObjectsFromSchematicTable = ({
|
|
|
6222
7243
|
(cell) => cell.start_column_index <= i && cell.end_column_index > i && cell.start_row_index <= j && cell.end_row_index >= j
|
|
6223
7244
|
);
|
|
6224
7245
|
if (!isMerged) {
|
|
6225
|
-
const start =
|
|
6226
|
-
const end =
|
|
7246
|
+
const start = applyToPoint52(transform, { x: currentX, y: segmentStartY });
|
|
7247
|
+
const end = applyToPoint52(transform, { x: currentX, y: segmentEndY });
|
|
6227
7248
|
svgObjects.push({
|
|
6228
7249
|
name: "line",
|
|
6229
7250
|
type: "element",
|
|
@@ -6252,11 +7273,11 @@ var createSvgObjectsFromSchematicTable = ({
|
|
|
6252
7273
|
(cell) => cell.start_row_index <= i && cell.end_row_index > i && cell.start_column_index <= j && cell.end_column_index >= j
|
|
6253
7274
|
);
|
|
6254
7275
|
if (!isMerged) {
|
|
6255
|
-
const start =
|
|
7276
|
+
const start = applyToPoint52(transform, {
|
|
6256
7277
|
x: segmentStartX,
|
|
6257
7278
|
y: currentY
|
|
6258
7279
|
});
|
|
6259
|
-
const end =
|
|
7280
|
+
const end = applyToPoint52(transform, { x: segmentEndX, y: currentY });
|
|
6260
7281
|
svgObjects.push({
|
|
6261
7282
|
name: "line",
|
|
6262
7283
|
type: "element",
|
|
@@ -6298,7 +7319,7 @@ var createSvgObjectsFromSchematicTable = ({
|
|
|
6298
7319
|
} else if (vertical_align === "bottom") {
|
|
6299
7320
|
realTextAnchorPos.y = cellTopLeftY - cellHeight + cell_padding;
|
|
6300
7321
|
}
|
|
6301
|
-
const screenTextAnchorPos =
|
|
7322
|
+
const screenTextAnchorPos = applyToPoint52(transform, realTextAnchorPos);
|
|
6302
7323
|
const fontSize = getSchScreenFontSize(
|
|
6303
7324
|
transform,
|
|
6304
7325
|
"reference_designator",
|
|
@@ -6353,14 +7374,14 @@ var createSvgObjectsFromSchematicTable = ({
|
|
|
6353
7374
|
};
|
|
6354
7375
|
|
|
6355
7376
|
// lib/sch/svg-object-fns/create-svg-objects-for-sch-port-hover.ts
|
|
6356
|
-
import { su as
|
|
6357
|
-
import { applyToPoint as
|
|
7377
|
+
import { su as su12 } from "@tscircuit/circuit-json-util";
|
|
7378
|
+
import { applyToPoint as applyToPoint53 } from "transformation-matrix";
|
|
6358
7379
|
var PIN_CIRCLE_RADIUS_MM2 = 0.02;
|
|
6359
7380
|
var createSvgObjectsForSchPortHover = ({
|
|
6360
7381
|
schPort,
|
|
6361
7382
|
transform
|
|
6362
7383
|
}) => {
|
|
6363
|
-
const screenSchPortPos =
|
|
7384
|
+
const screenSchPortPos = applyToPoint53(transform, schPort.center);
|
|
6364
7385
|
const pinRadiusPx = Math.abs(transform.a) * PIN_CIRCLE_RADIUS_MM2 * 2;
|
|
6365
7386
|
return [
|
|
6366
7387
|
{
|
|
@@ -6394,7 +7415,7 @@ var createSvgObjectsForSchComponentPortHovers = ({
|
|
|
6394
7415
|
transform,
|
|
6395
7416
|
circuitJson
|
|
6396
7417
|
}) => {
|
|
6397
|
-
const schematicPorts =
|
|
7418
|
+
const schematicPorts = su12(circuitJson).schematic_port.list({
|
|
6398
7419
|
schematic_component_id: component.schematic_component_id
|
|
6399
7420
|
});
|
|
6400
7421
|
const svgs = [];
|
|
@@ -6405,14 +7426,14 @@ var createSvgObjectsForSchComponentPortHovers = ({
|
|
|
6405
7426
|
};
|
|
6406
7427
|
|
|
6407
7428
|
// lib/sch/svg-object-fns/create-svg-objects-from-sch-line.ts
|
|
6408
|
-
import { applyToPoint as
|
|
7429
|
+
import { applyToPoint as applyToPoint54 } from "transformation-matrix";
|
|
6409
7430
|
function createSvgObjectsFromSchematicLine({
|
|
6410
7431
|
schLine,
|
|
6411
7432
|
transform,
|
|
6412
7433
|
colorMap: colorMap2
|
|
6413
7434
|
}) {
|
|
6414
|
-
const p1 =
|
|
6415
|
-
const p2 =
|
|
7435
|
+
const p1 = applyToPoint54(transform, { x: schLine.x1, y: schLine.y1 });
|
|
7436
|
+
const p2 = applyToPoint54(transform, { x: schLine.x2, y: schLine.y2 });
|
|
6416
7437
|
const strokeWidth = schLine.stroke_width ?? 0.02;
|
|
6417
7438
|
const transformedStrokeWidth = Math.abs(transform.a) * strokeWidth;
|
|
6418
7439
|
return [
|
|
@@ -6441,13 +7462,13 @@ function createSvgObjectsFromSchematicLine({
|
|
|
6441
7462
|
}
|
|
6442
7463
|
|
|
6443
7464
|
// lib/sch/svg-object-fns/create-svg-objects-from-sch-circle.ts
|
|
6444
|
-
import { applyToPoint as
|
|
7465
|
+
import { applyToPoint as applyToPoint55 } from "transformation-matrix";
|
|
6445
7466
|
function createSvgObjectsFromSchematicCircle({
|
|
6446
7467
|
schCircle,
|
|
6447
7468
|
transform,
|
|
6448
7469
|
colorMap: colorMap2
|
|
6449
7470
|
}) {
|
|
6450
|
-
const center =
|
|
7471
|
+
const center = applyToPoint55(transform, schCircle.center);
|
|
6451
7472
|
const transformedRadius = Math.abs(transform.a) * schCircle.radius;
|
|
6452
7473
|
const strokeWidth = schCircle.stroke_width ?? 0.02;
|
|
6453
7474
|
const transformedStrokeWidth = Math.abs(transform.a) * strokeWidth;
|
|
@@ -6477,13 +7498,13 @@ function createSvgObjectsFromSchematicCircle({
|
|
|
6477
7498
|
}
|
|
6478
7499
|
|
|
6479
7500
|
// lib/sch/svg-object-fns/create-svg-objects-from-sch-rect.ts
|
|
6480
|
-
import { applyToPoint as
|
|
7501
|
+
import { applyToPoint as applyToPoint56 } from "transformation-matrix";
|
|
6481
7502
|
function createSvgObjectsFromSchematicRect({
|
|
6482
7503
|
schRect,
|
|
6483
7504
|
transform,
|
|
6484
7505
|
colorMap: colorMap2
|
|
6485
7506
|
}) {
|
|
6486
|
-
const center =
|
|
7507
|
+
const center = applyToPoint56(transform, schRect.center);
|
|
6487
7508
|
const transformedWidth = Math.abs(transform.a) * schRect.width;
|
|
6488
7509
|
const transformedHeight = Math.abs(transform.d) * schRect.height;
|
|
6489
7510
|
const strokeWidth = schRect.stroke_width ?? 0.02;
|
|
@@ -6519,13 +7540,13 @@ function createSvgObjectsFromSchematicRect({
|
|
|
6519
7540
|
}
|
|
6520
7541
|
|
|
6521
7542
|
// lib/sch/svg-object-fns/create-svg-objects-from-sch-arc.ts
|
|
6522
|
-
import { applyToPoint as
|
|
7543
|
+
import { applyToPoint as applyToPoint57 } from "transformation-matrix";
|
|
6523
7544
|
function createSvgObjectsFromSchematicArc({
|
|
6524
7545
|
schArc,
|
|
6525
7546
|
transform,
|
|
6526
7547
|
colorMap: colorMap2
|
|
6527
7548
|
}) {
|
|
6528
|
-
const center =
|
|
7549
|
+
const center = applyToPoint57(transform, schArc.center);
|
|
6529
7550
|
const transformedRadius = Math.abs(transform.a) * schArc.radius;
|
|
6530
7551
|
const strokeWidth = schArc.stroke_width ?? 0.02;
|
|
6531
7552
|
const transformedStrokeWidth = Math.abs(transform.a) * strokeWidth;
|
|
@@ -6865,25 +7886,25 @@ function convertCircuitJsonToSchematicSvg(circuitJson, options) {
|
|
|
6865
7886
|
],
|
|
6866
7887
|
value: ""
|
|
6867
7888
|
};
|
|
6868
|
-
return
|
|
7889
|
+
return stringify4(svgObject);
|
|
6869
7890
|
}
|
|
6870
7891
|
var circuitJsonToSchematicSvg = convertCircuitJsonToSchematicSvg;
|
|
6871
7892
|
|
|
6872
7893
|
// lib/pcb/convert-circuit-json-to-solder-paste-mask.ts
|
|
6873
|
-
import { stringify as
|
|
7894
|
+
import { stringify as stringify5 } from "svgson";
|
|
6874
7895
|
import {
|
|
6875
|
-
applyToPoint as
|
|
6876
|
-
compose as
|
|
6877
|
-
scale as
|
|
6878
|
-
translate as
|
|
7896
|
+
applyToPoint as applyToPoint60,
|
|
7897
|
+
compose as compose14,
|
|
7898
|
+
scale as scale9,
|
|
7899
|
+
translate as translate14
|
|
6879
7900
|
} from "transformation-matrix";
|
|
6880
7901
|
|
|
6881
7902
|
// lib/pcb/svg-object-fns/convert-circuit-json-to-solder-paste-mask.ts
|
|
6882
|
-
import { applyToPoint as
|
|
7903
|
+
import { applyToPoint as applyToPoint59 } from "transformation-matrix";
|
|
6883
7904
|
function createSvgObjectsFromSolderPaste(solderPaste, ctx) {
|
|
6884
7905
|
const { transform, layer: layerFilter } = ctx;
|
|
6885
7906
|
if (layerFilter && solderPaste.layer !== layerFilter) return [];
|
|
6886
|
-
const [x, y] =
|
|
7907
|
+
const [x, y] = applyToPoint59(transform, [solderPaste.x, solderPaste.y]);
|
|
6887
7908
|
if (solderPaste.shape === "rect" || solderPaste.shape === "rotated_rect") {
|
|
6888
7909
|
const width = solderPaste.width * Math.abs(transform.a);
|
|
6889
7910
|
const height = solderPaste.height * Math.abs(transform.d);
|
|
@@ -6958,7 +7979,7 @@ function createSvgObjectsFromSolderPaste(solderPaste, ctx) {
|
|
|
6958
7979
|
}
|
|
6959
7980
|
|
|
6960
7981
|
// lib/pcb/convert-circuit-json-to-solder-paste-mask.ts
|
|
6961
|
-
var
|
|
7982
|
+
var OBJECT_ORDER4 = [
|
|
6962
7983
|
"pcb_board",
|
|
6963
7984
|
"pcb_solder_paste"
|
|
6964
7985
|
];
|
|
@@ -6991,12 +8012,12 @@ function convertCircuitJsonToSolderPasteMask(circuitJson, options) {
|
|
|
6991
8012
|
const scaleFactor = Math.min(scaleX, scaleY);
|
|
6992
8013
|
const offsetX = (svgWidth - circuitWidth * scaleFactor) / 2;
|
|
6993
8014
|
const offsetY = (svgHeight - circuitHeight * scaleFactor) / 2;
|
|
6994
|
-
const transform =
|
|
6995
|
-
|
|
8015
|
+
const transform = compose14(
|
|
8016
|
+
translate14(
|
|
6996
8017
|
offsetX - minX * scaleFactor + padding * scaleFactor,
|
|
6997
8018
|
svgHeight - offsetY + minY * scaleFactor - padding * scaleFactor
|
|
6998
8019
|
),
|
|
6999
|
-
|
|
8020
|
+
scale9(scaleFactor, -scaleFactor)
|
|
7000
8021
|
// Flip in y-direction
|
|
7001
8022
|
);
|
|
7002
8023
|
const ctx = {
|
|
@@ -7005,8 +8026,8 @@ function convertCircuitJsonToSolderPasteMask(circuitJson, options) {
|
|
|
7005
8026
|
colorMap: DEFAULT_PCB_COLOR_MAP
|
|
7006
8027
|
};
|
|
7007
8028
|
const svgObjects = filteredCircuitJson.sort(
|
|
7008
|
-
(a, b) => (
|
|
7009
|
-
).flatMap((item) =>
|
|
8029
|
+
(a, b) => (OBJECT_ORDER4.indexOf(b.type) ?? 9999) - (OBJECT_ORDER4.indexOf(a.type) ?? 9999)
|
|
8030
|
+
).flatMap((item) => createSvgObjects4({ elm: item, ctx }));
|
|
7010
8031
|
const softwareUsedString = getSoftwareUsedString(circuitJson);
|
|
7011
8032
|
const version = CIRCUIT_TO_SVG_VERSION;
|
|
7012
8033
|
const svgObject = {
|
|
@@ -7052,7 +8073,7 @@ function convertCircuitJsonToSolderPasteMask(circuitJson, options) {
|
|
|
7052
8073
|
].filter((child) => child !== null)
|
|
7053
8074
|
};
|
|
7054
8075
|
try {
|
|
7055
|
-
return
|
|
8076
|
+
return stringify5(svgObject);
|
|
7056
8077
|
} catch (error) {
|
|
7057
8078
|
console.error("Error stringifying SVG object:", error);
|
|
7058
8079
|
throw error;
|
|
@@ -7074,7 +8095,7 @@ function convertCircuitJsonToSolderPasteMask(circuitJson, options) {
|
|
|
7074
8095
|
}
|
|
7075
8096
|
}
|
|
7076
8097
|
}
|
|
7077
|
-
function
|
|
8098
|
+
function createSvgObjects4({ elm, ctx }) {
|
|
7078
8099
|
const { transform } = ctx;
|
|
7079
8100
|
switch (elm.type) {
|
|
7080
8101
|
case "pcb_board":
|
|
@@ -7086,8 +8107,8 @@ function createSvgObjects3({ elm, ctx }) {
|
|
|
7086
8107
|
}
|
|
7087
8108
|
}
|
|
7088
8109
|
function createSvgObjectFromPcbBoundary2(transform, minX, minY, maxX, maxY) {
|
|
7089
|
-
const [x1, y1] =
|
|
7090
|
-
const [x2, y2] =
|
|
8110
|
+
const [x1, y1] = applyToPoint60(transform, [minX, minY]);
|
|
8111
|
+
const [x2, y2] = applyToPoint60(transform, [maxX, maxY]);
|
|
7091
8112
|
const width = Math.abs(x2 - x1);
|
|
7092
8113
|
const height = Math.abs(y2 - y1);
|
|
7093
8114
|
const x = Math.min(x1, x2);
|
|
@@ -7115,6 +8136,7 @@ export {
|
|
|
7115
8136
|
circuitJsonToSchematicSvg,
|
|
7116
8137
|
convertCircuitJsonToAssemblySvg,
|
|
7117
8138
|
convertCircuitJsonToPcbSvg,
|
|
8139
|
+
convertCircuitJsonToPinoutSvg,
|
|
7118
8140
|
convertCircuitJsonToSchematicSvg,
|
|
7119
8141
|
convertCircuitJsonToSolderPasteMask,
|
|
7120
8142
|
createSvgObjectsForSchComponentPortHovers,
|