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.
- package/dist/index.d.ts +18 -11
- package/dist/index.js +19 -5
- package/lib/drawer/elements/pcb-copper-text.ts +2 -2
- package/lib/drawer/elements/pcb-silkscreen-text.ts +7 -1
- package/lib/drawer/shapes/text/text.ts +18 -8
- package/package.json +1 -1
- package/tests/elements/__snapshots__/fabrication-note-text-full-charset.snap.png +0 -0
- package/tests/elements/__snapshots__/pcb-board.snap.png +0 -0
- package/tests/elements/pcb-silkscreen-circle.test.ts +29 -0
- package/tests/elements/pcb-silkscreen-line.test.ts +31 -0
- package/tests/elements/pcb-silkscreen-on-component.test.ts +75 -0
- package/tests/elements/pcb-silkscreen-path.test.ts +36 -0
- package/tests/elements/pcb-silkscreen-rect.test.ts +30 -0
- package/tests/elements/pcb-silkscreen-text-bottom-rotated.test.ts +84 -0
- package/tests/elements/pcb-silkscreen-text-bottom.test.ts +31 -0
- package/tests/elements/pcb-silkscreen-text-rotated.test.ts +32 -0
- package/tests/elements/pcb-silkscreen-text.test.ts +31 -0
- package/tests/elements/pcb-smtpad-bottom-layer.test.ts +30 -0
- package/tests/elements/pcb-smtpad-circle.test.ts +29 -0
- package/tests/elements/pcb-smtpad-pill.test.ts +31 -0
- package/tests/elements/pcb-smtpad-polygon.test.ts +34 -0
- package/tests/elements/pcb-smtpad-rect-border-radius.test.ts +31 -0
- package/tests/elements/pcb-smtpad-rect.test.ts +30 -0
- package/tests/elements/pcb-smtpad-rotated-rect.test.ts +31 -0
- package/tests/elements/pcb-silkscreen.test.ts +0 -362
- package/tests/elements/pcb-smtpad.test.ts +0 -198
- /package/tests/elements/__snapshots__/{silkscreen-circle.snap.png → pcb-silkscreen-circle.snap.png} +0 -0
- /package/tests/elements/__snapshots__/{silkscreen-line.snap.png → pcb-silkscreen-line.snap.png} +0 -0
- /package/tests/elements/__snapshots__/{silkscreen-on-component.snap.png → pcb-silkscreen-on-component.snap.png} +0 -0
- /package/tests/elements/__snapshots__/{silkscreen-path.snap.png → pcb-silkscreen-path.snap.png} +0 -0
- /package/tests/elements/__snapshots__/{silkscreen-rect.snap.png → pcb-silkscreen-rect.snap.png} +0 -0
- /package/tests/elements/__snapshots__/{silkscreen-text-bottom-rotated.snap.png → pcb-silkscreen-text-bottom-rotated.snap.png} +0 -0
- /package/tests/elements/__snapshots__/{silkscreen-text-bottom.snap.png → pcb-silkscreen-text-bottom.snap.png} +0 -0
- /package/tests/elements/__snapshots__/{silkscreen-text-rotated.snap.png → pcb-silkscreen-text-rotated.snap.png} +0 -0
- /package/tests/elements/__snapshots__/{pcb-silkscreen.snap.png → pcb-silkscreen-text.snap.png} +0 -0
- /package/tests/elements/__snapshots__/{bottom-layer-pad.snap.png → pcb-smtpad-bottom-layer.snap.png} +0 -0
- /package/tests/elements/__snapshots__/{circular-pad.snap.png → pcb-smtpad-circle.snap.png} +0 -0
- /package/tests/elements/__snapshots__/{pill-pad.snap.png → pcb-smtpad-pill.snap.png} +0 -0
- /package/tests/elements/__snapshots__/{polygon-pad.snap.png → pcb-smtpad-polygon.snap.png} +0 -0
- /package/tests/elements/__snapshots__/{rect-pad-with-border-radius.snap.png → pcb-smtpad-rect-border-radius.snap.png} +0 -0
- /package/tests/elements/__snapshots__/{pcb-smtpad.snap.png → pcb-smtpad-rect.snap.png} +0 -0
- /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
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
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(
|
|
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(
|
|
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(
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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(
|
|
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
|
|
13
|
-
ctx: CanvasContext
|
|
14
|
-
text: string
|
|
15
|
-
|
|
16
|
-
startX: number
|
|
17
|
-
startY: number
|
|
18
|
-
|
|
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(
|
|
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
|
Binary file
|
|
Binary file
|
|
@@ -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
|
+
})
|