circuit-to-svg 0.0.304 → 0.0.306

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.js CHANGED
@@ -1,5 +1,5 @@
1
1
  // lib/pcb/convert-circuit-json-to-pcb-svg.ts
2
- import { distance as distance2 } from "circuit-json";
2
+ import "circuit-json";
3
3
  import { stringify } from "svgson";
4
4
  import {
5
5
  applyToPoint as applyToPoint37,
@@ -2646,7 +2646,8 @@ function createSvgObjectsFromPcbSilkscreenRect(pcbSilkscreenRect, ctx) {
2646
2646
  is_filled,
2647
2647
  has_stroke,
2648
2648
  is_stroke_dashed,
2649
- corner_radius
2649
+ corner_radius,
2650
+ ccw_rotation = 0
2650
2651
  } = pcbSilkscreenRect;
2651
2652
  if (layerFilter && layer !== layerFilter) return [];
2652
2653
  if (!center || typeof center.x !== "number" || typeof center.y !== "number" || typeof width !== "number" || typeof height !== "number") {
@@ -2665,8 +2666,8 @@ function createSvgObjectsFromPcbSilkscreenRect(pcbSilkscreenRect, ctx) {
2665
2666
  const transformedStrokeWidth = stroke_width * Math.abs(transform.a);
2666
2667
  const color = layer === "bottom" ? colorMap2.silkscreen.bottom : colorMap2.silkscreen.top;
2667
2668
  const attributes = {
2668
- x: (transformedX - transformedWidth / 2).toString(),
2669
- y: (transformedY - transformedHeight / 2).toString(),
2669
+ x: (-transformedWidth / 2).toString(),
2670
+ y: (-transformedHeight / 2).toString(),
2670
2671
  width: transformedWidth.toString(),
2671
2672
  height: transformedHeight.toString(),
2672
2673
  class: `pcb-silkscreen-rect pcb-silkscreen-${layer}`,
@@ -2674,6 +2675,12 @@ function createSvgObjectsFromPcbSilkscreenRect(pcbSilkscreenRect, ctx) {
2674
2675
  "data-type": "pcb_silkscreen_rect",
2675
2676
  "data-pcb-layer": layer
2676
2677
  };
2678
+ if (typeof ccw_rotation === "number" && ccw_rotation !== 0) {
2679
+ attributes.transform = `translate(${transformedX} ${transformedY}) rotate(${-ccw_rotation})`;
2680
+ } else {
2681
+ attributes.x = (transformedX - transformedWidth / 2).toString();
2682
+ attributes.y = (transformedY - transformedHeight / 2).toString();
2683
+ }
2677
2684
  if (transformedCornerRadiusX > 0) {
2678
2685
  attributes.rx = transformedCornerRadiusX.toString();
2679
2686
  }
@@ -3827,10 +3834,10 @@ function createSvgObjectsFromSmtPad(pad, ctx) {
3827
3834
  maskPoints = points.map(([px, py]) => {
3828
3835
  const dx = px - centroidX;
3829
3836
  const dy = py - centroidY;
3830
- const distance4 = Math.sqrt(dx * dx + dy * dy);
3831
- if (distance4 === 0) return [px, py];
3832
- const normalizedDx = dx / distance4;
3833
- const normalizedDy = dy / distance4;
3837
+ const distance5 = Math.sqrt(dx * dx + dy * dy);
3838
+ if (distance5 === 0) return [px, py];
3839
+ const normalizedDx = dx / distance5;
3840
+ const normalizedDy = dy / distance5;
3834
3841
  return [
3835
3842
  px + normalizedDx * soldermaskMargin,
3836
3843
  py + normalizedDy * soldermaskMargin
@@ -4036,11 +4043,11 @@ function createAnchorOffsetIndicators(params) {
4036
4043
  function getTrimmedConnectorLine(x1, y1, x2, y2) {
4037
4044
  const dx = x2 - x1;
4038
4045
  const dy = y2 - y1;
4039
- const distance4 = Math.hypot(dx, dy);
4046
+ const distance5 = Math.hypot(dx, dy);
4040
4047
  const totalTrim = CONNECTOR_GROUP_GAP_PX + CONNECTOR_COMPONENT_GAP_PX;
4041
- if (!(distance4 > totalTrim)) return { x1, y1, x2, y2 };
4042
- const ux = dx / distance4;
4043
- const uy = dy / distance4;
4048
+ if (!(distance5 > totalTrim)) return { x1, y1, x2, y2 };
4049
+ const ux = dx / distance5;
4050
+ const uy = dy / distance5;
4044
4051
  return {
4045
4052
  x1: x1 + ux * CONNECTOR_GROUP_GAP_PX,
4046
4053
  y1: y1 + uy * CONNECTOR_GROUP_GAP_PX,
@@ -4997,9 +5004,9 @@ var findNearestPointInNet = (sourcePoint, netId, connectivity, circuitJson) => {
4997
5004
  if (pos) {
4998
5005
  const dx = sourcePoint.x - pos.x;
4999
5006
  const dy = sourcePoint.y - pos.y;
5000
- const distance4 = Math.sqrt(dx * dx + dy * dy);
5001
- if (distance4 > 0 && distance4 < minDistance) {
5002
- minDistance = distance4;
5007
+ const distance5 = Math.sqrt(dx * dx + dy * dy);
5008
+ if (distance5 > 0 && distance5 < minDistance) {
5009
+ minDistance = distance5;
5003
5010
  nearestPoint = pos;
5004
5011
  }
5005
5012
  }
@@ -5877,7 +5884,7 @@ function getSoftwareUsedString(circuitJson) {
5877
5884
  var package_default = {
5878
5885
  name: "circuit-to-svg",
5879
5886
  type: "module",
5880
- version: "0.0.303",
5887
+ version: "0.0.305",
5881
5888
  description: "Convert Circuit JSON to SVG",
5882
5889
  main: "dist/index.js",
5883
5890
  files: [
@@ -6059,49 +6066,9 @@ function createErrorTextOverlay(circuitJson, dataType = "error_text_overlay") {
6059
6066
  return textBlock;
6060
6067
  }
6061
6068
 
6062
- // lib/pcb/convert-circuit-json-to-pcb-svg.ts
6063
- function convertCircuitJsonToPcbSvg(circuitJson, options) {
6064
- const drawPaddingOutsideBoard = options?.drawPaddingOutsideBoard ?? true;
6065
- const layer = options?.layer;
6066
- const colorOverrides = options?.colorOverrides;
6067
- const copperColors = {
6068
- ...DEFAULT_PCB_COLOR_MAP.copper
6069
- };
6070
- if (colorOverrides?.copper) {
6071
- for (const [layerName, color] of Object.entries(colorOverrides.copper)) {
6072
- if (color !== void 0) {
6073
- copperColors[layerName] = color;
6074
- }
6075
- }
6076
- }
6077
- const colorMap2 = {
6078
- copper: copperColors,
6079
- drill: colorOverrides?.drill ?? DEFAULT_PCB_COLOR_MAP.drill,
6080
- silkscreen: {
6081
- top: colorOverrides?.silkscreen?.top ?? DEFAULT_PCB_COLOR_MAP.silkscreen.top,
6082
- bottom: colorOverrides?.silkscreen?.bottom ?? DEFAULT_PCB_COLOR_MAP.silkscreen.bottom
6083
- },
6084
- boardOutline: colorOverrides?.boardOutline ?? DEFAULT_PCB_COLOR_MAP.boardOutline,
6085
- soldermask: {
6086
- top: colorOverrides?.soldermask?.top ?? DEFAULT_PCB_COLOR_MAP.soldermask.top,
6087
- bottom: colorOverrides?.soldermask?.bottom ?? DEFAULT_PCB_COLOR_MAP.soldermask.bottom
6088
- },
6089
- soldermaskOverCopper: {
6090
- top: colorOverrides?.soldermaskOverCopper?.top ?? DEFAULT_PCB_COLOR_MAP.soldermaskOverCopper.top,
6091
- bottom: colorOverrides?.soldermaskOverCopper?.bottom ?? DEFAULT_PCB_COLOR_MAP.soldermaskOverCopper.bottom
6092
- },
6093
- soldermaskWithCopperUnderneath: {
6094
- top: colorOverrides?.soldermaskWithCopperUnderneath?.top ?? DEFAULT_PCB_COLOR_MAP.soldermaskWithCopperUnderneath.top,
6095
- bottom: colorOverrides?.soldermaskWithCopperUnderneath?.bottom ?? DEFAULT_PCB_COLOR_MAP.soldermaskWithCopperUnderneath.bottom
6096
- },
6097
- substrate: colorOverrides?.substrate ?? DEFAULT_PCB_COLOR_MAP.substrate,
6098
- courtyard: colorOverrides?.courtyard ?? DEFAULT_PCB_COLOR_MAP.courtyard,
6099
- keepout: colorOverrides?.keepout ?? DEFAULT_PCB_COLOR_MAP.keepout,
6100
- debugComponent: {
6101
- fill: colorOverrides?.debugComponent?.fill ?? DEFAULT_PCB_COLOR_MAP.debugComponent.fill,
6102
- stroke: colorOverrides?.debugComponent?.stroke ?? DEFAULT_PCB_COLOR_MAP.debugComponent.stroke
6103
- }
6104
- };
6069
+ // lib/pcb/get-pcb-bounds-from-circuit-json.ts
6070
+ import { distance as distance2 } from "circuit-json";
6071
+ function getPcbBoundsFromCircuitJson(circuitJson) {
6105
6072
  let minX = Number.POSITIVE_INFINITY;
6106
6073
  let minY = Number.POSITIVE_INFINITY;
6107
6074
  let maxX = Number.NEGATIVE_INFINITY;
@@ -6121,53 +6088,73 @@ function convertCircuitJsonToPcbSvg(circuitJson, options) {
6121
6088
  continue;
6122
6089
  }
6123
6090
  const center = panel.center ?? { x: width / 2, y: height / 2 };
6124
- updateBounds(center, width, height);
6091
+ updateBounds({ center, width, height });
6125
6092
  } else if (circuitJsonElm.type === "pcb_board") {
6126
6093
  if (circuitJsonElm.outline && Array.isArray(circuitJsonElm.outline) && circuitJsonElm.outline.length >= 3) {
6127
6094
  updateBoundsToIncludeOutline(circuitJsonElm.outline);
6128
6095
  updateBoardBoundsToIncludeOutline(circuitJsonElm.outline);
6129
6096
  } else if ("center" in circuitJsonElm && "width" in circuitJsonElm && "height" in circuitJsonElm) {
6130
- updateBounds(
6131
- circuitJsonElm.center,
6132
- circuitJsonElm.width,
6133
- circuitJsonElm.height
6134
- );
6135
- updateBoardBounds(
6136
- circuitJsonElm.center,
6137
- circuitJsonElm.width,
6138
- circuitJsonElm.height
6139
- );
6097
+ updateBounds({
6098
+ center: circuitJsonElm.center,
6099
+ width: circuitJsonElm.width,
6100
+ height: circuitJsonElm.height
6101
+ });
6102
+ updateBoardBounds({
6103
+ center: circuitJsonElm.center,
6104
+ width: circuitJsonElm.width,
6105
+ height: circuitJsonElm.height
6106
+ });
6140
6107
  }
6141
6108
  } else if (circuitJsonElm.type === "pcb_smtpad") {
6142
6109
  const pad = circuitJsonElm;
6143
6110
  if (pad.shape === "rect" || pad.shape === "rotated_rect" || pad.shape === "pill") {
6144
- updateBounds({ x: pad.x, y: pad.y }, pad.width, pad.height);
6111
+ updateBounds({
6112
+ center: { x: pad.x, y: pad.y },
6113
+ width: pad.width,
6114
+ height: pad.height
6115
+ });
6145
6116
  } else if (pad.shape === "circle") {
6146
6117
  const radius = distance2.parse(pad.radius);
6147
6118
  if (radius !== void 0) {
6148
- updateBounds({ x: pad.x, y: pad.y }, radius * 2, radius * 2);
6119
+ updateBounds({
6120
+ center: { x: pad.x, y: pad.y },
6121
+ width: radius * 2,
6122
+ height: radius * 2
6123
+ });
6149
6124
  }
6150
6125
  } else if (pad.shape === "polygon") {
6151
6126
  updateTraceBounds(pad.points);
6152
6127
  }
6153
6128
  } else if ("x" in circuitJsonElm && "y" in circuitJsonElm) {
6154
- updateBounds({ x: circuitJsonElm.x, y: circuitJsonElm.y }, 0, 0);
6129
+ updateBounds({
6130
+ center: { x: circuitJsonElm.x, y: circuitJsonElm.y },
6131
+ width: 0,
6132
+ height: 0
6133
+ });
6155
6134
  } else if ("route" in circuitJsonElm) {
6156
6135
  updateTraceBounds(circuitJsonElm.route);
6157
6136
  } else if (circuitJsonElm.type === "pcb_note_rect" || circuitJsonElm.type === "pcb_fabrication_note_rect") {
6158
- updateBounds(
6159
- circuitJsonElm.center,
6160
- circuitJsonElm.width,
6161
- circuitJsonElm.height
6162
- );
6137
+ updateBounds({
6138
+ center: circuitJsonElm.center,
6139
+ width: circuitJsonElm.width,
6140
+ height: circuitJsonElm.height
6141
+ });
6163
6142
  } else if (circuitJsonElm.type === "pcb_cutout") {
6164
6143
  const cutout = circuitJsonElm;
6165
6144
  if (cutout.shape === "rect") {
6166
- updateBounds(cutout.center, cutout.width, cutout.height);
6145
+ updateBounds({
6146
+ center: cutout.center,
6147
+ width: cutout.width,
6148
+ height: cutout.height
6149
+ });
6167
6150
  } else if (cutout.shape === "circle") {
6168
6151
  const radius = distance2.parse(cutout.radius);
6169
6152
  if (radius !== void 0) {
6170
- updateBounds(cutout.center, radius * 2, radius * 2);
6153
+ updateBounds({
6154
+ center: cutout.center,
6155
+ width: radius * 2,
6156
+ height: radius * 2
6157
+ });
6171
6158
  }
6172
6159
  } else if (cutout.shape === "polygon") {
6173
6160
  updateTraceBounds(cutout.points);
@@ -6180,34 +6167,262 @@ function convertCircuitJsonToPcbSvg(circuitJson, options) {
6180
6167
  } else if (circuitJsonElm.type === "pcb_keepout") {
6181
6168
  const keepout = circuitJsonElm;
6182
6169
  if (keepout.shape === "rect") {
6183
- updateBounds(keepout.center, keepout.width, keepout.height);
6170
+ updateBounds({
6171
+ center: keepout.center,
6172
+ width: keepout.width,
6173
+ height: keepout.height
6174
+ });
6184
6175
  } else if (keepout.shape === "circle") {
6185
6176
  const radius = typeof keepout.radius === "number" ? keepout.radius : distance2.parse(keepout.radius) ?? 0;
6186
6177
  if (radius > 0) {
6187
- updateBounds(keepout.center, radius * 2, radius * 2);
6178
+ updateBounds({
6179
+ center: keepout.center,
6180
+ width: radius * 2,
6181
+ height: radius * 2
6182
+ });
6188
6183
  }
6189
6184
  }
6190
6185
  } else if (circuitJsonElm.type === "pcb_silkscreen_text" || circuitJsonElm.type === "pcb_silkscreen_rect" || circuitJsonElm.type === "pcb_silkscreen_circle" || circuitJsonElm.type === "pcb_silkscreen_line" || circuitJsonElm.type === "pcb_silkscreen_oval") {
6191
6186
  updateSilkscreenBounds(circuitJsonElm);
6192
6187
  } else if (circuitJsonElm.type === "pcb_copper_text") {
6193
- updateBounds(circuitJsonElm.anchor_position, 0, 0);
6188
+ updateBounds({
6189
+ center: circuitJsonElm.anchor_position,
6190
+ width: 0,
6191
+ height: 0
6192
+ });
6194
6193
  } else if (circuitJsonElm.type === "pcb_copper_pour") {
6195
6194
  if (circuitJsonElm.shape === "rect") {
6196
- updateBounds(
6197
- circuitJsonElm.center,
6198
- circuitJsonElm.width,
6199
- circuitJsonElm.height
6200
- );
6195
+ updateBounds({
6196
+ center: circuitJsonElm.center,
6197
+ width: circuitJsonElm.width,
6198
+ height: circuitJsonElm.height
6199
+ });
6201
6200
  } else if (circuitJsonElm.shape === "polygon") {
6202
6201
  updateTraceBounds(circuitJsonElm.points);
6203
6202
  }
6204
6203
  }
6205
6204
  }
6205
+ return {
6206
+ minX,
6207
+ minY,
6208
+ maxX,
6209
+ maxY,
6210
+ boardMinX,
6211
+ boardMinY,
6212
+ boardMaxX,
6213
+ boardMaxY,
6214
+ hasBounds,
6215
+ hasBoardBounds
6216
+ };
6217
+ function updateBounds({
6218
+ center,
6219
+ width,
6220
+ height
6221
+ }) {
6222
+ if (!center) return;
6223
+ const centerX = distance2.parse(center.x);
6224
+ const centerY = distance2.parse(center.y);
6225
+ if (centerX === void 0 || centerY === void 0) return;
6226
+ const numericWidth = distance2.parse(width) ?? 0;
6227
+ const numericHeight = distance2.parse(height) ?? 0;
6228
+ const halfWidth = numericWidth / 2;
6229
+ const halfHeight = numericHeight / 2;
6230
+ minX = Math.min(minX, centerX - halfWidth);
6231
+ minY = Math.min(minY, centerY - halfHeight);
6232
+ maxX = Math.max(maxX, centerX + halfWidth);
6233
+ maxY = Math.max(maxY, centerY + halfHeight);
6234
+ hasBounds = true;
6235
+ }
6236
+ function updateBoardBounds({
6237
+ center,
6238
+ width,
6239
+ height
6240
+ }) {
6241
+ if (!center) return;
6242
+ const centerX = distance2.parse(center.x);
6243
+ const centerY = distance2.parse(center.y);
6244
+ if (centerX === void 0 || centerY === void 0) return;
6245
+ const numericWidth = distance2.parse(width) ?? 0;
6246
+ const numericHeight = distance2.parse(height) ?? 0;
6247
+ const halfWidth = numericWidth / 2;
6248
+ const halfHeight = numericHeight / 2;
6249
+ boardMinX = Math.min(boardMinX, centerX - halfWidth);
6250
+ boardMinY = Math.min(boardMinY, centerY - halfHeight);
6251
+ boardMaxX = Math.max(boardMaxX, centerX + halfWidth);
6252
+ boardMaxY = Math.max(boardMaxY, centerY + halfHeight);
6253
+ hasBounds = true;
6254
+ hasBoardBounds = true;
6255
+ }
6256
+ function updateBoundsToIncludeOutline(outline) {
6257
+ let updated = false;
6258
+ for (const point of outline) {
6259
+ const x = distance2.parse(point.x);
6260
+ const y = distance2.parse(point.y);
6261
+ if (x === void 0 || y === void 0) continue;
6262
+ minX = Math.min(minX, x);
6263
+ minY = Math.min(minY, y);
6264
+ maxX = Math.max(maxX, x);
6265
+ maxY = Math.max(maxY, y);
6266
+ updated = true;
6267
+ }
6268
+ if (updated) {
6269
+ hasBounds = true;
6270
+ }
6271
+ }
6272
+ function updateBoardBoundsToIncludeOutline(outline) {
6273
+ let updated = false;
6274
+ for (const point of outline) {
6275
+ const x = distance2.parse(point.x);
6276
+ const y = distance2.parse(point.y);
6277
+ if (x === void 0 || y === void 0) continue;
6278
+ boardMinX = Math.min(boardMinX, x);
6279
+ boardMinY = Math.min(boardMinY, y);
6280
+ boardMaxX = Math.max(boardMaxX, x);
6281
+ boardMaxY = Math.max(boardMaxY, y);
6282
+ updated = true;
6283
+ }
6284
+ if (updated) {
6285
+ hasBounds = true;
6286
+ hasBoardBounds = true;
6287
+ }
6288
+ }
6289
+ function updateTraceBounds(route) {
6290
+ let updated = false;
6291
+ for (const point of route) {
6292
+ const x = distance2.parse(point?.x);
6293
+ const y = distance2.parse(point?.y);
6294
+ if (x === void 0 || y === void 0) continue;
6295
+ minX = Math.min(minX, x);
6296
+ minY = Math.min(minY, y);
6297
+ maxX = Math.max(maxX, x);
6298
+ maxY = Math.max(maxY, y);
6299
+ updated = true;
6300
+ }
6301
+ if (updated) {
6302
+ hasBounds = true;
6303
+ }
6304
+ }
6305
+ function updateSilkscreenBounds(item) {
6306
+ if (item.type === "pcb_silkscreen_text") {
6307
+ updateBounds({ center: item.anchor_position, width: 0, height: 0 });
6308
+ } else if (item.type === "pcb_silkscreen_path") {
6309
+ updateTraceBounds(item.route);
6310
+ } else if (item.type === "pcb_silkscreen_rect") {
6311
+ updateBounds({
6312
+ center: item.center,
6313
+ width: item.width,
6314
+ height: item.height
6315
+ });
6316
+ } else if (item.type === "pcb_silkscreen_circle") {
6317
+ const radius = distance2.parse(item.radius);
6318
+ if (radius !== void 0) {
6319
+ updateBounds({
6320
+ center: item.center,
6321
+ width: radius * 2,
6322
+ height: radius * 2
6323
+ });
6324
+ }
6325
+ } else if (item.type === "pcb_silkscreen_line") {
6326
+ updateBounds({ center: { x: item.x1, y: item.y1 }, width: 0, height: 0 });
6327
+ updateBounds({ center: { x: item.x2, y: item.y2 }, width: 0, height: 0 });
6328
+ } else if (item.type === "pcb_silkscreen_oval") {
6329
+ const radiusX = distance2.parse(item.radius_x);
6330
+ const radiusY = distance2.parse(item.radius_y);
6331
+ if (radiusX !== void 0 && radiusY !== void 0) {
6332
+ updateBounds({
6333
+ center: item.center,
6334
+ width: radiusX * 2,
6335
+ height: radiusY * 2
6336
+ });
6337
+ }
6338
+ } else if (item.type === "pcb_cutout") {
6339
+ const cutout = item;
6340
+ if (cutout.shape === "rect") {
6341
+ updateBounds({
6342
+ center: cutout.center,
6343
+ width: cutout.width,
6344
+ height: cutout.height
6345
+ });
6346
+ } else if (cutout.shape === "circle") {
6347
+ const radius = distance2.parse(cutout.radius);
6348
+ if (radius !== void 0) {
6349
+ updateBounds({
6350
+ center: cutout.center,
6351
+ width: radius * 2,
6352
+ height: radius * 2
6353
+ });
6354
+ }
6355
+ } else if (cutout.shape === "polygon") {
6356
+ updateTraceBounds(cutout.points);
6357
+ } else if (cutout.shape === "path") {
6358
+ const cutoutPath = cutout;
6359
+ if (cutoutPath.route && Array.isArray(cutoutPath.route)) {
6360
+ updateTraceBounds(cutoutPath.route);
6361
+ }
6362
+ }
6363
+ }
6364
+ }
6365
+ }
6366
+
6367
+ // lib/pcb/convert-circuit-json-to-pcb-svg.ts
6368
+ function convertCircuitJsonToPcbSvg(circuitJson, options) {
6369
+ const drawPaddingOutsideBoard = options?.drawPaddingOutsideBoard ?? true;
6370
+ const layer = options?.layer;
6371
+ const colorOverrides = options?.colorOverrides;
6372
+ const copperColors = {
6373
+ ...DEFAULT_PCB_COLOR_MAP.copper
6374
+ };
6375
+ if (colorOverrides?.copper) {
6376
+ for (const [layerName, color] of Object.entries(colorOverrides.copper)) {
6377
+ if (color !== void 0) {
6378
+ copperColors[layerName] = color;
6379
+ }
6380
+ }
6381
+ }
6382
+ const colorMap2 = {
6383
+ copper: copperColors,
6384
+ drill: colorOverrides?.drill ?? DEFAULT_PCB_COLOR_MAP.drill,
6385
+ silkscreen: {
6386
+ top: colorOverrides?.silkscreen?.top ?? DEFAULT_PCB_COLOR_MAP.silkscreen.top,
6387
+ bottom: colorOverrides?.silkscreen?.bottom ?? DEFAULT_PCB_COLOR_MAP.silkscreen.bottom
6388
+ },
6389
+ boardOutline: colorOverrides?.boardOutline ?? DEFAULT_PCB_COLOR_MAP.boardOutline,
6390
+ soldermask: {
6391
+ top: colorOverrides?.soldermask?.top ?? DEFAULT_PCB_COLOR_MAP.soldermask.top,
6392
+ bottom: colorOverrides?.soldermask?.bottom ?? DEFAULT_PCB_COLOR_MAP.soldermask.bottom
6393
+ },
6394
+ soldermaskOverCopper: {
6395
+ top: colorOverrides?.soldermaskOverCopper?.top ?? DEFAULT_PCB_COLOR_MAP.soldermaskOverCopper.top,
6396
+ bottom: colorOverrides?.soldermaskOverCopper?.bottom ?? DEFAULT_PCB_COLOR_MAP.soldermaskOverCopper.bottom
6397
+ },
6398
+ soldermaskWithCopperUnderneath: {
6399
+ top: colorOverrides?.soldermaskWithCopperUnderneath?.top ?? DEFAULT_PCB_COLOR_MAP.soldermaskWithCopperUnderneath.top,
6400
+ bottom: colorOverrides?.soldermaskWithCopperUnderneath?.bottom ?? DEFAULT_PCB_COLOR_MAP.soldermaskWithCopperUnderneath.bottom
6401
+ },
6402
+ substrate: colorOverrides?.substrate ?? DEFAULT_PCB_COLOR_MAP.substrate,
6403
+ courtyard: colorOverrides?.courtyard ?? DEFAULT_PCB_COLOR_MAP.courtyard,
6404
+ keepout: colorOverrides?.keepout ?? DEFAULT_PCB_COLOR_MAP.keepout,
6405
+ debugComponent: {
6406
+ fill: colorOverrides?.debugComponent?.fill ?? DEFAULT_PCB_COLOR_MAP.debugComponent.fill,
6407
+ stroke: colorOverrides?.debugComponent?.stroke ?? DEFAULT_PCB_COLOR_MAP.debugComponent.stroke
6408
+ }
6409
+ };
6410
+ const {
6411
+ minX,
6412
+ minY,
6413
+ maxX,
6414
+ maxY,
6415
+ boardMinX,
6416
+ boardMinY,
6417
+ boardMaxX,
6418
+ boardMaxY,
6419
+ hasBoardBounds
6420
+ } = getPcbBoundsFromCircuitJson(circuitJson);
6206
6421
  const padding = drawPaddingOutsideBoard ? 1 : 0;
6207
- const boundsMinX = drawPaddingOutsideBoard || !Number.isFinite(boardMinX) ? minX : boardMinX;
6208
- const boundsMinY = drawPaddingOutsideBoard || !Number.isFinite(boardMinY) ? minY : boardMinY;
6209
- const boundsMaxX = drawPaddingOutsideBoard || !Number.isFinite(boardMaxX) ? maxX : boardMaxX;
6210
- const boundsMaxY = drawPaddingOutsideBoard || !Number.isFinite(boardMaxY) ? maxY : boardMaxY;
6422
+ const boundsMinX = drawPaddingOutsideBoard || !hasBoardBounds ? minX : boardMinX;
6423
+ const boundsMinY = drawPaddingOutsideBoard || !hasBoardBounds ? minY : boardMinY;
6424
+ const boundsMaxX = drawPaddingOutsideBoard || !hasBoardBounds ? maxX : boardMaxX;
6425
+ const boundsMaxY = drawPaddingOutsideBoard || !hasBoardBounds ? maxY : boardMaxY;
6211
6426
  const circuitWidth = boundsMaxX - boundsMinX + 2 * padding;
6212
6427
  const circuitHeight = boundsMaxY - boundsMinY + 2 * padding;
6213
6428
  let svgWidth = options?.width ?? 800;
@@ -6356,126 +6571,6 @@ function convertCircuitJsonToPcbSvg(circuitJson, options) {
6356
6571
  console.error("Error stringifying SVG object:", error);
6357
6572
  throw error;
6358
6573
  }
6359
- function updateBounds(center, width, height) {
6360
- if (!center) return;
6361
- const centerX = distance2.parse(center.x);
6362
- const centerY = distance2.parse(center.y);
6363
- if (centerX === void 0 || centerY === void 0) return;
6364
- const numericWidth = distance2.parse(width) ?? 0;
6365
- const numericHeight = distance2.parse(height) ?? 0;
6366
- const halfWidth = numericWidth / 2;
6367
- const halfHeight = numericHeight / 2;
6368
- minX = Math.min(minX, centerX - halfWidth);
6369
- minY = Math.min(minY, centerY - halfHeight);
6370
- maxX = Math.max(maxX, centerX + halfWidth);
6371
- maxY = Math.max(maxY, centerY + halfHeight);
6372
- hasBounds = true;
6373
- }
6374
- function updateBoardBounds(center, width, height) {
6375
- if (!center) return;
6376
- const centerX = distance2.parse(center.x);
6377
- const centerY = distance2.parse(center.y);
6378
- if (centerX === void 0 || centerY === void 0) return;
6379
- const numericWidth = distance2.parse(width) ?? 0;
6380
- const numericHeight = distance2.parse(height) ?? 0;
6381
- const halfWidth = numericWidth / 2;
6382
- const halfHeight = numericHeight / 2;
6383
- boardMinX = Math.min(boardMinX, centerX - halfWidth);
6384
- boardMinY = Math.min(boardMinY, centerY - halfHeight);
6385
- boardMaxX = Math.max(boardMaxX, centerX + halfWidth);
6386
- boardMaxY = Math.max(boardMaxY, centerY + halfHeight);
6387
- hasBounds = true;
6388
- hasBoardBounds = true;
6389
- }
6390
- function updateBoundsToIncludeOutline(outline) {
6391
- let updated = false;
6392
- for (const point of outline) {
6393
- const x = distance2.parse(point.x);
6394
- const y = distance2.parse(point.y);
6395
- if (x === void 0 || y === void 0) continue;
6396
- minX = Math.min(minX, x);
6397
- minY = Math.min(minY, y);
6398
- maxX = Math.max(maxX, x);
6399
- maxY = Math.max(maxY, y);
6400
- updated = true;
6401
- }
6402
- if (updated) {
6403
- hasBounds = true;
6404
- }
6405
- }
6406
- function updateBoardBoundsToIncludeOutline(outline) {
6407
- let updated = false;
6408
- for (const point of outline) {
6409
- const x = distance2.parse(point.x);
6410
- const y = distance2.parse(point.y);
6411
- if (x === void 0 || y === void 0) continue;
6412
- boardMinX = Math.min(boardMinX, x);
6413
- boardMinY = Math.min(boardMinY, y);
6414
- boardMaxX = Math.max(boardMaxX, x);
6415
- boardMaxY = Math.max(boardMaxY, y);
6416
- updated = true;
6417
- }
6418
- if (updated) {
6419
- hasBounds = true;
6420
- hasBoardBounds = true;
6421
- }
6422
- }
6423
- function updateTraceBounds(route) {
6424
- let updated = false;
6425
- for (const point of route) {
6426
- const x = distance2.parse(point?.x);
6427
- const y = distance2.parse(point?.y);
6428
- if (x === void 0 || y === void 0) continue;
6429
- minX = Math.min(minX, x);
6430
- minY = Math.min(minY, y);
6431
- maxX = Math.max(maxX, x);
6432
- maxY = Math.max(maxY, y);
6433
- updated = true;
6434
- }
6435
- if (updated) {
6436
- hasBounds = true;
6437
- }
6438
- }
6439
- function updateSilkscreenBounds(item) {
6440
- if (item.type === "pcb_silkscreen_text") {
6441
- updateBounds(item.anchor_position, 0, 0);
6442
- } else if (item.type === "pcb_silkscreen_path") {
6443
- updateTraceBounds(item.route);
6444
- } else if (item.type === "pcb_silkscreen_rect") {
6445
- updateBounds(item.center, item.width, item.height);
6446
- } else if (item.type === "pcb_silkscreen_circle") {
6447
- const radius = distance2.parse(item.radius);
6448
- if (radius !== void 0) {
6449
- updateBounds(item.center, radius * 2, radius * 2);
6450
- }
6451
- } else if (item.type === "pcb_silkscreen_line") {
6452
- updateBounds({ x: item.x1, y: item.y1 }, 0, 0);
6453
- updateBounds({ x: item.x2, y: item.y2 }, 0, 0);
6454
- } else if (item.type === "pcb_silkscreen_oval") {
6455
- const radiusX = distance2.parse(item.radius_x);
6456
- const radiusY = distance2.parse(item.radius_y);
6457
- if (radiusX !== void 0 && radiusY !== void 0) {
6458
- updateBounds(item.center, radiusX * 2, radiusY * 2);
6459
- }
6460
- } else if (item.type === "pcb_cutout") {
6461
- const cutout = item;
6462
- if (cutout.shape === "rect") {
6463
- updateBounds(cutout.center, cutout.width, cutout.height);
6464
- } else if (cutout.shape === "circle") {
6465
- const radius = distance2.parse(cutout.radius);
6466
- if (radius !== void 0) {
6467
- updateBounds(cutout.center, radius * 2, radius * 2);
6468
- }
6469
- } else if (cutout.shape === "polygon") {
6470
- updateTraceBounds(cutout.points);
6471
- } else if (cutout.shape === "path") {
6472
- const cutoutPath = cutout;
6473
- if (cutoutPath.route && Array.isArray(cutoutPath.route)) {
6474
- updateTraceBounds(cutoutPath.route);
6475
- }
6476
- }
6477
- }
6478
- }
6479
6574
  }
6480
6575
  function createSvgObjects({
6481
6576
  elm,
@@ -13271,7 +13366,7 @@ function formatNumber2(value) {
13271
13366
  }
13272
13367
 
13273
13368
  // lib/pcb/convert-circuit-json-to-solder-paste-mask.ts
13274
- import { distance as distance3 } from "circuit-json";
13369
+ import { distance as distance4 } from "circuit-json";
13275
13370
  import { stringify as stringify7 } from "svgson";
13276
13371
  import {
13277
13372
  applyToPoint as applyToPoint76,
@@ -13389,8 +13484,8 @@ function convertCircuitJsonToSolderPasteMask(circuitJson, options) {
13389
13484
  }
13390
13485
  } else if (item.type === "pcb_panel") {
13391
13486
  const panel = item;
13392
- const width = distance3.parse(panel.width);
13393
- const height = distance3.parse(panel.height);
13487
+ const width = distance4.parse(panel.width);
13488
+ const height = distance4.parse(panel.height);
13394
13489
  if (width !== void 0 && height !== void 0) {
13395
13490
  const center = panel.center ?? { x: width / 2, y: height / 2 };
13396
13491
  updateBounds(center, width, height);