circuit-to-canvas 0.0.69 → 0.0.71
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/.github/CODEOWNERS
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
* @ShiboSoftwareDev @Abse2001
|
|
1
|
+
* @ShiboSoftwareDev @Abse2001 @techmannih
|
package/dist/index.js
CHANGED
|
@@ -2028,6 +2028,7 @@ function drawPcbSilkscreenRect(params) {
|
|
|
2028
2028
|
|
|
2029
2029
|
// lib/drawer/elements/pcb-silkscreen-text.ts
|
|
2030
2030
|
import { applyToPoint as applyToPoint15 } from "transformation-matrix";
|
|
2031
|
+
var DEFAULT_PADDING2 = { left: 0.2, right: 0.2, top: 0.2, bottom: 0.2 };
|
|
2031
2032
|
function layerToSilkscreenColor7(layer, colorMap) {
|
|
2032
2033
|
return layer === "bottom" ? colorMap.silkscreen.bottom : colorMap.silkscreen.top;
|
|
2033
2034
|
}
|
|
@@ -2047,7 +2048,12 @@ function drawPcbSilkscreenText(params) {
|
|
|
2047
2048
|
const scale2 = Math.abs(realToCanvasMat.a);
|
|
2048
2049
|
const fontSize = (text.font_size ?? 1) * scale2;
|
|
2049
2050
|
const rotation = text.ccw_rotation ?? 0;
|
|
2051
|
+
const padding = {
|
|
2052
|
+
...DEFAULT_PADDING2,
|
|
2053
|
+
...text.knockout_padding
|
|
2054
|
+
};
|
|
2050
2055
|
const layout = getAlphabetLayout(content, fontSize);
|
|
2056
|
+
const totalWidth = layout.width + layout.strokeWidth;
|
|
2051
2057
|
const alignment = mapAnchorAlignment2(text.anchor_alignment);
|
|
2052
2058
|
const startPos = getTextStartPosition(alignment, layout);
|
|
2053
2059
|
ctx.save();
|
|
@@ -2061,7 +2067,20 @@ function drawPcbSilkscreenText(params) {
|
|
|
2061
2067
|
ctx.lineWidth = layout.strokeWidth;
|
|
2062
2068
|
ctx.lineCap = "round";
|
|
2063
2069
|
ctx.lineJoin = "round";
|
|
2064
|
-
|
|
2070
|
+
if (text.is_knockout) {
|
|
2071
|
+
const paddingLeft = padding.left * scale2;
|
|
2072
|
+
const paddingRight = padding.right * scale2;
|
|
2073
|
+
const paddingTop = padding.top * scale2;
|
|
2074
|
+
const paddingBottom = padding.bottom * scale2;
|
|
2075
|
+
const rectX = startPos.x - paddingLeft * 4;
|
|
2076
|
+
const rectY = startPos.y - paddingTop * 4;
|
|
2077
|
+
const rectWidth = totalWidth + paddingLeft * 2 + paddingRight * 2;
|
|
2078
|
+
const rectHeight = layout.height + layout.strokeWidth + paddingTop * 2 + paddingBottom * 2;
|
|
2079
|
+
ctx.fillStyle = color;
|
|
2080
|
+
ctx.fillRect(rectX, rectY, rectWidth, rectHeight);
|
|
2081
|
+
} else {
|
|
2082
|
+
ctx.strokeStyle = color;
|
|
2083
|
+
}
|
|
2065
2084
|
const { lines, lineWidths, lineHeight, width, strokeWidth } = layout;
|
|
2066
2085
|
lines.forEach((line, lineIndex) => {
|
|
2067
2086
|
const lineStartX = startPos.x + getLineStartX({
|
|
@@ -17,6 +17,8 @@ export interface DrawPcbSilkscreenTextParams {
|
|
|
17
17
|
colorMap: PcbColorMap
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
+
const DEFAULT_PADDING = { left: 0.2, right: 0.2, top: 0.2, bottom: 0.2 }
|
|
21
|
+
|
|
20
22
|
function layerToSilkscreenColor(layer: string, colorMap: PcbColorMap): string {
|
|
21
23
|
return layer === "bottom"
|
|
22
24
|
? colorMap.silkscreen.bottom
|
|
@@ -44,8 +46,13 @@ export function drawPcbSilkscreenText(
|
|
|
44
46
|
const scale = Math.abs(realToCanvasMat.a)
|
|
45
47
|
const fontSize = (text.font_size ?? 1) * scale
|
|
46
48
|
const rotation = text.ccw_rotation ?? 0
|
|
49
|
+
const padding = {
|
|
50
|
+
...DEFAULT_PADDING,
|
|
51
|
+
...text.knockout_padding,
|
|
52
|
+
}
|
|
47
53
|
|
|
48
54
|
const layout = getAlphabetLayout(content, fontSize)
|
|
55
|
+
const totalWidth = layout.width + layout.strokeWidth
|
|
49
56
|
const alignment = mapAnchorAlignment(text.anchor_alignment)
|
|
50
57
|
const startPos = getTextStartPosition(alignment, layout)
|
|
51
58
|
|
|
@@ -64,7 +71,23 @@ export function drawPcbSilkscreenText(
|
|
|
64
71
|
ctx.lineWidth = layout.strokeWidth
|
|
65
72
|
ctx.lineCap = "round"
|
|
66
73
|
ctx.lineJoin = "round"
|
|
67
|
-
|
|
74
|
+
|
|
75
|
+
if (text.is_knockout) {
|
|
76
|
+
const paddingLeft = padding.left * scale
|
|
77
|
+
const paddingRight = padding.right * scale
|
|
78
|
+
const paddingTop = padding.top * scale
|
|
79
|
+
const paddingBottom = padding.bottom * scale
|
|
80
|
+
const rectX = startPos.x - paddingLeft * 4
|
|
81
|
+
const rectY = startPos.y - paddingTop * 4
|
|
82
|
+
const rectWidth = totalWidth + paddingLeft * 2 + paddingRight * 2
|
|
83
|
+
const rectHeight =
|
|
84
|
+
layout.height + layout.strokeWidth + paddingTop * 2 + paddingBottom * 2
|
|
85
|
+
|
|
86
|
+
ctx.fillStyle = color
|
|
87
|
+
ctx.fillRect(rectX, rectY, rectWidth, rectHeight)
|
|
88
|
+
} else {
|
|
89
|
+
ctx.strokeStyle = color
|
|
90
|
+
}
|
|
68
91
|
|
|
69
92
|
const { lines, lineWidths, lineHeight, width, strokeWidth } = layout
|
|
70
93
|
|
package/package.json
CHANGED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { expect, test } from "bun:test"
|
|
2
|
+
import { createCanvas } from "@napi-rs/canvas"
|
|
3
|
+
import type { PcbSilkscreenText } from "circuit-json"
|
|
4
|
+
import { scale } from "transformation-matrix"
|
|
5
|
+
import { CircuitToCanvasDrawer } from "../../lib/drawer"
|
|
6
|
+
|
|
7
|
+
test("draw silkscreen text knockout", async () => {
|
|
8
|
+
const SCALE = 4
|
|
9
|
+
const canvas = createCanvas(100 * SCALE, 60 * SCALE)
|
|
10
|
+
const ctx = canvas.getContext("2d")
|
|
11
|
+
ctx.scale(SCALE, SCALE)
|
|
12
|
+
const drawer = new CircuitToCanvasDrawer(ctx)
|
|
13
|
+
|
|
14
|
+
ctx.fillStyle = "#1a1a1a"
|
|
15
|
+
ctx.fillRect(0, 0, canvas.width / SCALE, canvas.height / SCALE)
|
|
16
|
+
|
|
17
|
+
drawer.realToCanvasMat = scale(2, 2)
|
|
18
|
+
|
|
19
|
+
const text: PcbSilkscreenText[] = [
|
|
20
|
+
{
|
|
21
|
+
type: "pcb_silkscreen_text",
|
|
22
|
+
pcb_silkscreen_text_id: "text1",
|
|
23
|
+
pcb_component_id: "component1",
|
|
24
|
+
layer: "top",
|
|
25
|
+
text: "U1",
|
|
26
|
+
anchor_position: { x: 25, y: 15 },
|
|
27
|
+
anchor_alignment: "center",
|
|
28
|
+
font: "tscircuit2024",
|
|
29
|
+
font_size: 8,
|
|
30
|
+
is_knockout: true,
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
type: "pcb_silkscreen_text",
|
|
34
|
+
pcb_silkscreen_text_id: "text2",
|
|
35
|
+
pcb_component_id: "component1",
|
|
36
|
+
layer: "bottom",
|
|
37
|
+
text: "R1",
|
|
38
|
+
anchor_position: { x: 25, y: 25 },
|
|
39
|
+
anchor_alignment: "center",
|
|
40
|
+
font: "tscircuit2024",
|
|
41
|
+
font_size: 6,
|
|
42
|
+
is_knockout: true,
|
|
43
|
+
knockout_padding: { left: 0.5, right: 0.5, top: 0.3, bottom: 0.3 },
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
type: "pcb_silkscreen_text",
|
|
47
|
+
pcb_silkscreen_text_id: "text3",
|
|
48
|
+
pcb_component_id: "component1",
|
|
49
|
+
layer: "top",
|
|
50
|
+
text: "C1",
|
|
51
|
+
anchor_position: { x: 40, y: 20 },
|
|
52
|
+
anchor_alignment: "center",
|
|
53
|
+
font: "tscircuit2024",
|
|
54
|
+
font_size: 8,
|
|
55
|
+
is_knockout: true,
|
|
56
|
+
ccw_rotation: 45,
|
|
57
|
+
},
|
|
58
|
+
]
|
|
59
|
+
|
|
60
|
+
drawer.drawElements(text)
|
|
61
|
+
|
|
62
|
+
await expect(canvas.toBuffer("image/png")).toMatchPngSnapshot(
|
|
63
|
+
import.meta.path,
|
|
64
|
+
)
|
|
65
|
+
})
|