circuit-to-canvas 0.0.23 → 0.0.25

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 (42) hide show
  1. package/dist/index.d.ts +18 -11
  2. package/dist/index.js +19 -5
  3. package/lib/drawer/elements/pcb-copper-text.ts +2 -2
  4. package/lib/drawer/elements/pcb-silkscreen-text.ts +7 -1
  5. package/lib/drawer/shapes/text/text.ts +18 -8
  6. package/package.json +1 -1
  7. package/tests/elements/__snapshots__/fabrication-note-text-full-charset.snap.png +0 -0
  8. package/tests/elements/__snapshots__/pcb-board.snap.png +0 -0
  9. package/tests/elements/pcb-silkscreen-circle.test.ts +29 -0
  10. package/tests/elements/pcb-silkscreen-line.test.ts +31 -0
  11. package/tests/elements/pcb-silkscreen-on-component.test.ts +75 -0
  12. package/tests/elements/pcb-silkscreen-path.test.ts +36 -0
  13. package/tests/elements/pcb-silkscreen-rect.test.ts +30 -0
  14. package/tests/elements/pcb-silkscreen-text-bottom-rotated.test.ts +84 -0
  15. package/tests/elements/pcb-silkscreen-text-bottom.test.ts +31 -0
  16. package/tests/elements/pcb-silkscreen-text-rotated.test.ts +32 -0
  17. package/tests/elements/pcb-silkscreen-text.test.ts +31 -0
  18. package/tests/elements/pcb-smtpad-bottom-layer.test.ts +30 -0
  19. package/tests/elements/pcb-smtpad-circle.test.ts +29 -0
  20. package/tests/elements/pcb-smtpad-pill.test.ts +31 -0
  21. package/tests/elements/pcb-smtpad-polygon.test.ts +34 -0
  22. package/tests/elements/pcb-smtpad-rect-border-radius.test.ts +31 -0
  23. package/tests/elements/pcb-smtpad-rect.test.ts +30 -0
  24. package/tests/elements/pcb-smtpad-rotated-rect.test.ts +31 -0
  25. package/tests/elements/pcb-silkscreen.test.ts +0 -362
  26. package/tests/elements/pcb-smtpad.test.ts +0 -198
  27. /package/tests/elements/__snapshots__/{silkscreen-circle.snap.png → pcb-silkscreen-circle.snap.png} +0 -0
  28. /package/tests/elements/__snapshots__/{silkscreen-line.snap.png → pcb-silkscreen-line.snap.png} +0 -0
  29. /package/tests/elements/__snapshots__/{silkscreen-on-component.snap.png → pcb-silkscreen-on-component.snap.png} +0 -0
  30. /package/tests/elements/__snapshots__/{silkscreen-path.snap.png → pcb-silkscreen-path.snap.png} +0 -0
  31. /package/tests/elements/__snapshots__/{silkscreen-rect.snap.png → pcb-silkscreen-rect.snap.png} +0 -0
  32. /package/tests/elements/__snapshots__/{silkscreen-text-bottom-rotated.snap.png → pcb-silkscreen-text-bottom-rotated.snap.png} +0 -0
  33. /package/tests/elements/__snapshots__/{silkscreen-text-bottom.snap.png → pcb-silkscreen-text-bottom.snap.png} +0 -0
  34. /package/tests/elements/__snapshots__/{silkscreen-text-rotated.snap.png → pcb-silkscreen-text-rotated.snap.png} +0 -0
  35. /package/tests/elements/__snapshots__/{pcb-silkscreen.snap.png → pcb-silkscreen-text.snap.png} +0 -0
  36. /package/tests/elements/__snapshots__/{bottom-layer-pad.snap.png → pcb-smtpad-bottom-layer.snap.png} +0 -0
  37. /package/tests/elements/__snapshots__/{circular-pad.snap.png → pcb-smtpad-circle.snap.png} +0 -0
  38. /package/tests/elements/__snapshots__/{pill-pad.snap.png → pcb-smtpad-pill.snap.png} +0 -0
  39. /package/tests/elements/__snapshots__/{polygon-pad.snap.png → pcb-smtpad-polygon.snap.png} +0 -0
  40. /package/tests/elements/__snapshots__/{rect-pad-with-border-radius.snap.png → pcb-smtpad-rect-border-radius.snap.png} +0 -0
  41. /package/tests/elements/__snapshots__/{pcb-smtpad.snap.png → pcb-smtpad-rect.snap.png} +0 -0
  42. /package/tests/elements/__snapshots__/{rotated-rect-pad.snap.png → pcb-smtpad-rotated-rect.snap.png} +0 -0
package/dist/index.d.ts CHANGED
@@ -216,17 +216,14 @@ interface DrawArrowParams {
216
216
  */
217
217
  declare function drawArrow(params: DrawArrowParams): void;
218
218
 
219
- type AlphabetLayout = {
220
- width: number;
221
- height: number;
222
- glyphWidth: number;
223
- letterSpacing: number;
224
- spaceWidth: number;
225
- strokeWidth: number;
226
- };
227
- declare function getAlphabetLayout(text: string, fontSize: number): AlphabetLayout;
228
-
229
- declare function strokeAlphabetText(ctx: CanvasContext, text: string, layout: AlphabetLayout, startX: number, startY: number): void;
219
+ interface StrokeAlphabetTextParams {
220
+ ctx: CanvasContext;
221
+ text: string;
222
+ fontSize: number;
223
+ startX: number;
224
+ startY: number;
225
+ }
226
+ declare function strokeAlphabetText(params: StrokeAlphabetTextParams): void;
230
227
  interface DrawTextParams {
231
228
  ctx: CanvasContext;
232
229
  text: string;
@@ -240,6 +237,16 @@ interface DrawTextParams {
240
237
  }
241
238
  declare function drawText(params: DrawTextParams): void;
242
239
 
240
+ type AlphabetLayout = {
241
+ width: number;
242
+ height: number;
243
+ glyphWidth: number;
244
+ letterSpacing: number;
245
+ spaceWidth: number;
246
+ strokeWidth: number;
247
+ };
248
+ declare function getAlphabetLayout(text: string, fontSize: number): AlphabetLayout;
249
+
243
250
  type AnchorAlignment = NinePointAnchor;
244
251
  declare function getTextStartPosition(alignment: NinePointAnchor, layout: AlphabetLayout): {
245
252
  x: number;
package/dist/index.js CHANGED
@@ -708,7 +708,9 @@ function getTextStartPosition(alignment, layout) {
708
708
 
709
709
  // lib/drawer/shapes/text/text.ts
710
710
  var getGlyphLines = (char) => lineAlphabet[char] ?? lineAlphabet[char.toUpperCase()];
711
- function strokeAlphabetText(ctx, text, layout, startX, startY) {
711
+ function strokeAlphabetText(params) {
712
+ const { ctx, text, fontSize, startX, startY } = params;
713
+ const layout = getAlphabetLayout(text, fontSize);
712
714
  const { glyphWidth, letterSpacing, spaceWidth, height, strokeWidth } = layout;
713
715
  const topY = startY;
714
716
  const characters = Array.from(text);
@@ -761,7 +763,13 @@ function drawText(params) {
761
763
  ctx.lineCap = "round";
762
764
  ctx.lineJoin = "round";
763
765
  ctx.strokeStyle = color;
764
- strokeAlphabetText(ctx, text, layout, startPos.x, startPos.y);
766
+ strokeAlphabetText({
767
+ ctx,
768
+ text,
769
+ fontSize: scaledFontSize,
770
+ startX: startPos.x,
771
+ startY: startPos.y
772
+ });
765
773
  ctx.restore();
766
774
  }
767
775
 
@@ -800,7 +808,13 @@ function drawPcbSilkscreenText(params) {
800
808
  ctx.lineCap = "round";
801
809
  ctx.lineJoin = "round";
802
810
  ctx.strokeStyle = color;
803
- strokeAlphabetText(ctx, content, layout, startPos.x, startPos.y);
811
+ strokeAlphabetText({
812
+ ctx,
813
+ text: content,
814
+ fontSize,
815
+ startX: startPos.x,
816
+ startY: startPos.y
817
+ });
804
818
  ctx.restore();
805
819
  }
806
820
 
@@ -1032,7 +1046,7 @@ function drawPcbCopperText(params) {
1032
1046
  ctx.globalCompositeOperation = "destination-out";
1033
1047
  ctx.fillStyle = "rgba(0,0,0,1)";
1034
1048
  ctx.strokeStyle = "rgba(0,0,0,1)";
1035
- strokeAlphabetText(ctx, content, layout, startX, startY);
1049
+ strokeAlphabetText({ ctx, text: content, fontSize, startX, startY });
1036
1050
  if (previousCompositeOperation) {
1037
1051
  ctx.globalCompositeOperation = previousCompositeOperation;
1038
1052
  } else {
@@ -1040,7 +1054,7 @@ function drawPcbCopperText(params) {
1040
1054
  }
1041
1055
  } else {
1042
1056
  ctx.strokeStyle = textColor;
1043
- strokeAlphabetText(ctx, content, layout, startX, startY);
1057
+ strokeAlphabetText({ ctx, text: content, fontSize, startX, startY });
1044
1058
  }
1045
1059
  ctx.restore();
1046
1060
  }
@@ -88,7 +88,7 @@ export function drawPcbCopperText(params: DrawPcbCopperTextParams): void {
88
88
  ctx.globalCompositeOperation = "destination-out"
89
89
  ctx.fillStyle = "rgba(0,0,0,1)"
90
90
  ctx.strokeStyle = "rgba(0,0,0,1)"
91
- strokeAlphabetText(ctx, content, layout, startX, startY)
91
+ strokeAlphabetText({ ctx, text: content, fontSize, startX, startY })
92
92
  if (previousCompositeOperation) {
93
93
  ctx.globalCompositeOperation = previousCompositeOperation
94
94
  } else {
@@ -96,7 +96,7 @@ export function drawPcbCopperText(params: DrawPcbCopperTextParams): void {
96
96
  }
97
97
  } else {
98
98
  ctx.strokeStyle = textColor
99
- strokeAlphabetText(ctx, content, layout, startX, startY)
99
+ strokeAlphabetText({ ctx, text: content, fontSize, startX, startY })
100
100
  }
101
101
  ctx.restore()
102
102
  }
@@ -65,7 +65,13 @@ export function drawPcbSilkscreenText(
65
65
  ctx.lineJoin = "round"
66
66
  ctx.strokeStyle = color
67
67
 
68
- strokeAlphabetText(ctx, content, layout, startPos.x, startPos.y)
68
+ strokeAlphabetText({
69
+ ctx,
70
+ text: content,
71
+ fontSize,
72
+ startX: startPos.x,
73
+ startY: startPos.y,
74
+ })
69
75
 
70
76
  ctx.restore()
71
77
  }
@@ -9,13 +9,17 @@ import { getTextStartPosition } from "./getTextStartPosition"
9
9
  const getGlyphLines = (char: string) =>
10
10
  lineAlphabet[char] ?? lineAlphabet[char.toUpperCase()]
11
11
 
12
- export function strokeAlphabetText(
13
- ctx: CanvasContext,
14
- text: string,
15
- layout: AlphabetLayout,
16
- startX: number,
17
- startY: number,
18
- ): void {
12
+ export interface StrokeAlphabetTextParams {
13
+ ctx: CanvasContext
14
+ text: string
15
+ fontSize: number
16
+ startX: number
17
+ startY: number
18
+ }
19
+
20
+ export function strokeAlphabetText(params: StrokeAlphabetTextParams): void {
21
+ const { ctx, text, fontSize, startX, startY } = params
22
+ const layout = getAlphabetLayout(text, fontSize)
19
23
  const { glyphWidth, letterSpacing, spaceWidth, height, strokeWidth } = layout
20
24
  const topY = startY
21
25
  const characters = Array.from(text)
@@ -92,7 +96,13 @@ export function drawText(params: DrawTextParams): void {
92
96
  ctx.lineJoin = "round"
93
97
  ctx.strokeStyle = color
94
98
 
95
- strokeAlphabetText(ctx, text, layout, startPos.x, startPos.y)
99
+ strokeAlphabetText({
100
+ ctx,
101
+ text,
102
+ fontSize: scaledFontSize,
103
+ startX: startPos.x,
104
+ startY: startPos.y,
105
+ })
96
106
 
97
107
  ctx.restore()
98
108
  }
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.23",
4
+ "version": "0.0.25",
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
+ })
@@ -0,0 +1,84 @@
1
+ import { expect, test } from "bun:test"
2
+ import { createCanvas } from "@napi-rs/canvas"
3
+ import type { PcbSilkscreenText } from "circuit-json"
4
+ import { CircuitToCanvasDrawer } from "../../lib/drawer"
5
+
6
+ test("draw silkscreen text bottom layer with rotation - tests transform order", async () => {
7
+ const canvas = createCanvas(150, 150)
8
+ const ctx = canvas.getContext("2d")
9
+ const drawer = new CircuitToCanvasDrawer(ctx)
10
+
11
+ ctx.fillStyle = "#1a1a1a"
12
+ ctx.fillRect(0, 0, 150, 150)
13
+
14
+ // This test verifies the transform order (translate -> rotate -> scale) is correct
15
+ // by testing bottom layer text with various rotations
16
+ const texts: PcbSilkscreenText[] = [
17
+ {
18
+ type: "pcb_silkscreen_text",
19
+ pcb_silkscreen_text_id: "text1",
20
+ pcb_component_id: "component1",
21
+ layer: "bottom",
22
+ text: "0",
23
+ anchor_position: { x: 75, y: 30 },
24
+ anchor_alignment: "center",
25
+ font: "tscircuit2024",
26
+ font_size: 6,
27
+ ccw_rotation: 0,
28
+ },
29
+ {
30
+ type: "pcb_silkscreen_text",
31
+ pcb_silkscreen_text_id: "text2",
32
+ pcb_component_id: "component1",
33
+ layer: "bottom",
34
+ text: "90",
35
+ anchor_position: { x: 120, y: 75 },
36
+ anchor_alignment: "center",
37
+ font: "tscircuit2024",
38
+ font_size: 6,
39
+ ccw_rotation: 90,
40
+ },
41
+ {
42
+ type: "pcb_silkscreen_text",
43
+ pcb_silkscreen_text_id: "text3",
44
+ pcb_component_id: "component1",
45
+ layer: "bottom",
46
+ text: "180",
47
+ anchor_position: { x: 75, y: 120 },
48
+ anchor_alignment: "center",
49
+ font: "tscircuit2024",
50
+ font_size: 6,
51
+ ccw_rotation: 180,
52
+ },
53
+ {
54
+ type: "pcb_silkscreen_text",
55
+ pcb_silkscreen_text_id: "text4",
56
+ pcb_component_id: "component1",
57
+ layer: "bottom",
58
+ text: "270",
59
+ anchor_position: { x: 30, y: 75 },
60
+ anchor_alignment: "center",
61
+ font: "tscircuit2024",
62
+ font_size: 6,
63
+ ccw_rotation: 270,
64
+ },
65
+ {
66
+ type: "pcb_silkscreen_text",
67
+ pcb_silkscreen_text_id: "text5",
68
+ pcb_component_id: "component1",
69
+ layer: "bottom",
70
+ text: "BTM",
71
+ anchor_position: { x: 75, y: 75 },
72
+ anchor_alignment: "center",
73
+ font: "tscircuit2024",
74
+ font_size: 8,
75
+ ccw_rotation: 45,
76
+ },
77
+ ]
78
+
79
+ drawer.drawElements(texts)
80
+
81
+ await expect(canvas.toBuffer("image/png")).toMatchPngSnapshot(
82
+ import.meta.path,
83
+ )
84
+ })
@@ -0,0 +1,31 @@
1
+ import { expect, test } from "bun:test"
2
+ import { createCanvas } from "@napi-rs/canvas"
3
+ import type { PcbSilkscreenText } from "circuit-json"
4
+ import { CircuitToCanvasDrawer } from "../../lib/drawer"
5
+
6
+ test("draw silkscreen text bottom layer", 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 text: PcbSilkscreenText = {
15
+ type: "pcb_silkscreen_text",
16
+ pcb_silkscreen_text_id: "text1",
17
+ pcb_component_id: "component1",
18
+ layer: "bottom",
19
+ text: "BOTTOM",
20
+ anchor_position: { x: 50, y: 50 },
21
+ anchor_alignment: "center",
22
+ font: "tscircuit2024",
23
+ font_size: 8,
24
+ }
25
+
26
+ drawer.drawElements([text])
27
+
28
+ await expect(canvas.toBuffer("image/png")).toMatchPngSnapshot(
29
+ import.meta.path,
30
+ )
31
+ })
@@ -0,0 +1,32 @@
1
+ import { expect, test } from "bun:test"
2
+ import { createCanvas } from "@napi-rs/canvas"
3
+ import type { PcbSilkscreenText } from "circuit-json"
4
+ import { CircuitToCanvasDrawer } from "../../lib/drawer"
5
+
6
+ test("draw silkscreen text with rotation", 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 text: PcbSilkscreenText = {
15
+ type: "pcb_silkscreen_text",
16
+ pcb_silkscreen_text_id: "text1",
17
+ pcb_component_id: "component1",
18
+ layer: "top",
19
+ text: "ROT45",
20
+ anchor_position: { x: 50, y: 50 },
21
+ anchor_alignment: "center",
22
+ font: "tscircuit2024",
23
+ font_size: 8,
24
+ ccw_rotation: 45,
25
+ }
26
+
27
+ drawer.drawElements([text])
28
+
29
+ await expect(canvas.toBuffer("image/png")).toMatchPngSnapshot(
30
+ import.meta.path,
31
+ )
32
+ })
@@ -0,0 +1,31 @@
1
+ import { expect, test } from "bun:test"
2
+ import { createCanvas } from "@napi-rs/canvas"
3
+ import type { PcbSilkscreenText } from "circuit-json"
4
+ import { CircuitToCanvasDrawer } from "../../lib/drawer"
5
+
6
+ test("draw silkscreen text", 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 text: PcbSilkscreenText = {
15
+ type: "pcb_silkscreen_text",
16
+ pcb_silkscreen_text_id: "text1",
17
+ pcb_component_id: "component1",
18
+ layer: "top",
19
+ text: "U1",
20
+ anchor_position: { x: 50, y: 50 },
21
+ anchor_alignment: "center",
22
+ font: "tscircuit2024",
23
+ font_size: 8,
24
+ }
25
+
26
+ drawer.drawElements([text])
27
+
28
+ await expect(canvas.toBuffer("image/png")).toMatchPngSnapshot(
29
+ import.meta.path,
30
+ )
31
+ })
@@ -0,0 +1,30 @@
1
+ import { expect, test } from "bun:test"
2
+ import { createCanvas } from "@napi-rs/canvas"
3
+ import type { PcbSmtPad } from "circuit-json"
4
+ import { CircuitToCanvasDrawer } from "../../lib/drawer"
5
+
6
+ test("draw bottom layer smt pad", 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 pad: PcbSmtPad = {
15
+ type: "pcb_smtpad",
16
+ pcb_smtpad_id: "pad1",
17
+ shape: "rect",
18
+ x: 50,
19
+ y: 50,
20
+ width: 40,
21
+ height: 20,
22
+ layer: "bottom",
23
+ }
24
+
25
+ drawer.drawElements([pad])
26
+
27
+ await expect(canvas.toBuffer("image/png")).toMatchPngSnapshot(
28
+ import.meta.path,
29
+ )
30
+ })
@@ -0,0 +1,29 @@
1
+ import { expect, test } from "bun:test"
2
+ import { createCanvas } from "@napi-rs/canvas"
3
+ import type { PcbSmtPad } from "circuit-json"
4
+ import { CircuitToCanvasDrawer } from "../../lib/drawer"
5
+
6
+ test("draw circular smt pad", 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 pad: PcbSmtPad = {
15
+ type: "pcb_smtpad",
16
+ pcb_smtpad_id: "pad1",
17
+ shape: "circle",
18
+ x: 50,
19
+ y: 50,
20
+ radius: 20,
21
+ layer: "top",
22
+ }
23
+
24
+ drawer.drawElements([pad])
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 { PcbSmtPad } from "circuit-json"
4
+ import { CircuitToCanvasDrawer } from "../../lib/drawer"
5
+
6
+ test("draw pill smt pad", 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 pad: PcbSmtPad = {
15
+ type: "pcb_smtpad",
16
+ pcb_smtpad_id: "pad1",
17
+ shape: "pill",
18
+ x: 50,
19
+ y: 50,
20
+ width: 50,
21
+ height: 25,
22
+ radius: 12.5,
23
+ layer: "top",
24
+ }
25
+
26
+ drawer.drawElements([pad])
27
+
28
+ await expect(canvas.toBuffer("image/png")).toMatchPngSnapshot(
29
+ import.meta.path,
30
+ )
31
+ })