From a2eb7b20ed7a7c2f608d1d69baf39de9303ef98a Mon Sep 17 00:00:00 2001 From: Sahil Gupta Date: Thu, 8 Jan 2026 13:18:24 +0530 Subject: [PATCH 1/2] add plcc fp --- src/fn/index.ts | 1 + src/fn/plcc.ts | 33 +++++++++++++++++++ src/fn/quad.ts | 16 +++++---- .../plcc44_w16.5_h16.5_p1.27mm.snap.svg | 1 + ...plcc44_parity._boolean_difference.snap.svg | 1 + .../__snapshots__/plcc44_parity.snap.svg | 1 + tests/kicad-parity/plcc_kikac_parity.test.ts | 18 ++++++++++ tests/plcc.test.ts | 12 +++++++ 8 files changed, 77 insertions(+), 6 deletions(-) create mode 100644 src/fn/plcc.ts create mode 100644 tests/__snapshots__/plcc44_w16.5_h16.5_p1.27mm.snap.svg create mode 100644 tests/kicad-parity/__snapshots__/plcc44_parity._boolean_difference.snap.svg create mode 100644 tests/kicad-parity/__snapshots__/plcc44_parity.snap.svg create mode 100644 tests/kicad-parity/plcc_kikac_parity.test.ts create mode 100644 tests/plcc.test.ts diff --git a/src/fn/index.ts b/src/fn/index.ts index 07668c12..8c7eea6a 100644 --- a/src/fn/index.ts +++ b/src/fn/index.ts @@ -78,3 +78,4 @@ export { sot } from "./sot" export { sot343 } from "./sot343" export { m2host } from "./m2host" export { to92l } from "./to92l" +export { plcc } from "./plcc" \ No newline at end of file diff --git a/src/fn/plcc.ts b/src/fn/plcc.ts new file mode 100644 index 00000000..13b80735 --- /dev/null +++ b/src/fn/plcc.ts @@ -0,0 +1,33 @@ +import type { AnyCircuitElement } from "circuit-json" +import { quad, quad_def } from "./quad" +import type { z } from "zod" + +export const plcc_def = quad_def + +export const plcc = ( + raw_params: z.input, +): { circuitJson: AnyCircuitElement[]; parameters: any } => { + if (!raw_params.p) { + raw_params.p = 1.27 + } + + if (!raw_params.pl) { + raw_params.pl = 1.7 + } + + if (!raw_params.pw) { + raw_params.pw = 0.6 + } + + if (raw_params.pcdfe === undefined && raw_params.w) { + const w = + typeof raw_params.w === "number" + ? raw_params.w + : parseFloat(raw_params.w as string) + if (!isNaN(w)) { + raw_params.pcdfe = 8.0 - w / 2 + } + } + + return quad(raw_params) +} \ No newline at end of file diff --git a/src/fn/quad.ts b/src/fn/quad.ts index b9993016..c46ee2b1 100644 --- a/src/fn/quad.ts +++ b/src/fn/quad.ts @@ -27,6 +27,7 @@ export const base_quad_def = base_def.extend({ pl: length.optional(), thermalpad: z.union([z.literal(true), dim2d]).optional(), legsoutside: z.boolean().default(false), + pcdfe: length.optional(), }) export const quadTransform = >( @@ -81,8 +82,9 @@ export const getQuadCoords = (params: { p: number // pitch between pins pl: number // length of the pin legsoutside?: boolean + pcdfe?: number }) => { - const { pin_count, pn, w, h, p, pl, legsoutside } = params + const { pin_count, pn, w, h, p, pl, legsoutside, pcdfe: pcdfe_param } = params const sidePinCount = pin_count / 4 const side = SIDES_CCW[Math.floor((pn - 1) / sidePinCount)] const pos = (pn - 1) % sidePinCount @@ -93,17 +95,18 @@ export const getQuadCoords = (params: { const ibh = p * (sidePinCount - 1) /** pad center distance from edge (negative is inside, positive is outside) */ - const pcdfe = legsoutside ? pl / 2 : -pl / 2 + const pcdfe = pcdfe_param ?? (legsoutside ? pl / 2 : -pl / 2) + const offset = pcdfe_param === undefined ? 0.1 : 0 switch (side) { case "left": - return { x: -w / 2 - pcdfe + 0.1, y: ibh / 2 - pos * p, o: "vert" } + return { x: -w / 2 - pcdfe + offset, y: ibh / 2 - pos * p, o: "vert" } case "bottom": - return { x: -ibw / 2 + pos * p, y: -h / 2 - pcdfe + 0.1, o: "horz" } + return { x: -ibw / 2 + pos * p, y: -h / 2 - pcdfe + offset, o: "horz" } case "right": - return { x: w / 2 + pcdfe - 0.1, y: -ibh / 2 + pos * p, o: "vert" } + return { x: w / 2 + pcdfe - offset, y: -ibh / 2 + pos * p, o: "vert" } case "top": - return { x: ibw / 2 - pos * p, y: h / 2 + pcdfe - 0.1, o: "horz" } + return { x: ibw / 2 - pos * p, y: h / 2 + pcdfe - offset, o: "horz" } default: throw new Error("Invalid pin number") } @@ -130,6 +133,7 @@ export const quad = ( p: parameters.p ?? 0.5, pl: parameters.pl, legsoutside: parameters.legsoutside, + pcdfe: parameters.pcdfe }) let pw = parameters.pw diff --git a/tests/__snapshots__/plcc44_w16.5_h16.5_p1.27mm.snap.svg b/tests/__snapshots__/plcc44_w16.5_h16.5_p1.27mm.snap.svg new file mode 100644 index 00000000..368579b5 --- /dev/null +++ b/tests/__snapshots__/plcc44_w16.5_h16.5_p1.27mm.snap.svg @@ -0,0 +1 @@ +{REF} \ No newline at end of file diff --git a/tests/kicad-parity/__snapshots__/plcc44_parity._boolean_difference.snap.svg b/tests/kicad-parity/__snapshots__/plcc44_parity._boolean_difference.snap.svg new file mode 100644 index 00000000..6ad81776 --- /dev/null +++ b/tests/kicad-parity/__snapshots__/plcc44_parity._boolean_difference.snap.svg @@ -0,0 +1 @@ +PLCC-44_16.6x16.6mm_P1.27mm - Alignment Analysis (Footprinter vs KiCad)plcc44_w16.6_h16.6_p1.27mmKiCad: PLCC-44_16.6x16.6mm_P1.27mmPerfect alignment = complete overlap \ No newline at end of file diff --git a/tests/kicad-parity/__snapshots__/plcc44_parity.snap.svg b/tests/kicad-parity/__snapshots__/plcc44_parity.snap.svg new file mode 100644 index 00000000..74baae47 --- /dev/null +++ b/tests/kicad-parity/__snapshots__/plcc44_parity.snap.svg @@ -0,0 +1 @@ +{REF}Diff: 0.00% \ No newline at end of file diff --git a/tests/kicad-parity/plcc_kikac_parity.test.ts b/tests/kicad-parity/plcc_kikac_parity.test.ts new file mode 100644 index 00000000..d6f6a624 --- /dev/null +++ b/tests/kicad-parity/plcc_kikac_parity.test.ts @@ -0,0 +1,18 @@ +import { expect, test } from "bun:test" +import { compareFootprinterVsKicad } from "../fixtures/compareFootprinterVsKicad" +import { convertCircuitJsonToPcbSvg } from "circuit-to-svg" + +test("parity/plcc44", async () => { + const { combinedFootprintElements, booleanDifferenceSvg } = + await compareFootprinterVsKicad( + "plcc44_w16.6_h16.6_p1.27mm", + "Package_LCC.pretty/PLCC-44_16.6x16.6mm_P1.27mm.circuit.json", + ) + + const svgContent = convertCircuitJsonToPcbSvg(combinedFootprintElements) + expect(svgContent).toMatchSvgSnapshot(import.meta.path, "plcc44_parity") + expect(booleanDifferenceSvg).toMatchSvgSnapshot( + import.meta.path, + "plcc44_parity._boolean_difference", + ) +}) \ No newline at end of file diff --git a/tests/plcc.test.ts b/tests/plcc.test.ts new file mode 100644 index 00000000..db3ce4c1 --- /dev/null +++ b/tests/plcc.test.ts @@ -0,0 +1,12 @@ +import { test, expect } from "bun:test" +import { convertCircuitJsonToPcbSvg } from "circuit-to-svg" +import { fp } from "../src/footprinter" + +test("plcc44_w16.5_h16.5_p1.27mm", () => { + const soup = fp.string("plcc44_w16.5_h16.5_p1.27mm").circuitJson() + const svgContent = convertCircuitJsonToPcbSvg(soup) + expect(svgContent).toMatchSvgSnapshot( + import.meta.path, + "plcc44_w16.5_h16.5_p1.27mm", + ) +}) \ No newline at end of file From a3dcd14f4baa2bc934b698350fdf7f4a9ecc7012 Mon Sep 17 00:00:00 2001 From: Sahil Gupta Date: Thu, 8 Jan 2026 13:19:51 +0530 Subject: [PATCH 2/2] format --- src/fn/index.ts | 2 +- src/fn/plcc.ts | 40 ++++++++++---------- src/fn/quad.ts | 2 +- tests/kicad-parity/plcc_kikac_parity.test.ts | 24 ++++++------ tests/plcc.test.ts | 14 +++---- 5 files changed, 41 insertions(+), 41 deletions(-) diff --git a/src/fn/index.ts b/src/fn/index.ts index 8c7eea6a..16715dc4 100644 --- a/src/fn/index.ts +++ b/src/fn/index.ts @@ -78,4 +78,4 @@ export { sot } from "./sot" export { sot343 } from "./sot343" export { m2host } from "./m2host" export { to92l } from "./to92l" -export { plcc } from "./plcc" \ No newline at end of file +export { plcc } from "./plcc" diff --git a/src/fn/plcc.ts b/src/fn/plcc.ts index 13b80735..f0225fa8 100644 --- a/src/fn/plcc.ts +++ b/src/fn/plcc.ts @@ -5,29 +5,29 @@ import type { z } from "zod" export const plcc_def = quad_def export const plcc = ( - raw_params: z.input, + raw_params: z.input, ): { circuitJson: AnyCircuitElement[]; parameters: any } => { - if (!raw_params.p) { - raw_params.p = 1.27 - } + if (!raw_params.p) { + raw_params.p = 1.27 + } - if (!raw_params.pl) { - raw_params.pl = 1.7 - } + if (!raw_params.pl) { + raw_params.pl = 1.7 + } - if (!raw_params.pw) { - raw_params.pw = 0.6 - } + if (!raw_params.pw) { + raw_params.pw = 0.6 + } - if (raw_params.pcdfe === undefined && raw_params.w) { - const w = - typeof raw_params.w === "number" - ? raw_params.w - : parseFloat(raw_params.w as string) - if (!isNaN(w)) { - raw_params.pcdfe = 8.0 - w / 2 - } + if (raw_params.pcdfe === undefined && raw_params.w) { + const w = + typeof raw_params.w === "number" + ? raw_params.w + : parseFloat(raw_params.w as string) + if (!isNaN(w)) { + raw_params.pcdfe = 8.0 - w / 2 } + } - return quad(raw_params) -} \ No newline at end of file + return quad(raw_params) +} diff --git a/src/fn/quad.ts b/src/fn/quad.ts index c46ee2b1..c63ed00f 100644 --- a/src/fn/quad.ts +++ b/src/fn/quad.ts @@ -133,7 +133,7 @@ export const quad = ( p: parameters.p ?? 0.5, pl: parameters.pl, legsoutside: parameters.legsoutside, - pcdfe: parameters.pcdfe + pcdfe: parameters.pcdfe, }) let pw = parameters.pw diff --git a/tests/kicad-parity/plcc_kikac_parity.test.ts b/tests/kicad-parity/plcc_kikac_parity.test.ts index d6f6a624..c79e3a4a 100644 --- a/tests/kicad-parity/plcc_kikac_parity.test.ts +++ b/tests/kicad-parity/plcc_kikac_parity.test.ts @@ -3,16 +3,16 @@ import { compareFootprinterVsKicad } from "../fixtures/compareFootprinterVsKicad import { convertCircuitJsonToPcbSvg } from "circuit-to-svg" test("parity/plcc44", async () => { - const { combinedFootprintElements, booleanDifferenceSvg } = - await compareFootprinterVsKicad( - "plcc44_w16.6_h16.6_p1.27mm", - "Package_LCC.pretty/PLCC-44_16.6x16.6mm_P1.27mm.circuit.json", - ) - - const svgContent = convertCircuitJsonToPcbSvg(combinedFootprintElements) - expect(svgContent).toMatchSvgSnapshot(import.meta.path, "plcc44_parity") - expect(booleanDifferenceSvg).toMatchSvgSnapshot( - import.meta.path, - "plcc44_parity._boolean_difference", + const { combinedFootprintElements, booleanDifferenceSvg } = + await compareFootprinterVsKicad( + "plcc44_w16.6_h16.6_p1.27mm", + "Package_LCC.pretty/PLCC-44_16.6x16.6mm_P1.27mm.circuit.json", ) -}) \ No newline at end of file + + const svgContent = convertCircuitJsonToPcbSvg(combinedFootprintElements) + expect(svgContent).toMatchSvgSnapshot(import.meta.path, "plcc44_parity") + expect(booleanDifferenceSvg).toMatchSvgSnapshot( + import.meta.path, + "plcc44_parity._boolean_difference", + ) +}) diff --git a/tests/plcc.test.ts b/tests/plcc.test.ts index db3ce4c1..6d79136f 100644 --- a/tests/plcc.test.ts +++ b/tests/plcc.test.ts @@ -3,10 +3,10 @@ import { convertCircuitJsonToPcbSvg } from "circuit-to-svg" import { fp } from "../src/footprinter" test("plcc44_w16.5_h16.5_p1.27mm", () => { - const soup = fp.string("plcc44_w16.5_h16.5_p1.27mm").circuitJson() - const svgContent = convertCircuitJsonToPcbSvg(soup) - expect(svgContent).toMatchSvgSnapshot( - import.meta.path, - "plcc44_w16.5_h16.5_p1.27mm", - ) -}) \ No newline at end of file + const soup = fp.string("plcc44_w16.5_h16.5_p1.27mm").circuitJson() + const svgContent = convertCircuitJsonToPcbSvg(soup) + expect(svgContent).toMatchSvgSnapshot( + import.meta.path, + "plcc44_w16.5_h16.5_p1.27mm", + ) +})