From 26231b2f48d62220e4764d47e12013fc0cd8a401 Mon Sep 17 00:00:00 2001 From: LordBaryhobal Date: Sat, 19 Apr 2025 00:11:53 +0200 Subject: [PATCH] adapted wire stubs with auto side detection --- gallery/target_api.pdf | Bin 6072 -> 7099 bytes gallery/target_api.typ | 16 +------ src/util.typ | 13 +++++- src/wire.typ | 103 +++++++++++++++++++++++++++-------------- 4 files changed, 80 insertions(+), 52 deletions(-) diff --git a/gallery/target_api.pdf b/gallery/target_api.pdf index e56479de9be760ab82fe19b546b7c6458bb4f9c7..840b7562c8c05e13e9a38b06c039a836eb3e0055 100644 GIT binary patch delta 3585 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 WuP}OKn2#?Ai^X6;YHBAOE&l{uFI6`H diff --git a/gallery/target_api.typ b/gallery/target_api.typ index 991caf9..6b810ef 100644 --- a/gallery/target_api.typ +++ b/gallery/target_api.typ @@ -13,25 +13,11 @@ ), debug: (ports: true) ) - - element.block( - size: (1, 2), - ports: ( - west: (("a", "A"), "e"), - north: "b", - east: "c", - south: "d" - ), - pos: ( - (offset: -1, from: "PCBuf.south"), - 2,//(align: "e", with: "PCBuf.EN"), - ) - ) - /* wire.stub("PCBuf.CLK", name: "CLK") wire.stub("PCBuf.EN", name: "PCWrite") + /* element.multiplexer( pos: ( 3, (align: "in0", with: "PCBuf.PC") diff --git a/src/util.typ b/src/util.typ index a444434..037ae67 100644 --- a/src/util.typ +++ b/src/util.typ @@ -73,4 +73,15 @@ #let valid-anchors = ( "center", "north", "east", "west", "south", "north-east", "north-west", "south-east", "south-west" -) \ No newline at end of file +) + +#let get-port-side(element, port) = { + for (side, ports) in element.ports { + for p in ports { + if p.id == port { + return side + } + } + } + panic("Unknown port " + port + " on element " + element.id) +} \ No newline at end of file diff --git a/src/wire.typ b/src/wire.typ index 8300a2c..661faed 100644 --- a/src/wire.typ +++ b/src/wire.typ @@ -1,5 +1,6 @@ #import "@preview/cetz:0.3.2": draw, coordinate -#import "util.typ": opposite-anchor +#import "util.typ": opposite-anchor, get-port-side +#import "elements/element.typ" /// List of valid wire styles /// #examples.wires @@ -267,40 +268,70 @@ /// - vertical (bool): Whether the name should be displayed vertically /// - length (number): The length of the stub /// - name-offset (number): The name offset, perpendicular to the stub -#let stub(port-id, side, name: none, vertical: false, length: 1em, name-offset: 0) = { - let end-offset = ( - north: (0, length), - east: (length, 0), - south: (0, -length), - west: (-length, 0) - ).at(side) - - let name-offset = ( - north: (name-offset, length), - east: (length, name-offset), - south: (name-offset, -length), - west: (-length, name-offset) - ).at(side) - - draw.line( - port-id, - (rel: end-offset, to: port-id) - ) - if name != none { - let text-anchor = if vertical { - ( - "north": "west", - "south": "east", - "west": "south", - "east": "north" - ).at(side) - } else { opposite-anchor(side) } - draw.content( - anchor: text-anchor, - padding: 0.2em, - angle: if vertical {90deg} else {0deg}, - (rel: name-offset, to: port-id), - name - ) +#let stub(anchor, name: none, vertical: false, length: 1em, name-offset: 0) = { + if "." not in anchor { + panic("`anchor` must be a valid anchor of an element") } + let parts = anchor.split(".") + let port-id = parts.last() + let port-elmt-id = parts.slice(0, -1).join(".") + + let pre-process = (elements, elmt) => { + let eid = elmt.id + + if port-elmt-id not in elements { + panic("Unknown element " + port-elmt-id) + } + let port-elmt = elements.at(port-elmt-id) + let side = get-port-side(port-elmt, port-id) + elements.at(eid).insert("side", side) + return elements + } + + let draw-func(elmt, bounds) = { + let side = elmt.side + let end-offset = ( + north: (0, length), + east: (length, 0), + south: (0, -length), + west: (-length, 0) + ).at(side) + + let name-offset = ( + north: (name-offset, length), + east: (length, name-offset), + south: (name-offset, -length), + west: (-length, name-offset) + ).at(side) + + let shapes = () + shapes += draw.line( + anchor, + (rel: end-offset, to: anchor) + ) + if name != none { + let text-anchor = if vertical { + ( + "north": "west", + "south": "east", + "west": "south", + "east": "north" + ).at(side) + } else { opposite-anchor(side) } + shapes += draw.content( + anchor: text-anchor, + padding: 0.2em, + angle: if vertical {90deg} else {0deg}, + (rel: name-offset, to: anchor), + name + ) + } + + return (shapes, bounds) + } + + return element.elmt( + draw-shape: draw-func, + pre-process: pre-process + ) } \ No newline at end of file