← Commit history

Merge PR #321: altium-lane: marking font, D and B no longer read as IO and 8 (body3d)

Colby Knox ·d520b30660 ·13d ago ·parent 80fb480
1 file changed +19−1
engine/src/writers/body3d.rs+19−1
@@ -312,10 +312,16 @@ fn glyph(c: char) -> Option<&'static [((f64, f64), (f64, f64))]> {     const DBL: ((f64, f64), (f64, f64)) = (MM, BL); const DBR: ((f64, f64), (f64, f64)) = (MM, BR);     const LB: ((f64, f64), (f64, f64)) = (ML, BM); const RB: ((f64, f64), (f64, f64)) = (MR, BM);     const DOT: ((f64, f64), (f64, f64)) = ((0.4, 0.0), (0.6, 0.0));+    // D and B: the left side full and the right corners cut, so D does not read as I and O side by side (it was a+    // box with a centre bar: "ADOM" read "AIOM" on a QFN in Altium, 2026-10-28) and B is not an 8+    const KT: (f64, f64) = (0.75, 2.0); const KM: (f64, f64) = (0.75, 1.0); const KB: (f64, f64) = (0.75, 0.0);+    const RT: (f64, f64) = (1.0, 1.75); const RU: (f64, f64) = (1.0, 1.25); const RL: (f64, f64) = (1.0, 0.75); const RB0: (f64, f64) = (1.0, 0.25);+    const DG: &[((f64, f64), (f64, f64))] = &[F, E, (TL, KT), (KT, RT), (RT, RB0), (RB0, KB), (BL, KB)];+    const BG: &[((f64, f64), (f64, f64))] = &[F, E, (TL, KT), (KT, RT), (RT, RU), (RU, KM), (ML, KM), (KM, RL), (RL, RB0), (RB0, KB), (BL, KB)];     Some(match c.to_ascii_uppercase() {         '0' => &[A, B, C, D, E, F, DTR, DBL], '1' => &[V], '2' => &[A, B, G, E, D], '3' => &[A, B, G2, C, D],         '4' => &[F, G, B, C], '5' => &[A, F, G, C, D], '6' => &[A, F, E, D, C, G], '7' => &[A, B, C], '8' => &[A, B, C, D, E, F, G],-        '9' => &[A, B, C, D, F, G], 'A' => &[E, F, A, B, C, G], 'B' => &[A, B, C, D, V, G2], 'C' => &[A, F, E, D], 'D' => &[A, B, C, D, V],+        '9' => &[A, B, C, D, F, G], 'A' => &[E, F, A, B, C, G], 'B' => BG, 'C' => &[A, F, E, D], 'D' => DG,         'E' => &[A, F, E, D, G1], 'F' => &[A, F, E, G1], 'G' => &[A, F, E, D, C, G2], 'H' => &[F, E, B, C, G], 'I' => &[A, V, D],         'J' => &[B, C, D, E], 'K' => &[F, E, G1, DTR, DBR], 'L' => &[F, E, D], 'M' => &[E, F, B, C, DTL, DTR], 'N' => &[E, F, B, C, DTL, DBR],         'O' => &[A, B, C, D, E, F], 'P' => &[A, B, F, E, G], 'Q' => &[A, B, C, D, E, F, DBR], 'R' => &[A, B, F, E, G, DBR],@@ -520,4 +526,16 @@ mod tests {         // pins is the total in a BGA too: 64 balls are an 8 x 8 grid         assert_eq!(package("bga", json!({"pins": 64}).as_object().unwrap()).unwrap().len(), 65);     }++    #[test]+    fn d_and_b_are_not_i_o_or_8() {+        // D was a box with a centre bar and read as "IO"; B was an 8 with a bar+        assert_ne!(glyph('D'), glyph('O'));+        assert_ne!(glyph('B'), glyph('8'));+        for c in ['D', 'B'] {+            let g = glyph(c).unwrap();+            assert!(g.iter().all(|s| s.0 .0 != 0.5 || s.1 .0 != 0.5), "{c} has no centre bar");+            assert!(!g.iter().any(|s| (s.0 == (1.0, 2.0)) || (s.1 == (1.0, 2.0))), "{c}'s top-right corner is cut");+        }+    } }