circuit-to-canvas 0.0.26 → 0.0.28

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/README.md CHANGED
@@ -53,6 +53,7 @@ This checklist tracks PCB drawing features from [circuit-to-svg](https://github.
53
53
  - [x] `pcb_silkscreen_circle` - Circles on silkscreen
54
54
  - [x] `pcb_silkscreen_line` - Lines on silkscreen
55
55
  - [x] `pcb_silkscreen_path` - Paths/routes on silkscreen
56
+ - [x] `pcb_silkscreen_pill` - Pill shapes (rounded rectangles) on silkscreen
56
57
 
57
58
  ### Copper Text
58
59
 
@@ -72,17 +73,17 @@ This checklist tracks PCB drawing features from [circuit-to-svg](https://github.
72
73
  ### Fabrication Notes
73
74
 
74
75
  - [x] `pcb_fabrication_note_text` - Fabrication note text
75
- - [ ] `pcb_fabrication_note_rect` - Fabrication note rectangles
76
- - [ ] `pcb_fabrication_note_path` - Fabrication note paths
76
+ - [x] `pcb_fabrication_note_rect` - Fabrication note rectangles
77
+ - [x] `pcb_fabrication_note_path` - Fabrication note paths
77
78
  - [ ] `pcb_fabrication_note_dimension` - Fabrication dimension annotations
78
79
 
79
80
  ### Annotation/Notes
80
81
 
81
- - [ ] `pcb_note_text` - General note text
82
- - [ ] `pcb_note_rect` - Note rectangles
83
- - [ ] `pcb_note_path` - Note paths
84
- - [ ] `pcb_note_line` - Note lines
85
- - [ ] `pcb_note_dimension` - Dimension annotations
82
+ - [x] `pcb_note_text` - General note text
83
+ - [x] `pcb_note_rect` - Note rectangles
84
+ - [x] `pcb_note_path` - Note paths
85
+ - [x] `pcb_note_line` - Note lines
86
+ - [x] `pcb_note_dimension` - Dimension annotations
86
87
 
87
88
  ### Panel Support
88
89
 
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { AnyCircuitElement, NinePointAnchor, PcbPlatedHole, PCBVia, PCBHole, PcbSmtPad, PCBTrace, PcbBoard, PcbSilkscreenText, PcbSilkscreenRect, PcbSilkscreenCircle, PcbSilkscreenLine, PcbSilkscreenPath, PcbCutout, PcbCopperPour, PcbCopperText, PcbFabricationNoteText, PcbFabricationNoteRect, PcbNoteRect, PcbFabricationNotePath, PcbNotePath, PcbNoteText, PcbNoteDimension } from 'circuit-json';
1
+ import { AnyCircuitElement, NinePointAnchor, PcbPlatedHole, PCBVia, PCBHole, PcbSmtPad, PCBTrace, PcbBoard, PcbSilkscreenText, PcbSilkscreenRect, PcbSilkscreenCircle, PcbSilkscreenLine, PcbSilkscreenPath, PcbSilkscreenPill, PcbCutout, PcbCopperPour, PcbCopperText, PcbFabricationNoteText, PcbFabricationNoteRect, PcbNoteRect, PcbFabricationNotePath, PcbNotePath, PcbNoteText, PcbNoteDimension } from 'circuit-json';
2
2
  import { Matrix } from 'transformation-matrix';
3
3
 
4
4
  /**
@@ -154,9 +154,11 @@ interface DrawPillParams {
154
154
  };
155
155
  width: number;
156
156
  height: number;
157
- fill: string;
157
+ fill?: string;
158
158
  realToCanvasMat: Matrix;
159
159
  rotation?: number;
160
+ stroke?: string;
161
+ strokeWidth?: number;
160
162
  }
161
163
  declare function drawPill(params: DrawPillParams): void;
162
164
 
@@ -341,6 +343,14 @@ interface DrawPcbSilkscreenPathParams {
341
343
  }
342
344
  declare function drawPcbSilkscreenPath(params: DrawPcbSilkscreenPathParams): void;
343
345
 
346
+ interface DrawPcbSilkscreenPillParams {
347
+ ctx: CanvasContext;
348
+ pill: PcbSilkscreenPill;
349
+ realToCanvasMat: Matrix;
350
+ colorMap: PcbColorMap;
351
+ }
352
+ declare function drawPcbSilkscreenPill(params: DrawPcbSilkscreenPillParams): void;
353
+
344
354
  interface DrawPcbCutoutParams {
345
355
  ctx: CanvasContext;
346
356
  cutout: PcbCutout;
@@ -421,4 +431,4 @@ interface DrawPcbNoteDimensionParams {
421
431
  }
422
432
  declare function drawPcbNoteDimension(params: DrawPcbNoteDimensionParams): void;
423
433
 
424
- export { type AlphabetLayout, type AnchorAlignment, type CameraBounds, type CanvasContext, CircuitToCanvasDrawer, type CopperColorMap, type CopperLayerName, DEFAULT_PCB_COLOR_MAP, type DrawArrowParams, type DrawCircleParams, type DrawContext, type DrawElementsOptions, type DrawLineParams, type DrawOvalParams, type DrawPathParams, type DrawPcbBoardParams, type DrawPcbCopperPourParams, type DrawPcbCopperTextParams, type DrawPcbCutoutParams, type DrawPcbFabricationNotePathParams, type DrawPcbFabricationNoteRectParams, type DrawPcbFabricationNoteTextParams, type DrawPcbHoleParams, type DrawPcbNoteDimensionParams, type DrawPcbNotePathParams, type DrawPcbNoteRectParams, type DrawPcbNoteTextParams, type DrawPcbPlatedHoleParams, type DrawPcbSilkscreenCircleParams, type DrawPcbSilkscreenLineParams, type DrawPcbSilkscreenPathParams, type DrawPcbSilkscreenRectParams, type DrawPcbSilkscreenTextParams, type DrawPcbSmtPadParams, type DrawPcbTraceParams, type DrawPcbViaParams, type DrawPillParams, type DrawPolygonParams, type DrawRectParams, type DrawTextParams, type DrawerConfig, type PcbColorMap, drawArrow, drawCircle, drawLine, drawOval, drawPath, drawPcbBoard, drawPcbCopperPour, drawPcbCopperText, drawPcbCutout, drawPcbFabricationNotePath, drawPcbFabricationNoteRect, drawPcbFabricationNoteText, drawPcbHole, drawPcbNoteDimension, drawPcbNotePath, drawPcbNoteRect, drawPcbNoteText, drawPcbPlatedHole, drawPcbSilkscreenCircle, drawPcbSilkscreenLine, drawPcbSilkscreenPath, drawPcbSilkscreenRect, drawPcbSilkscreenText, drawPcbSmtPad, drawPcbTrace, drawPcbVia, drawPill, drawPolygon, drawRect, drawText, getAlphabetLayout, getTextStartPosition, strokeAlphabetText };
434
+ export { type AlphabetLayout, type AnchorAlignment, type CameraBounds, type CanvasContext, CircuitToCanvasDrawer, type CopperColorMap, type CopperLayerName, DEFAULT_PCB_COLOR_MAP, type DrawArrowParams, type DrawCircleParams, type DrawContext, type DrawElementsOptions, type DrawLineParams, type DrawOvalParams, type DrawPathParams, type DrawPcbBoardParams, type DrawPcbCopperPourParams, type DrawPcbCopperTextParams, type DrawPcbCutoutParams, type DrawPcbFabricationNotePathParams, type DrawPcbFabricationNoteRectParams, type DrawPcbFabricationNoteTextParams, type DrawPcbHoleParams, type DrawPcbNoteDimensionParams, type DrawPcbNotePathParams, type DrawPcbNoteRectParams, type DrawPcbNoteTextParams, type DrawPcbPlatedHoleParams, type DrawPcbSilkscreenCircleParams, type DrawPcbSilkscreenLineParams, type DrawPcbSilkscreenPathParams, type DrawPcbSilkscreenPillParams, type DrawPcbSilkscreenRectParams, type DrawPcbSilkscreenTextParams, type DrawPcbSmtPadParams, type DrawPcbTraceParams, type DrawPcbViaParams, type DrawPillParams, type DrawPolygonParams, type DrawRectParams, type DrawTextParams, type DrawerConfig, type PcbColorMap, drawArrow, drawCircle, drawLine, drawOval, drawPath, drawPcbBoard, drawPcbCopperPour, drawPcbCopperText, drawPcbCutout, drawPcbFabricationNotePath, drawPcbFabricationNoteRect, drawPcbFabricationNoteText, drawPcbHole, drawPcbNoteDimension, drawPcbNotePath, drawPcbNoteRect, drawPcbNoteText, drawPcbPlatedHole, drawPcbSilkscreenCircle, drawPcbSilkscreenLine, drawPcbSilkscreenPath, drawPcbSilkscreenPill, drawPcbSilkscreenRect, drawPcbSilkscreenText, drawPcbSmtPad, drawPcbTrace, drawPcbVia, drawPill, drawPolygon, drawRect, drawText, getAlphabetLayout, getTextStartPosition, strokeAlphabetText };
package/dist/index.js CHANGED
@@ -150,11 +150,14 @@ function drawPill(params) {
150
150
  height,
151
151
  fill,
152
152
  realToCanvasMat,
153
- rotation = 0
153
+ rotation = 0,
154
+ stroke,
155
+ strokeWidth
154
156
  } = params;
155
157
  const [cx, cy] = applyToPoint4(realToCanvasMat, [center.x, center.y]);
156
158
  const scaledWidth = width * Math.abs(realToCanvasMat.a);
157
159
  const scaledHeight = height * Math.abs(realToCanvasMat.a);
160
+ const scaledStrokeWidth = strokeWidth ? strokeWidth * Math.abs(realToCanvasMat.a) : void 0;
158
161
  ctx.save();
159
162
  ctx.translate(cx, cy);
160
163
  if (rotation !== 0) {
@@ -181,8 +184,15 @@ function drawPill(params) {
181
184
  ctx.arc(0, 0, scaledWidth / 2, 0, Math.PI * 2);
182
185
  }
183
186
  ctx.closePath();
184
- ctx.fillStyle = fill;
185
- ctx.fill();
187
+ if (fill) {
188
+ ctx.fillStyle = fill;
189
+ ctx.fill();
190
+ }
191
+ if (stroke && scaledStrokeWidth) {
192
+ ctx.strokeStyle = stroke;
193
+ ctx.lineWidth = scaledStrokeWidth;
194
+ ctx.stroke();
195
+ }
186
196
  ctx.restore();
187
197
  }
188
198
 
@@ -891,6 +901,25 @@ function drawPcbSilkscreenPath(params) {
891
901
  }
892
902
  }
893
903
 
904
+ // lib/drawer/elements/pcb-silkscreen-pill.ts
905
+ function layerToSilkscreenColor6(layer, colorMap) {
906
+ return layer === "bottom" ? colorMap.silkscreen.bottom : colorMap.silkscreen.top;
907
+ }
908
+ function drawPcbSilkscreenPill(params) {
909
+ const { ctx, pill, realToCanvasMat, colorMap } = params;
910
+ const color = layerToSilkscreenColor6(pill.layer, colorMap);
911
+ const strokeWidth = 0.2;
912
+ drawPill({
913
+ ctx,
914
+ center: pill.center,
915
+ width: pill.width,
916
+ height: pill.height,
917
+ stroke: color,
918
+ strokeWidth,
919
+ realToCanvasMat
920
+ });
921
+ }
922
+
894
923
  // lib/drawer/elements/pcb-cutout.ts
895
924
  function drawPcbCutout(params) {
896
925
  const { ctx, cutout, realToCanvasMat, colorMap } = params;
@@ -1520,6 +1549,14 @@ var CircuitToCanvasDrawer = class {
1520
1549
  colorMap: this.colorMap
1521
1550
  });
1522
1551
  }
1552
+ if (element.type === "pcb_silkscreen_pill") {
1553
+ drawPcbSilkscreenPill({
1554
+ ctx: this.ctx,
1555
+ pill: element,
1556
+ realToCanvasMat: this.realToCanvasMat,
1557
+ colorMap: this.colorMap
1558
+ });
1559
+ }
1523
1560
  if (element.type === "pcb_cutout") {
1524
1561
  drawPcbCutout({
1525
1562
  ctx: this.ctx,
@@ -1634,6 +1671,7 @@ export {
1634
1671
  drawPcbSilkscreenCircle,
1635
1672
  drawPcbSilkscreenLine,
1636
1673
  drawPcbSilkscreenPath,
1674
+ drawPcbSilkscreenPill,
1637
1675
  drawPcbSilkscreenRect,
1638
1676
  drawPcbSilkscreenText,
1639
1677
  drawPcbSmtPad,
@@ -11,6 +11,7 @@ import type {
11
11
  PcbSilkscreenCircle,
12
12
  PcbSilkscreenLine,
13
13
  PcbSilkscreenPath,
14
+ PcbSilkscreenPill,
14
15
  PcbCutout,
15
16
  PcbCopperPour,
16
17
  PcbCopperText,
@@ -43,6 +44,7 @@ import { drawPcbSilkscreenRect } from "./elements/pcb-silkscreen-rect"
43
44
  import { drawPcbSilkscreenCircle } from "./elements/pcb-silkscreen-circle"
44
45
  import { drawPcbSilkscreenLine } from "./elements/pcb-silkscreen-line"
45
46
  import { drawPcbSilkscreenPath } from "./elements/pcb-silkscreen-path"
47
+ import { drawPcbSilkscreenPill } from "./elements/pcb-silkscreen-pill"
46
48
  import { drawPcbCutout } from "./elements/pcb-cutout"
47
49
  import { drawPcbCopperPour } from "./elements/pcb-copper-pour"
48
50
  import { drawPcbCopperText } from "./elements/pcb-copper-text"
@@ -252,6 +254,15 @@ export class CircuitToCanvasDrawer {
252
254
  })
253
255
  }
254
256
 
257
+ if (element.type === "pcb_silkscreen_pill") {
258
+ drawPcbSilkscreenPill({
259
+ ctx: this.ctx,
260
+ pill: element as PcbSilkscreenPill,
261
+ realToCanvasMat: this.realToCanvasMat,
262
+ colorMap: this.colorMap,
263
+ })
264
+ }
265
+
255
266
  if (element.type === "pcb_cutout") {
256
267
  drawPcbCutout({
257
268
  ctx: this.ctx,
@@ -38,6 +38,11 @@ export {
38
38
  type DrawPcbSilkscreenPathParams,
39
39
  } from "./pcb-silkscreen-path"
40
40
 
41
+ export {
42
+ drawPcbSilkscreenPill,
43
+ type DrawPcbSilkscreenPillParams,
44
+ } from "./pcb-silkscreen-pill"
45
+
41
46
  export { drawPcbCutout, type DrawPcbCutoutParams } from "./pcb-cutout"
42
47
 
43
48
  export {
@@ -0,0 +1,37 @@
1
+ import type { PcbSilkscreenPill } from "circuit-json"
2
+ import type { Matrix } from "transformation-matrix"
3
+ import type { PcbColorMap, CanvasContext } from "../types"
4
+ import { drawPill } from "../shapes/pill"
5
+
6
+ export interface DrawPcbSilkscreenPillParams {
7
+ ctx: CanvasContext
8
+ pill: PcbSilkscreenPill
9
+ realToCanvasMat: Matrix
10
+ colorMap: PcbColorMap
11
+ }
12
+
13
+ function layerToSilkscreenColor(layer: string, colorMap: PcbColorMap): string {
14
+ return layer === "bottom"
15
+ ? colorMap.silkscreen.bottom
16
+ : colorMap.silkscreen.top
17
+ }
18
+
19
+ export function drawPcbSilkscreenPill(
20
+ params: DrawPcbSilkscreenPillParams,
21
+ ): void {
22
+ const { ctx, pill, realToCanvasMat, colorMap } = params
23
+
24
+ const color = layerToSilkscreenColor(pill.layer, colorMap)
25
+ const strokeWidth = 0.2
26
+
27
+ // Draw as boundary/outline, not filled
28
+ drawPill({
29
+ ctx,
30
+ center: pill.center,
31
+ width: pill.width,
32
+ height: pill.height,
33
+ stroke: color,
34
+ strokeWidth,
35
+ realToCanvasMat,
36
+ })
37
+ }
@@ -7,9 +7,11 @@ export interface DrawPillParams {
7
7
  center: { x: number; y: number }
8
8
  width: number
9
9
  height: number
10
- fill: string
10
+ fill?: string
11
11
  realToCanvasMat: Matrix
12
12
  rotation?: number
13
+ stroke?: string
14
+ strokeWidth?: number
13
15
  }
14
16
 
15
17
  export function drawPill(params: DrawPillParams): void {
@@ -21,11 +23,16 @@ export function drawPill(params: DrawPillParams): void {
21
23
  fill,
22
24
  realToCanvasMat,
23
25
  rotation = 0,
26
+ stroke,
27
+ strokeWidth,
24
28
  } = params
25
29
 
26
30
  const [cx, cy] = applyToPoint(realToCanvasMat, [center.x, center.y])
27
31
  const scaledWidth = width * Math.abs(realToCanvasMat.a)
28
32
  const scaledHeight = height * Math.abs(realToCanvasMat.a)
33
+ const scaledStrokeWidth = strokeWidth
34
+ ? strokeWidth * Math.abs(realToCanvasMat.a)
35
+ : undefined
29
36
 
30
37
  ctx.save()
31
38
  ctx.translate(cx, cy)
@@ -62,7 +69,17 @@ export function drawPill(params: DrawPillParams): void {
62
69
  }
63
70
 
64
71
  ctx.closePath()
65
- ctx.fillStyle = fill
66
- ctx.fill()
72
+
73
+ if (fill) {
74
+ ctx.fillStyle = fill
75
+ ctx.fill()
76
+ }
77
+
78
+ if (stroke && scaledStrokeWidth) {
79
+ ctx.strokeStyle = stroke
80
+ ctx.lineWidth = scaledStrokeWidth
81
+ ctx.stroke()
82
+ }
83
+
67
84
  ctx.restore()
68
85
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "circuit-to-canvas",
3
3
  "main": "dist/index.js",
4
- "version": "0.0.26",
4
+ "version": "0.0.28",
5
5
  "type": "module",
6
6
  "scripts": {
7
7
  "build": "tsup-node ./lib/index.ts --format esm --dts",
@@ -17,7 +17,7 @@
17
17
  "@tscircuit/math-utils": "^0.0.29",
18
18
  "@types/bun": "latest",
19
19
  "bun-match-svg": "^0.0.14",
20
- "circuit-json": "^0.0.335",
20
+ "circuit-json": "^0.0.342",
21
21
  "circuit-json-to-connectivity-map": "^0.0.23",
22
22
  "circuit-to-svg": "^0.0.297",
23
23
  "looks-same": "^10.0.1",
@@ -0,0 +1,55 @@
1
+ import { expect, test } from "bun:test"
2
+ import { createCanvas } from "@napi-rs/canvas"
3
+ import type { PcbSilkscreenPill } from "circuit-json"
4
+ import { CircuitToCanvasDrawer } from "../../lib/drawer"
5
+
6
+ test("draw silkscreen pill", async () => {
7
+ const canvas = createCanvas(400, 400)
8
+ const ctx = canvas.getContext("2d")
9
+ const drawer = new CircuitToCanvasDrawer(ctx)
10
+
11
+ ctx.fillStyle = "#1a1a1a"
12
+ ctx.fillRect(0, 0, 400, 400)
13
+
14
+ const pill: PcbSilkscreenPill = {
15
+ type: "pcb_silkscreen_pill",
16
+ pcb_silkscreen_pill_id: "pill1",
17
+ pcb_component_id: "component1",
18
+ layer: "top",
19
+ center: { x: 200, y: 200 },
20
+ width: 240,
21
+ height: 80,
22
+ }
23
+
24
+ drawer.drawElements([pill])
25
+
26
+ await expect(canvas.toBuffer("image/png")).toMatchPngSnapshot(
27
+ import.meta.path,
28
+ )
29
+ })
30
+
31
+ test("draw silkscreen pill bottom layer", async () => {
32
+ const canvas = createCanvas(400, 400)
33
+ const ctx = canvas.getContext("2d")
34
+ const drawer = new CircuitToCanvasDrawer(ctx)
35
+
36
+ ctx.fillStyle = "#1a1a1a"
37
+ ctx.fillRect(0, 0, 400, 400)
38
+
39
+ const pill: PcbSilkscreenPill = {
40
+ type: "pcb_silkscreen_pill",
41
+ pcb_silkscreen_pill_id: "pill1",
42
+ pcb_component_id: "component1",
43
+ layer: "bottom",
44
+ center: { x: 200, y: 200 },
45
+ width: 160,
46
+ height: 120,
47
+ }
48
+
49
+ drawer.drawElements([pill])
50
+
51
+ await expect(canvas.toBuffer("image/png")).toMatchPngSnapshot(
52
+ import.meta.path,
53
+ "silkscreen-pill-bottom",
54
+ )
55
+ })