Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 9 additions & 3 deletions src/fn/smdpads.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ export const smdpads_def = base_def
p: length.default("1mm").describe("pad center pitch"),
pw: length.default("1mm").describe("outer pad width"),
ph: length.default("1mm").describe("pad height"),
cyw: length.optional().describe("courtyard width"),
cyh: length.optional().describe("courtyard height"),
centerpadwidth: length.optional().describe("center pad width"),
})
.superRefine((parameters, ctx) => {
Expand All @@ -34,7 +36,7 @@ export const smdpads = (
rawParams: z.input<typeof smdpads_def>,
): { circuitJson: AnyCircuitElement[]; parameters: any } => {
const parameters = smdpads_def.parse(rawParams)
const { num_pins, p, pw, ph, centerpadwidth } = parameters
const { num_pins, p, pw, ph, cyw, cyh, centerpadwidth } = parameters
const centerPin = Math.ceil(num_pins / 2)
const xStart = -((num_pins - 1) * p) / 2
const pads = Array.from({ length: num_pins }, (_, index) => {
Expand All @@ -49,13 +51,17 @@ export const smdpads = (
const outerPadHalfWidth = ((num_pins - 1) * p) / 2 + pw / 2
const centerPadHalfWidth = centerpadwidth ? centerpadwidth / 2 : 0
const copperHalfWidth = Math.max(outerPadHalfWidth, centerPadHalfWidth)
const courtyardSize =
cyw !== undefined && cyh !== undefined
? { width: cyw, height: cyh }
: { width: copperHalfWidth * 2 + 0.5, height: ph + 0.5 }
const courtyard: PcbCourtyardRect = {
type: "pcb_courtyard_rect",
pcb_courtyard_rect_id: "",
pcb_component_id: "",
center: { x: 0, y: 0 },
width: copperHalfWidth * 2 + 0.5,
height: ph + 0.5,
width: courtyardSize.width,
height: courtyardSize.height,
layer: "top",
}

Expand Down
16 changes: 12 additions & 4 deletions src/helpers/passive-fn.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import mm from "@tscircuit/mm"
import type {
AnyCircuitElement,
PcbCourtyardRect,
PcbSilkscreenPath,
} from "circuit-json"
import { distance, length } from "circuit-json"
import { z } from "zod"
import { rectpad } from "../helpers/rectpad"
import mm from "@tscircuit/mm"
import { platedhole } from "./platedhole"
import { z } from "zod"
import { length, distance } from "circuit-json"
import { type SilkscreenRef, silkscreenRef } from "./silkscreenRef"
import { base_def } from "./zod/base_def"

Expand Down Expand Up @@ -230,6 +230,8 @@ export const passive_def = base_def.extend({
imperial: distance.optional(),
w: length.optional(),
h: length.optional(),
cyw: length.optional().describe("courtyard width"),
cyh: length.optional().describe("courtyard height"),
nonpolarized: z.boolean().optional(),
textbottom: z.boolean().optional(),
roundedPads: z.boolean().optional(),
Expand All @@ -248,6 +250,8 @@ export const passive = (params: PassiveDef): AnyCircuitElement[] => {
imperial,
w,
h,
cyw,
cyh,
nonpolarized,
textbottom,
roundedPads,
Expand All @@ -256,6 +260,8 @@ export const passive = (params: PassiveDef): AnyCircuitElement[] => {

if (typeof w === "string") w = mm(w)
if (typeof h === "string") h = mm(h)
if (typeof cyw === "string") cyw = mm(cyw)
if (typeof cyh === "string") cyh = mm(cyh)
if (typeof p === "string") p = mm(p)
if (typeof pw === "string") pw = mm(pw)
if (typeof ph === "string") ph = mm(ph)
Expand Down Expand Up @@ -345,7 +351,9 @@ export const passive = (params: PassiveDef): AnyCircuitElement[] => {
const courtyard =
sz?.courtyard_width_mm && sz.courtyard_height_mm
? createCourtyardRect(sz.courtyard_width_mm, sz.courtyard_height_mm)
: null
: cyw !== undefined && cyh !== undefined
? createCourtyardRect(cyw, cyh)
: null
const shouldRoundPads = roundedPads ?? sz?.rounded_pads ?? false
const cornerRadius = shouldRoundPads
? Math.min(0.125, Math.min(pw, ph) / 8)
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
19 changes: 18 additions & 1 deletion tests/cap.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { test, expect } from "bun:test"
import { expect, test } from "bun:test"
import { convertCircuitJsonToPcbSvg } from "circuit-to-svg"
import { fp } from "../src/footprinter"

Expand Down Expand Up @@ -46,3 +46,20 @@ test("cap 2512", () => {
const svgContent = convertCircuitJsonToPcbSvg(soup)
expect(svgContent).toMatchSvgSnapshot(import.meta.path, "cap_2512")
})

test("custom capacitor footprint uses explicit courtyard dimensions", () => {
const footprintString =
"cap_p4.6599mm_pw2.91mm_ph2.9106mm_cyw8.628mm_cyh4.056mm"
const circuitJson = fp.string(footprintString).circuitJson()
const courtyard = circuitJson.find(
(element) => element.type === "pcb_courtyard_rect",
)

expect(courtyard).toMatchObject({
width: 8.628,
height: 4.056,
})
expect(
convertCircuitJsonToPcbSvg(circuitJson, { showCourtyards: true }),
).toMatchSvgSnapshot(import.meta.path, footprintString)
})
19 changes: 18 additions & 1 deletion tests/diode.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { test, expect } from "bun:test"
import { expect, test } from "bun:test"
import { convertCircuitJsonToPcbSvg } from "circuit-to-svg"
import { fp } from "../src/footprinter"

Expand Down Expand Up @@ -43,3 +43,20 @@ test("diode2512", () => {
const svgContent = convertCircuitJsonToPcbSvg(soup)
expect(svgContent).toMatchSvgSnapshot(import.meta.path, "diode2512")
})

test("custom diode footprint uses explicit courtyard dimensions", () => {
const footprintString =
"diode_p4.6599mm_pw2.91mm_ph2.9106mm_cyw8.628mm_cyh4.056mm"
const circuitJson = fp.string(footprintString).circuitJson()
const courtyard = circuitJson.find(
(element) => element.type === "pcb_courtyard_rect",
)

expect(courtyard).toMatchObject({
width: 8.628,
height: 4.056,
})
expect(
convertCircuitJsonToPcbSvg(circuitJson, { showCourtyards: true }),
).toMatchSvgSnapshot(import.meta.path, footprintString)
})
19 changes: 18 additions & 1 deletion tests/led.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { test, expect } from "bun:test"
import { expect, test } from "bun:test"
import { convertCircuitJsonToPcbSvg } from "circuit-to-svg"
import { led } from "../src/fn"
import { fp } from "../src/footprinter"
Expand Down Expand Up @@ -99,3 +99,20 @@ test("led0201", () => {
const svgContent = convertCircuitJsonToPcbSvg(soup)
expect(svgContent).toMatchSvgSnapshot(import.meta.path, "led_0201")
})

test("custom LED footprint uses explicit courtyard dimensions", () => {
const footprintString =
"led_p4.6599mm_pw2.91mm_ph2.9106mm_cyw8.628mm_cyh4.056mm"
const circuitJson = fp.string(footprintString).circuitJson()
const courtyard = circuitJson.find(
(element) => element.type === "pcb_courtyard_rect",
)

expect(courtyard).toMatchObject({
width: 8.628,
height: 4.056,
})
expect(
convertCircuitJsonToPcbSvg(circuitJson, { showCourtyards: true }),
).toMatchSvgSnapshot(import.meta.path, footprintString)
})
Loading
Loading