circuit-to-canvas 0.0.22 → 0.0.24

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/dist/index.d.ts +8 -4
  2. package/dist/index.js +26 -6
  3. package/lib/drawer/CircuitToCanvasDrawer.ts +5 -7
  4. package/lib/drawer/elements/index.ts +17 -5
  5. package/lib/drawer/elements/pcb-silkscreen-circle.ts +33 -0
  6. package/lib/drawer/elements/pcb-silkscreen-line.ts +34 -0
  7. package/lib/drawer/elements/pcb-silkscreen-path.ts +44 -0
  8. package/lib/drawer/elements/pcb-silkscreen-rect.ts +34 -0
  9. package/lib/drawer/elements/pcb-silkscreen-text.ts +71 -0
  10. package/package.json +1 -1
  11. package/tests/elements/__snapshots__/fabrication-note-text-full-charset.snap.png +0 -0
  12. package/tests/elements/__snapshots__/pcb-board.snap.png +0 -0
  13. package/tests/elements/pcb-silkscreen-circle.test.ts +29 -0
  14. package/tests/elements/pcb-silkscreen-line.test.ts +31 -0
  15. package/tests/elements/pcb-silkscreen-on-component.test.ts +75 -0
  16. package/tests/elements/pcb-silkscreen-path.test.ts +36 -0
  17. package/tests/elements/pcb-silkscreen-rect.test.ts +30 -0
  18. package/tests/elements/pcb-silkscreen-text-bottom-rotated.test.ts +84 -0
  19. package/tests/elements/pcb-silkscreen-text-bottom.test.ts +31 -0
  20. package/tests/elements/pcb-silkscreen-text-rotated.test.ts +32 -0
  21. package/tests/elements/pcb-silkscreen-text.test.ts +31 -0
  22. package/tests/elements/pcb-smtpad-bottom-layer.test.ts +30 -0
  23. package/tests/elements/pcb-smtpad-circle.test.ts +29 -0
  24. package/tests/elements/pcb-smtpad-pill.test.ts +31 -0
  25. package/tests/elements/pcb-smtpad-polygon.test.ts +34 -0
  26. package/tests/elements/pcb-smtpad-rect-border-radius.test.ts +31 -0
  27. package/tests/elements/pcb-smtpad-rect.test.ts +30 -0
  28. package/tests/elements/pcb-smtpad-rotated-rect.test.ts +31 -0
  29. package/lib/drawer/elements/pcb-silkscreen.ts +0 -186
  30. package/tests/elements/pcb-silkscreen.test.ts +0 -362
  31. package/tests/elements/pcb-smtpad.test.ts +0 -198
  32. /package/tests/elements/__snapshots__/{silkscreen-circle.snap.png → pcb-silkscreen-circle.snap.png} +0 -0
  33. /package/tests/elements/__snapshots__/{silkscreen-line.snap.png → pcb-silkscreen-line.snap.png} +0 -0
  34. /package/tests/elements/__snapshots__/{silkscreen-on-component.snap.png → pcb-silkscreen-on-component.snap.png} +0 -0
  35. /package/tests/elements/__snapshots__/{silkscreen-path.snap.png → pcb-silkscreen-path.snap.png} +0 -0
  36. /package/tests/elements/__snapshots__/{silkscreen-rect.snap.png → pcb-silkscreen-rect.snap.png} +0 -0
  37. /package/tests/elements/__snapshots__/{silkscreen-text-bottom-rotated.snap.png → pcb-silkscreen-text-bottom-rotated.snap.png} +0 -0
  38. /package/tests/elements/__snapshots__/{silkscreen-text-bottom.snap.png → pcb-silkscreen-text-bottom.snap.png} +0 -0
  39. /package/tests/elements/__snapshots__/{silkscreen-text-rotated.snap.png → pcb-silkscreen-text-rotated.snap.png} +0 -0
  40. /package/tests/elements/__snapshots__/{pcb-silkscreen.snap.png → pcb-silkscreen-text.snap.png} +0 -0
  41. /package/tests/elements/__snapshots__/{bottom-layer-pad.snap.png → pcb-smtpad-bottom-layer.snap.png} +0 -0
  42. /package/tests/elements/__snapshots__/{circular-pad.snap.png → pcb-smtpad-circle.snap.png} +0 -0
  43. /package/tests/elements/__snapshots__/{pill-pad.snap.png → pcb-smtpad-pill.snap.png} +0 -0
  44. /package/tests/elements/__snapshots__/{polygon-pad.snap.png → pcb-smtpad-polygon.snap.png} +0 -0
  45. /package/tests/elements/__snapshots__/{rect-pad-with-border-radius.snap.png → pcb-smtpad-rect-border-radius.snap.png} +0 -0
  46. /package/tests/elements/__snapshots__/{pcb-smtpad.snap.png → pcb-smtpad-rect.snap.png} +0 -0
  47. /package/tests/elements/__snapshots__/{rotated-rect-pad.snap.png → pcb-smtpad-rotated-rect.snap.png} +0 -0
package/dist/index.d.ts CHANGED
@@ -300,34 +300,38 @@ interface DrawPcbSilkscreenTextParams {
300
300
  realToCanvasMat: Matrix;
301
301
  colorMap: PcbColorMap;
302
302
  }
303
+ declare function drawPcbSilkscreenText(params: DrawPcbSilkscreenTextParams): void;
304
+
303
305
  interface DrawPcbSilkscreenRectParams {
304
306
  ctx: CanvasContext;
305
307
  rect: PcbSilkscreenRect;
306
308
  realToCanvasMat: Matrix;
307
309
  colorMap: PcbColorMap;
308
310
  }
311
+ declare function drawPcbSilkscreenRect(params: DrawPcbSilkscreenRectParams): void;
312
+
309
313
  interface DrawPcbSilkscreenCircleParams {
310
314
  ctx: CanvasContext;
311
315
  circle: PcbSilkscreenCircle;
312
316
  realToCanvasMat: Matrix;
313
317
  colorMap: PcbColorMap;
314
318
  }
319
+ declare function drawPcbSilkscreenCircle(params: DrawPcbSilkscreenCircleParams): void;
320
+
315
321
  interface DrawPcbSilkscreenLineParams {
316
322
  ctx: CanvasContext;
317
323
  line: PcbSilkscreenLine;
318
324
  realToCanvasMat: Matrix;
319
325
  colorMap: PcbColorMap;
320
326
  }
327
+ declare function drawPcbSilkscreenLine(params: DrawPcbSilkscreenLineParams): void;
328
+
321
329
  interface DrawPcbSilkscreenPathParams {
322
330
  ctx: CanvasContext;
323
331
  path: PcbSilkscreenPath;
324
332
  realToCanvasMat: Matrix;
325
333
  colorMap: PcbColorMap;
326
334
  }
327
- declare function drawPcbSilkscreenText(params: DrawPcbSilkscreenTextParams): void;
328
- declare function drawPcbSilkscreenRect(params: DrawPcbSilkscreenRectParams): void;
329
- declare function drawPcbSilkscreenCircle(params: DrawPcbSilkscreenCircleParams): void;
330
- declare function drawPcbSilkscreenLine(params: DrawPcbSilkscreenLineParams): void;
331
335
  declare function drawPcbSilkscreenPath(params: DrawPcbSilkscreenPathParams): void;
332
336
 
333
337
  interface DrawPcbCutoutParams {
package/dist/index.js CHANGED
@@ -647,7 +647,7 @@ function drawPcbBoard(params) {
647
647
  }
648
648
  }
649
649
 
650
- // lib/drawer/elements/pcb-silkscreen.ts
650
+ // lib/drawer/elements/pcb-silkscreen-text.ts
651
651
  import { applyToPoint as applyToPoint9 } from "transformation-matrix";
652
652
 
653
653
  // lib/drawer/shapes/text/text.ts
@@ -765,7 +765,7 @@ function drawText(params) {
765
765
  ctx.restore();
766
766
  }
767
767
 
768
- // lib/drawer/elements/pcb-silkscreen.ts
768
+ // lib/drawer/elements/pcb-silkscreen-text.ts
769
769
  function layerToSilkscreenColor(layer, colorMap) {
770
770
  return layer === "bottom" ? colorMap.silkscreen.bottom : colorMap.silkscreen.top;
771
771
  }
@@ -803,9 +803,14 @@ function drawPcbSilkscreenText(params) {
803
803
  strokeAlphabetText(ctx, content, layout, startPos.x, startPos.y);
804
804
  ctx.restore();
805
805
  }
806
+
807
+ // lib/drawer/elements/pcb-silkscreen-rect.ts
808
+ function layerToSilkscreenColor2(layer, colorMap) {
809
+ return layer === "bottom" ? colorMap.silkscreen.bottom : colorMap.silkscreen.top;
810
+ }
806
811
  function drawPcbSilkscreenRect(params) {
807
812
  const { ctx, rect, realToCanvasMat, colorMap } = params;
808
- const color = layerToSilkscreenColor(rect.layer, colorMap);
813
+ const color = layerToSilkscreenColor2(rect.layer, colorMap);
809
814
  drawRect({
810
815
  ctx,
811
816
  center: rect.center,
@@ -815,9 +820,14 @@ function drawPcbSilkscreenRect(params) {
815
820
  realToCanvasMat
816
821
  });
817
822
  }
823
+
824
+ // lib/drawer/elements/pcb-silkscreen-circle.ts
825
+ function layerToSilkscreenColor3(layer, colorMap) {
826
+ return layer === "bottom" ? colorMap.silkscreen.bottom : colorMap.silkscreen.top;
827
+ }
818
828
  function drawPcbSilkscreenCircle(params) {
819
829
  const { ctx, circle, realToCanvasMat, colorMap } = params;
820
- const color = layerToSilkscreenColor(circle.layer, colorMap);
830
+ const color = layerToSilkscreenColor3(circle.layer, colorMap);
821
831
  drawCircle({
822
832
  ctx,
823
833
  center: circle.center,
@@ -826,9 +836,14 @@ function drawPcbSilkscreenCircle(params) {
826
836
  realToCanvasMat
827
837
  });
828
838
  }
839
+
840
+ // lib/drawer/elements/pcb-silkscreen-line.ts
841
+ function layerToSilkscreenColor4(layer, colorMap) {
842
+ return layer === "bottom" ? colorMap.silkscreen.bottom : colorMap.silkscreen.top;
843
+ }
829
844
  function drawPcbSilkscreenLine(params) {
830
845
  const { ctx, line, realToCanvasMat, colorMap } = params;
831
- const color = layerToSilkscreenColor(line.layer, colorMap);
846
+ const color = layerToSilkscreenColor4(line.layer, colorMap);
832
847
  drawLine({
833
848
  ctx,
834
849
  start: { x: line.x1, y: line.y1 },
@@ -838,9 +853,14 @@ function drawPcbSilkscreenLine(params) {
838
853
  realToCanvasMat
839
854
  });
840
855
  }
856
+
857
+ // lib/drawer/elements/pcb-silkscreen-path.ts
858
+ function layerToSilkscreenColor5(layer, colorMap) {
859
+ return layer === "bottom" ? colorMap.silkscreen.bottom : colorMap.silkscreen.top;
860
+ }
841
861
  function drawPcbSilkscreenPath(params) {
842
862
  const { ctx, path, realToCanvasMat, colorMap } = params;
843
- const color = layerToSilkscreenColor(path.layer, colorMap);
863
+ const color = layerToSilkscreenColor5(path.layer, colorMap);
844
864
  if (!path.route || path.route.length < 2) return;
845
865
  for (let i = 0; i < path.route.length - 1; i++) {
846
866
  const start = path.route[i];
@@ -38,13 +38,11 @@ import { drawPcbHole } from "./elements/pcb-hole"
38
38
  import { drawPcbSmtPad } from "./elements/pcb-smtpad"
39
39
  import { drawPcbTrace } from "./elements/pcb-trace"
40
40
  import { drawPcbBoard } from "./elements/pcb-board"
41
- import {
42
- drawPcbSilkscreenText,
43
- drawPcbSilkscreenRect,
44
- drawPcbSilkscreenCircle,
45
- drawPcbSilkscreenLine,
46
- drawPcbSilkscreenPath,
47
- } from "./elements/pcb-silkscreen"
41
+ import { drawPcbSilkscreenText } from "./elements/pcb-silkscreen-text"
42
+ import { drawPcbSilkscreenRect } from "./elements/pcb-silkscreen-rect"
43
+ import { drawPcbSilkscreenCircle } from "./elements/pcb-silkscreen-circle"
44
+ import { drawPcbSilkscreenLine } from "./elements/pcb-silkscreen-line"
45
+ import { drawPcbSilkscreenPath } from "./elements/pcb-silkscreen-path"
48
46
  import { drawPcbCutout } from "./elements/pcb-cutout"
49
47
  import { drawPcbCopperPour } from "./elements/pcb-copper-pour"
50
48
  import { drawPcbCopperText } from "./elements/pcb-copper-text"
@@ -15,16 +15,28 @@ export { drawPcbBoard, type DrawPcbBoardParams } from "./pcb-board"
15
15
 
16
16
  export {
17
17
  drawPcbSilkscreenText,
18
- drawPcbSilkscreenRect,
19
- drawPcbSilkscreenCircle,
20
- drawPcbSilkscreenLine,
21
- drawPcbSilkscreenPath,
22
18
  type DrawPcbSilkscreenTextParams,
19
+ } from "./pcb-silkscreen-text"
20
+
21
+ export {
22
+ drawPcbSilkscreenRect,
23
23
  type DrawPcbSilkscreenRectParams,
24
+ } from "./pcb-silkscreen-rect"
25
+
26
+ export {
27
+ drawPcbSilkscreenCircle,
24
28
  type DrawPcbSilkscreenCircleParams,
29
+ } from "./pcb-silkscreen-circle"
30
+
31
+ export {
32
+ drawPcbSilkscreenLine,
25
33
  type DrawPcbSilkscreenLineParams,
34
+ } from "./pcb-silkscreen-line"
35
+
36
+ export {
37
+ drawPcbSilkscreenPath,
26
38
  type DrawPcbSilkscreenPathParams,
27
- } from "./pcb-silkscreen"
39
+ } from "./pcb-silkscreen-path"
28
40
 
29
41
  export { drawPcbCutout, type DrawPcbCutoutParams } from "./pcb-cutout"
30
42
 
@@ -0,0 +1,33 @@
1
+ import type { PcbSilkscreenCircle } from "circuit-json"
2
+ import type { Matrix } from "transformation-matrix"
3
+ import type { PcbColorMap, CanvasContext } from "../types"
4
+ import { drawCircle } from "../shapes/circle"
5
+
6
+ export interface DrawPcbSilkscreenCircleParams {
7
+ ctx: CanvasContext
8
+ circle: PcbSilkscreenCircle
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 drawPcbSilkscreenCircle(
20
+ params: DrawPcbSilkscreenCircleParams,
21
+ ): void {
22
+ const { ctx, circle, realToCanvasMat, colorMap } = params
23
+
24
+ const color = layerToSilkscreenColor(circle.layer, colorMap)
25
+
26
+ drawCircle({
27
+ ctx,
28
+ center: circle.center,
29
+ radius: circle.radius,
30
+ fill: color,
31
+ realToCanvasMat,
32
+ })
33
+ }
@@ -0,0 +1,34 @@
1
+ import type { PcbSilkscreenLine } from "circuit-json"
2
+ import type { Matrix } from "transformation-matrix"
3
+ import type { PcbColorMap, CanvasContext } from "../types"
4
+ import { drawLine } from "../shapes/line"
5
+
6
+ export interface DrawPcbSilkscreenLineParams {
7
+ ctx: CanvasContext
8
+ line: PcbSilkscreenLine
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 drawPcbSilkscreenLine(
20
+ params: DrawPcbSilkscreenLineParams,
21
+ ): void {
22
+ const { ctx, line, realToCanvasMat, colorMap } = params
23
+
24
+ const color = layerToSilkscreenColor(line.layer, colorMap)
25
+
26
+ drawLine({
27
+ ctx,
28
+ start: { x: line.x1, y: line.y1 },
29
+ end: { x: line.x2, y: line.y2 },
30
+ strokeWidth: line.stroke_width ?? 0.1,
31
+ stroke: color,
32
+ realToCanvasMat,
33
+ })
34
+ }
@@ -0,0 +1,44 @@
1
+ import type { PcbSilkscreenPath } from "circuit-json"
2
+ import type { Matrix } from "transformation-matrix"
3
+ import type { PcbColorMap, CanvasContext } from "../types"
4
+ import { drawLine } from "../shapes/line"
5
+
6
+ export interface DrawPcbSilkscreenPathParams {
7
+ ctx: CanvasContext
8
+ path: PcbSilkscreenPath
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 drawPcbSilkscreenPath(
20
+ params: DrawPcbSilkscreenPathParams,
21
+ ): void {
22
+ const { ctx, path, realToCanvasMat, colorMap } = params
23
+
24
+ const color = layerToSilkscreenColor(path.layer, colorMap)
25
+
26
+ if (!path.route || path.route.length < 2) return
27
+
28
+ // Draw each segment of the path
29
+ for (let i = 0; i < path.route.length - 1; i++) {
30
+ const start = path.route[i]
31
+ const end = path.route[i + 1]
32
+
33
+ if (!start || !end) continue
34
+
35
+ drawLine({
36
+ ctx,
37
+ start: { x: start.x, y: start.y },
38
+ end: { x: end.x, y: end.y },
39
+ strokeWidth: path.stroke_width ?? 0.1,
40
+ stroke: color,
41
+ realToCanvasMat,
42
+ })
43
+ }
44
+ }
@@ -0,0 +1,34 @@
1
+ import type { PcbSilkscreenRect } from "circuit-json"
2
+ import type { Matrix } from "transformation-matrix"
3
+ import type { PcbColorMap, CanvasContext } from "../types"
4
+ import { drawRect } from "../shapes/rect"
5
+
6
+ export interface DrawPcbSilkscreenRectParams {
7
+ ctx: CanvasContext
8
+ rect: PcbSilkscreenRect
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 drawPcbSilkscreenRect(
20
+ params: DrawPcbSilkscreenRectParams,
21
+ ): void {
22
+ const { ctx, rect, realToCanvasMat, colorMap } = params
23
+
24
+ const color = layerToSilkscreenColor(rect.layer, colorMap)
25
+
26
+ drawRect({
27
+ ctx,
28
+ center: rect.center,
29
+ width: rect.width,
30
+ height: rect.height,
31
+ fill: color,
32
+ realToCanvasMat,
33
+ })
34
+ }
@@ -0,0 +1,71 @@
1
+ import type { PcbSilkscreenText } from "circuit-json"
2
+ import type { Matrix } from "transformation-matrix"
3
+ import { applyToPoint } from "transformation-matrix"
4
+ import type { PcbColorMap, CanvasContext } from "../types"
5
+ import {
6
+ getAlphabetLayout,
7
+ strokeAlphabetText,
8
+ getTextStartPosition,
9
+ type AnchorAlignment,
10
+ } from "../shapes/text"
11
+
12
+ export interface DrawPcbSilkscreenTextParams {
13
+ ctx: CanvasContext
14
+ text: PcbSilkscreenText
15
+ realToCanvasMat: Matrix
16
+ colorMap: PcbColorMap
17
+ }
18
+
19
+ function layerToSilkscreenColor(layer: string, colorMap: PcbColorMap): string {
20
+ return layer === "bottom"
21
+ ? colorMap.silkscreen.bottom
22
+ : colorMap.silkscreen.top
23
+ }
24
+
25
+ function mapAnchorAlignment(alignment?: string): AnchorAlignment {
26
+ if (!alignment) return "center"
27
+ return alignment as AnchorAlignment
28
+ }
29
+
30
+ export function drawPcbSilkscreenText(
31
+ params: DrawPcbSilkscreenTextParams,
32
+ ): void {
33
+ const { ctx, text, realToCanvasMat, colorMap } = params
34
+
35
+ const content = text.text ?? ""
36
+ if (!content) return
37
+
38
+ const color = layerToSilkscreenColor(text.layer, colorMap)
39
+ const [x, y] = applyToPoint(realToCanvasMat, [
40
+ text.anchor_position.x,
41
+ text.anchor_position.y,
42
+ ])
43
+ const scale = Math.abs(realToCanvasMat.a)
44
+ const fontSize = (text.font_size ?? 1) * scale
45
+ const rotation = text.ccw_rotation ?? 0
46
+
47
+ const layout = getAlphabetLayout(content, fontSize)
48
+ const alignment = mapAnchorAlignment(text.anchor_alignment)
49
+ const startPos = getTextStartPosition(alignment, layout)
50
+
51
+ ctx.save()
52
+ ctx.translate(x, y)
53
+
54
+ // Apply rotation (CCW rotation in degrees)
55
+ if (rotation !== 0) {
56
+ ctx.rotate(-rotation * (Math.PI / 180))
57
+ }
58
+
59
+ if (text.layer === "bottom") {
60
+ ctx.scale(-1, 1)
61
+ }
62
+
63
+ ctx.lineWidth = layout.strokeWidth
64
+ ctx.lineCap = "round"
65
+ ctx.lineJoin = "round"
66
+ ctx.strokeStyle = color
67
+
68
+ strokeAlphabetText(ctx, content, layout, startPos.x, startPos.y)
69
+
70
+ ctx.restore()
71
+ }
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.22",
4
+ "version": "0.0.24",
5
5
  "type": "module",
6
6
  "scripts": {
7
7
  "build": "tsup-node ./lib/index.ts --format esm --dts",
@@ -0,0 +1,29 @@
1
+ import { expect, test } from "bun:test"
2
+ import { createCanvas } from "@napi-rs/canvas"
3
+ import type { PcbSilkscreenCircle } from "circuit-json"
4
+ import { CircuitToCanvasDrawer } from "../../lib/drawer"
5
+
6
+ test("draw silkscreen circle", async () => {
7
+ const canvas = createCanvas(100, 100)
8
+ const ctx = canvas.getContext("2d")
9
+ const drawer = new CircuitToCanvasDrawer(ctx)
10
+
11
+ ctx.fillStyle = "#1a1a1a"
12
+ ctx.fillRect(0, 0, 100, 100)
13
+
14
+ const circle: PcbSilkscreenCircle = {
15
+ type: "pcb_silkscreen_circle",
16
+ pcb_silkscreen_circle_id: "circle1",
17
+ pcb_component_id: "component1",
18
+ layer: "top",
19
+ center: { x: 50, y: 50 },
20
+ radius: 20,
21
+ stroke_width: 0.2,
22
+ }
23
+
24
+ drawer.drawElements([circle])
25
+
26
+ await expect(canvas.toBuffer("image/png")).toMatchPngSnapshot(
27
+ import.meta.path,
28
+ )
29
+ })
@@ -0,0 +1,31 @@
1
+ import { expect, test } from "bun:test"
2
+ import { createCanvas } from "@napi-rs/canvas"
3
+ import type { PcbSilkscreenLine } from "circuit-json"
4
+ import { CircuitToCanvasDrawer } from "../../lib/drawer"
5
+
6
+ test("draw silkscreen line", async () => {
7
+ const canvas = createCanvas(100, 100)
8
+ const ctx = canvas.getContext("2d")
9
+ const drawer = new CircuitToCanvasDrawer(ctx)
10
+
11
+ ctx.fillStyle = "#1a1a1a"
12
+ ctx.fillRect(0, 0, 100, 100)
13
+
14
+ const line: PcbSilkscreenLine = {
15
+ type: "pcb_silkscreen_line",
16
+ pcb_silkscreen_line_id: "line1",
17
+ pcb_component_id: "component1",
18
+ layer: "top",
19
+ x1: 20,
20
+ y1: 20,
21
+ x2: 80,
22
+ y2: 80,
23
+ stroke_width: 2,
24
+ }
25
+
26
+ drawer.drawElements([line])
27
+
28
+ await expect(canvas.toBuffer("image/png")).toMatchPngSnapshot(
29
+ import.meta.path,
30
+ )
31
+ })
@@ -0,0 +1,75 @@
1
+ import { expect, test } from "bun:test"
2
+ import { createCanvas } from "@napi-rs/canvas"
3
+ import { CircuitToCanvasDrawer } from "../../lib/drawer"
4
+
5
+ test("draw silkscreen on component", async () => {
6
+ const canvas = createCanvas(150, 100)
7
+ const ctx = canvas.getContext("2d")
8
+ const drawer = new CircuitToCanvasDrawer(ctx)
9
+
10
+ ctx.fillStyle = "#1a1a1a"
11
+ ctx.fillRect(0, 0, 150, 100)
12
+
13
+ const elements = [
14
+ // Component outline
15
+ {
16
+ type: "pcb_silkscreen_rect" as const,
17
+ pcb_silkscreen_rect_id: "outline1",
18
+ pcb_component_id: "component1",
19
+ layer: "top" as const,
20
+ center: { x: 75, y: 50 },
21
+ width: 60,
22
+ height: 30,
23
+ stroke_width: 0.2,
24
+ },
25
+ // Pin 1 indicator
26
+ {
27
+ type: "pcb_silkscreen_circle" as const,
28
+ pcb_silkscreen_circle_id: "pin1marker",
29
+ pcb_component_id: "component1",
30
+ layer: "top" as const,
31
+ center: { x: 55, y: 40 },
32
+ radius: 3,
33
+ stroke_width: 0.2,
34
+ },
35
+ // Component label
36
+ {
37
+ type: "pcb_silkscreen_text" as const,
38
+ pcb_silkscreen_text_id: "label1",
39
+ pcb_component_id: "component1",
40
+ layer: "top" as const,
41
+ text: "IC1",
42
+ anchor_position: { x: 75, y: 50 },
43
+ anchor_alignment: "center" as const,
44
+ font: "tscircuit2024" as const,
45
+ font_size: 8,
46
+ },
47
+ // SMT pads
48
+ {
49
+ type: "pcb_smtpad" as const,
50
+ pcb_smtpad_id: "pad1",
51
+ shape: "rect" as const,
52
+ x: 55,
53
+ y: 50,
54
+ width: 10,
55
+ height: 5,
56
+ layer: "top" as const,
57
+ },
58
+ {
59
+ type: "pcb_smtpad" as const,
60
+ pcb_smtpad_id: "pad2",
61
+ shape: "rect" as const,
62
+ x: 95,
63
+ y: 50,
64
+ width: 10,
65
+ height: 5,
66
+ layer: "top" as const,
67
+ },
68
+ ]
69
+
70
+ drawer.drawElements(elements)
71
+
72
+ await expect(canvas.toBuffer("image/png")).toMatchPngSnapshot(
73
+ import.meta.path,
74
+ )
75
+ })
@@ -0,0 +1,36 @@
1
+ import { expect, test } from "bun:test"
2
+ import { createCanvas } from "@napi-rs/canvas"
3
+ import type { PcbSilkscreenPath } from "circuit-json"
4
+ import { CircuitToCanvasDrawer } from "../../lib/drawer"
5
+
6
+ test("draw silkscreen path", async () => {
7
+ const canvas = createCanvas(100, 100)
8
+ const ctx = canvas.getContext("2d")
9
+ const drawer = new CircuitToCanvasDrawer(ctx)
10
+
11
+ ctx.fillStyle = "#1a1a1a"
12
+ ctx.fillRect(0, 0, 100, 100)
13
+
14
+ const path: PcbSilkscreenPath = {
15
+ type: "pcb_silkscreen_path",
16
+ pcb_silkscreen_path_id: "path1",
17
+ pcb_component_id: "component1",
18
+ layer: "top",
19
+ route: [
20
+ { x: 10, y: 50 },
21
+ { x: 30, y: 20 },
22
+ { x: 70, y: 20 },
23
+ { x: 90, y: 50 },
24
+ { x: 70, y: 80 },
25
+ { x: 30, y: 80 },
26
+ { x: 10, y: 50 },
27
+ ],
28
+ stroke_width: 2,
29
+ }
30
+
31
+ drawer.drawElements([path])
32
+
33
+ await expect(canvas.toBuffer("image/png")).toMatchPngSnapshot(
34
+ import.meta.path,
35
+ )
36
+ })
@@ -0,0 +1,30 @@
1
+ import { expect, test } from "bun:test"
2
+ import { createCanvas } from "@napi-rs/canvas"
3
+ import type { PcbSilkscreenRect } from "circuit-json"
4
+ import { CircuitToCanvasDrawer } from "../../lib/drawer"
5
+
6
+ test("draw silkscreen rect", async () => {
7
+ const canvas = createCanvas(100, 100)
8
+ const ctx = canvas.getContext("2d")
9
+ const drawer = new CircuitToCanvasDrawer(ctx)
10
+
11
+ ctx.fillStyle = "#1a1a1a"
12
+ ctx.fillRect(0, 0, 100, 100)
13
+
14
+ const rect: PcbSilkscreenRect = {
15
+ type: "pcb_silkscreen_rect",
16
+ pcb_silkscreen_rect_id: "rect1",
17
+ pcb_component_id: "component1",
18
+ layer: "top",
19
+ center: { x: 50, y: 50 },
20
+ width: 40,
21
+ height: 20,
22
+ stroke_width: 0.2,
23
+ }
24
+
25
+ drawer.drawElements([rect])
26
+
27
+ await expect(canvas.toBuffer("image/png")).toMatchPngSnapshot(
28
+ import.meta.path,
29
+ )
30
+ })