circuit-to-canvas 0.0.45 → 0.0.46

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 (26) hide show
  1. package/dist/index.js +394 -157
  2. package/lib/drawer/CircuitToCanvasDrawer.ts +1 -5
  3. package/lib/drawer/elements/pcb-hole.ts +248 -61
  4. package/lib/drawer/elements/pcb-plated-hole.ts +194 -102
  5. package/lib/drawer/elements/pcb-smtpad.ts +14 -17
  6. package/package.json +1 -1
  7. package/tests/board-snapshot/__snapshots__/usb-c-flashlight-board.snap.png +0 -0
  8. package/tests/elements/__snapshots__/board-with-elements.snap.png +0 -0
  9. package/tests/elements/__snapshots__/custom-outline-board.snap.png +0 -0
  10. package/tests/elements/__snapshots__/pcb-board.snap.png +0 -0
  11. package/tests/elements/__snapshots__/pcb-comprehensive-soldermask-margin.snap.png +0 -0
  12. package/tests/elements/__snapshots__/pcb-fabrication-note-dimension.snap.png +0 -0
  13. package/tests/elements/__snapshots__/pcb-hole-soldermask-margin.snap.png +0 -0
  14. package/tests/elements/__snapshots__/pcb-keepout-layer-filter.snap.png +0 -0
  15. package/tests/elements/__snapshots__/pcb-keepout-multiple-layers.snap.png +0 -0
  16. package/tests/elements/__snapshots__/pcb-keepout-rect-and-circle.snap.png +0 -0
  17. package/tests/elements/__snapshots__/pcb-keepout-with-group-id.snap.png +0 -0
  18. package/tests/elements/__snapshots__/pcb-note-dimension-with-offset.snap.png +0 -0
  19. package/tests/elements/__snapshots__/pcb-plated-hole-soldermask-margin.snap.png +0 -0
  20. package/tests/elements/__snapshots__/pcb-silkscreen-oval.snap.png +0 -0
  21. package/tests/elements/__snapshots__/pcb-smtpad-soldermask-margin.snap.png +0 -0
  22. package/tests/elements/pcb-comprehensive-soldermask-margin.test.ts +330 -0
  23. package/tests/elements/pcb-hole-soldermask-margin.test.ts +5 -5
  24. package/tests/elements/pcb-plated-hole-soldermask-margin.test.ts +8 -8
  25. package/tests/elements/pcb-smtpad-soldermask-margin.test.ts +0 -6
  26. package/tests/shapes/__snapshots__/dimension-line.snap.png +0 -0
@@ -182,11 +182,7 @@ export class CircuitToCanvasDrawer {
182
182
  )
183
183
 
184
184
  for (const element of elements) {
185
- if (
186
- element.type === "pcb_board" &&
187
- (hasSoldermaskPads || hasSoldermaskHoles || hasSoldermaskPlatedHoles)
188
- ) {
189
- // Draw board with soldermask fill when pads or holes have soldermask
185
+ if (element.type === "pcb_board") {
190
186
  this.drawBoardWithSoldermask(element as PcbBoard)
191
187
  } else {
192
188
  this.drawElement(element, options)
@@ -5,6 +5,12 @@ import { drawCircle } from "../shapes/circle"
5
5
  import { drawRect } from "../shapes/rect"
6
6
  import { drawOval } from "../shapes/oval"
7
7
  import { drawPill } from "../shapes/pill"
8
+ import {
9
+ drawSoldermaskRingForCircle,
10
+ drawSoldermaskRingForOval,
11
+ drawSoldermaskRingForPill,
12
+ drawSoldermaskRingForRect,
13
+ } from "./soldermask-margin"
8
14
 
9
15
  export interface DrawPcbHoleParams {
10
16
  ctx: CanvasContext
@@ -24,12 +30,15 @@ function getRotation(hole: PCBHole): number {
24
30
  export function drawPcbHole(params: DrawPcbHoleParams): void {
25
31
  const { ctx, hole, realToCanvasMat, colorMap } = params
26
32
 
33
+ const isCoveredWithSoldermask = hole.is_covered_with_solder_mask === true
34
+ const margin = isCoveredWithSoldermask ? 0 : (hole.soldermask_margin ?? 0)
27
35
  const hasSoldermask =
28
- hole.is_covered_with_solder_mask === true &&
36
+ !isCoveredWithSoldermask &&
29
37
  hole.soldermask_margin !== undefined &&
30
- hole.soldermask_margin > 0
31
- const margin = hasSoldermask ? hole.soldermask_margin! : 0
38
+ hole.soldermask_margin !== 0
32
39
  const positiveMarginColor = colorMap.substrate
40
+ const soldermaskOverlayColor = colorMap.soldermask.top
41
+ const soldermaskRingColor = colorMap.soldermask.top
33
42
 
34
43
  if (hole.hole_shape === "circle") {
35
44
  // For positive margins, draw extended mask area first
@@ -43,14 +52,40 @@ export function drawPcbHole(params: DrawPcbHoleParams): void {
43
52
  })
44
53
  }
45
54
 
46
- // Draw the hole
47
- drawCircle({
48
- ctx,
49
- center: { x: hole.x, y: hole.y },
50
- radius: hole.hole_diameter / 2,
51
- fill: colorMap.drill,
52
- realToCanvasMat,
53
- })
55
+ // Draw the hole (only if not fully covered with soldermask)
56
+ if (!isCoveredWithSoldermask) {
57
+ drawCircle({
58
+ ctx,
59
+ center: { x: hole.x, y: hole.y },
60
+ radius: hole.hole_diameter / 2,
61
+ fill: colorMap.drill,
62
+ realToCanvasMat,
63
+ })
64
+
65
+ // For negative margins, draw soldermask ring on top of the hole
66
+ if (hasSoldermask && margin < 0) {
67
+ drawSoldermaskRingForCircle(
68
+ ctx,
69
+ { x: hole.x, y: hole.y },
70
+ hole.hole_diameter / 2,
71
+ margin,
72
+ realToCanvasMat,
73
+ soldermaskRingColor,
74
+ colorMap.drill,
75
+ )
76
+ }
77
+ }
78
+
79
+ // If fully covered, draw soldermask overlay
80
+ if (isCoveredWithSoldermask) {
81
+ drawCircle({
82
+ ctx,
83
+ center: { x: hole.x, y: hole.y },
84
+ radius: hole.hole_diameter / 2,
85
+ fill: soldermaskOverlayColor,
86
+ realToCanvasMat,
87
+ })
88
+ }
54
89
  return
55
90
  }
56
91
 
@@ -69,16 +104,47 @@ export function drawPcbHole(params: DrawPcbHoleParams): void {
69
104
  })
70
105
  }
71
106
 
72
- // Draw the hole
73
- drawRect({
74
- ctx,
75
- center: { x: hole.x, y: hole.y },
76
- width: hole.hole_diameter,
77
- height: hole.hole_diameter,
78
- fill: colorMap.drill,
79
- realToCanvasMat,
80
- rotation,
81
- })
107
+ // Draw the hole (only if not fully covered with soldermask)
108
+ if (!isCoveredWithSoldermask) {
109
+ drawRect({
110
+ ctx,
111
+ center: { x: hole.x, y: hole.y },
112
+ width: hole.hole_diameter,
113
+ height: hole.hole_diameter,
114
+ fill: colorMap.drill,
115
+ realToCanvasMat,
116
+ rotation,
117
+ })
118
+
119
+ // For negative margins, draw soldermask ring on top of the hole
120
+ if (hasSoldermask && margin < 0) {
121
+ drawSoldermaskRingForRect(
122
+ ctx,
123
+ { x: hole.x, y: hole.y },
124
+ hole.hole_diameter,
125
+ hole.hole_diameter,
126
+ margin,
127
+ 0,
128
+ rotation,
129
+ realToCanvasMat,
130
+ soldermaskRingColor,
131
+ colorMap.drill,
132
+ )
133
+ }
134
+ }
135
+
136
+ // If fully covered, draw soldermask overlay
137
+ if (isCoveredWithSoldermask) {
138
+ drawRect({
139
+ ctx,
140
+ center: { x: hole.x, y: hole.y },
141
+ width: hole.hole_diameter,
142
+ height: hole.hole_diameter,
143
+ fill: soldermaskOverlayColor,
144
+ realToCanvasMat,
145
+ rotation,
146
+ })
147
+ }
82
148
  return
83
149
  }
84
150
 
@@ -97,16 +163,46 @@ export function drawPcbHole(params: DrawPcbHoleParams): void {
97
163
  })
98
164
  }
99
165
 
100
- // Draw the hole
101
- drawOval({
102
- ctx,
103
- center: { x: hole.x, y: hole.y },
104
- radius_x: hole.hole_width / 2,
105
- radius_y: hole.hole_height / 2,
106
- fill: colorMap.drill,
107
- realToCanvasMat,
108
- rotation,
109
- })
166
+ // Draw the hole (only if not fully covered with soldermask)
167
+ if (!isCoveredWithSoldermask) {
168
+ drawOval({
169
+ ctx,
170
+ center: { x: hole.x, y: hole.y },
171
+ radius_x: hole.hole_width / 2,
172
+ radius_y: hole.hole_height / 2,
173
+ fill: colorMap.drill,
174
+ realToCanvasMat,
175
+ rotation,
176
+ })
177
+
178
+ // For negative margins, draw soldermask ring on top of the hole
179
+ if (hasSoldermask && margin < 0) {
180
+ drawSoldermaskRingForOval(
181
+ ctx,
182
+ { x: hole.x, y: hole.y },
183
+ hole.hole_width / 2,
184
+ hole.hole_height / 2,
185
+ margin,
186
+ rotation,
187
+ realToCanvasMat,
188
+ soldermaskRingColor,
189
+ colorMap.drill,
190
+ )
191
+ }
192
+ }
193
+
194
+ // If fully covered, draw soldermask overlay
195
+ if (isCoveredWithSoldermask) {
196
+ drawOval({
197
+ ctx,
198
+ center: { x: hole.x, y: hole.y },
199
+ radius_x: hole.hole_width / 2,
200
+ radius_y: hole.hole_height / 2,
201
+ fill: soldermaskOverlayColor,
202
+ realToCanvasMat,
203
+ rotation,
204
+ })
205
+ }
110
206
  return
111
207
  }
112
208
 
@@ -125,16 +221,47 @@ export function drawPcbHole(params: DrawPcbHoleParams): void {
125
221
  })
126
222
  }
127
223
 
128
- // Draw the hole
129
- drawRect({
130
- ctx,
131
- center: { x: hole.x, y: hole.y },
132
- width: hole.hole_width,
133
- height: hole.hole_height,
134
- fill: colorMap.drill,
135
- realToCanvasMat,
136
- rotation,
137
- })
224
+ // Draw the hole (only if not fully covered with soldermask)
225
+ if (!isCoveredWithSoldermask) {
226
+ drawRect({
227
+ ctx,
228
+ center: { x: hole.x, y: hole.y },
229
+ width: hole.hole_width,
230
+ height: hole.hole_height,
231
+ fill: colorMap.drill,
232
+ realToCanvasMat,
233
+ rotation,
234
+ })
235
+
236
+ // For negative margins, draw soldermask ring on top of the hole
237
+ if (hasSoldermask && margin < 0) {
238
+ drawSoldermaskRingForRect(
239
+ ctx,
240
+ { x: hole.x, y: hole.y },
241
+ hole.hole_width,
242
+ hole.hole_height,
243
+ margin,
244
+ 0,
245
+ rotation,
246
+ realToCanvasMat,
247
+ soldermaskRingColor,
248
+ colorMap.drill,
249
+ )
250
+ }
251
+ }
252
+
253
+ // If fully covered, draw soldermask overlay
254
+ if (isCoveredWithSoldermask) {
255
+ drawRect({
256
+ ctx,
257
+ center: { x: hole.x, y: hole.y },
258
+ width: hole.hole_width,
259
+ height: hole.hole_height,
260
+ fill: soldermaskOverlayColor,
261
+ realToCanvasMat,
262
+ rotation,
263
+ })
264
+ }
138
265
  return
139
266
  }
140
267
 
@@ -153,16 +280,46 @@ export function drawPcbHole(params: DrawPcbHoleParams): void {
153
280
  })
154
281
  }
155
282
 
156
- // Draw the hole
157
- drawPill({
158
- ctx,
159
- center: { x: hole.x, y: hole.y },
160
- width: hole.hole_width,
161
- height: hole.hole_height,
162
- fill: colorMap.drill,
163
- realToCanvasMat,
164
- rotation,
165
- })
283
+ // Draw the hole (only if not fully covered with soldermask)
284
+ if (!isCoveredWithSoldermask) {
285
+ drawPill({
286
+ ctx,
287
+ center: { x: hole.x, y: hole.y },
288
+ width: hole.hole_width,
289
+ height: hole.hole_height,
290
+ fill: colorMap.drill,
291
+ realToCanvasMat,
292
+ rotation,
293
+ })
294
+
295
+ // For negative margins, draw soldermask ring on top of the hole
296
+ if (hasSoldermask && margin < 0) {
297
+ drawSoldermaskRingForPill(
298
+ ctx,
299
+ { x: hole.x, y: hole.y },
300
+ hole.hole_width,
301
+ hole.hole_height,
302
+ margin,
303
+ rotation,
304
+ realToCanvasMat,
305
+ soldermaskRingColor,
306
+ colorMap.drill,
307
+ )
308
+ }
309
+ }
310
+
311
+ // If fully covered, draw soldermask overlay
312
+ if (isCoveredWithSoldermask) {
313
+ drawPill({
314
+ ctx,
315
+ center: { x: hole.x, y: hole.y },
316
+ width: hole.hole_width,
317
+ height: hole.hole_height,
318
+ fill: soldermaskOverlayColor,
319
+ realToCanvasMat,
320
+ rotation,
321
+ })
322
+ }
166
323
  return
167
324
  }
168
325
 
@@ -182,16 +339,46 @@ export function drawPcbHole(params: DrawPcbHoleParams): void {
182
339
  })
183
340
  }
184
341
 
185
- // Draw the hole
186
- drawPill({
187
- ctx,
188
- center: { x: hole.x, y: hole.y },
189
- width: hole.hole_width,
190
- height: hole.hole_height,
191
- fill: colorMap.drill,
192
- realToCanvasMat,
193
- rotation,
194
- })
342
+ // Draw the hole (only if not fully covered with soldermask)
343
+ if (!isCoveredWithSoldermask) {
344
+ drawPill({
345
+ ctx,
346
+ center: { x: hole.x, y: hole.y },
347
+ width: hole.hole_width,
348
+ height: hole.hole_height,
349
+ fill: colorMap.drill,
350
+ realToCanvasMat,
351
+ rotation,
352
+ })
353
+
354
+ // For negative margins, draw soldermask ring on top of the hole
355
+ if (hasSoldermask && margin < 0) {
356
+ drawSoldermaskRingForPill(
357
+ ctx,
358
+ { x: hole.x, y: hole.y },
359
+ hole.hole_width,
360
+ hole.hole_height,
361
+ margin,
362
+ rotation,
363
+ realToCanvasMat,
364
+ soldermaskRingColor,
365
+ colorMap.drill,
366
+ )
367
+ }
368
+ }
369
+
370
+ // If fully covered, draw soldermask overlay
371
+ if (isCoveredWithSoldermask) {
372
+ drawPill({
373
+ ctx,
374
+ center: { x: hole.x, y: hole.y },
375
+ width: hole.hole_width,
376
+ height: hole.hole_height,
377
+ fill: soldermaskOverlayColor,
378
+ realToCanvasMat,
379
+ rotation,
380
+ })
381
+ }
195
382
  return
196
383
  }
197
384
  }