From 3aca407ce5bd4e2c5a15d0fbc742f4974cd8c0a5 Mon Sep 17 00:00:00 2001 From: nafkhanzam Date: Sun, 6 Oct 2024 16:05:41 +0700 Subject: [PATCH] add arrow on stub --- src/wire.typ | 108 ++++++++++++++++++++++++++++++++------------------- 1 file changed, 68 insertions(+), 40 deletions(-) diff --git a/src/wire.typ b/src/wire.typ index 07a3ac1..f5de4b2 100644 --- a/src/wire.typ +++ b/src/wire.typ @@ -19,7 +19,7 @@ #let get-direct-wire(pts) = { let anchors = ( "start": pts.first(), - "end": pts.last() + "end": pts.last(), ) return (pts, anchors) } @@ -38,21 +38,21 @@ start, (horizontal: mid, vertical: ()), (horizontal: (), vertical: end), - end + end, ) } else { ( start, (horizontal: (), vertical: mid), (horizontal: end, vertical: ()), - end + end, ) } let anchors = ( "start": start, "zig": points.at(1), "zag": points.at(2), - "end": end + "end": end, ) return (points, anchors) } @@ -65,7 +65,7 @@ let p1 = (start, margin-start, end) let p2 = (end, margin-end, start) - + let (ctx, p0) = coordinate.resolve(ctx, start) let (ctx, p3) = coordinate.resolve(ctx, end) p0 = (x: p0.first(), y: p0.last()) @@ -73,7 +73,7 @@ let dx1 = margin-start let dx2 = margin-end - + if type(margin-start) == ratio { dx1 = calc.abs(p3.x - p0.x) * margin-start / 100% } @@ -95,7 +95,7 @@ (horizontal: (), vertical: (0, dodge-y)), (horizontal: p2, vertical: ()), (horizontal: (), vertical: end), - end + end, ) let anchors = ( "start": start, @@ -103,7 +103,7 @@ "dodge-start": points.at(2), "dodge-end": points.at(3), "end2": points.at(4), - "end": end + "end": end, ) return (points, anchors) @@ -128,7 +128,8 @@ /// - dodge-sides (array): The start and end sides (going out of the connected element) of the wire (only with style "dodge") /// - dodge-margins (array): The start and end margins (i.e. space before dodging) of the wire (only with style "dodge") #let wire( - id, pts, + id, + pts, bus: false, name: none, name-pos: "middle", @@ -143,7 +144,7 @@ zigzag-dir: "vertical", dodge-y: 0, dodge-sides: ("east", "west"), - dodge-margins: (5%, 5%) + dodge-margins: (5%, 5%), ) = draw.get-ctx(ctx => { if not style in wire-styles { panic("Invalid wire style '" + style + "'") @@ -152,10 +153,14 @@ if pts.len() != 2 { panic("Wrong number of points (got " + str(pts.len()) + " instead of 2)") } - + let stroke = ( paint: color, - thickness: if bus {bus-width} else {signal-width} + thickness: if bus { + bus-width + } else { + signal-width + }, ) if dashed { stroke.insert("dash", "dashed") @@ -166,17 +171,17 @@ if style == "direct" { (points, anchors) = get-direct-wire(pts) - + } else if style == "zigzag" { (points, anchors) = get-zigzag-wire(pts, zigzag-ratio, zigzag-dir) - + } else if style == "dodge" { (points, anchors) = get-dodge-wire( pts, dodge-y, dodge-margins, dodge-sides, - ctx + ctx, ) } @@ -184,12 +189,15 @@ if directed { mark = (end: ">", fill: color) } - draw.group(name: id, { - draw.line(..points, stroke: stroke, mark: mark) - for (anchor-name, anchor-pos) in anchors { - draw.anchor(anchor-name, anchor-pos) - } - }) + draw.group( + name: id, + { + draw.line(..points, stroke: stroke, mark: mark) + for (anchor-name, anchor-pos) in anchors { + draw.anchor(anchor-name, anchor-pos) + } + }, + ) let first-pt = id + ".start" let last-pt = id + ".end" @@ -198,12 +206,12 @@ if reverse { (first-pt, last-pt) = (last-pt, first-pt) } - + let angle = 0deg if rotate-name { (ctx, first-pos) = coordinate.resolve(ctx, first-pos) (ctx, second-pos) = coordinate.resolve(ctx, second-pos) - + if reverse { (first-pos, second-pos) = (second-pos, first-pos) } @@ -211,24 +219,24 @@ let (x2, y2, ..) = second-pos angle = calc.atan2(x2 - x1, y2 - y1) } - + if name != none { let names = () - - if type(name) == str { + + if type(name) == str or type(name) == content { names = ((name, name-pos),) - + } else if type(name) == array { names = ( (name.at(0), "start"), - (name.at(1), "end") + (name.at(1), "end"), ) } for (name, pos) in names { let point let anchor - + if pos == "middle" { point = (first-pt, 50%, last-pt) anchor = "south" @@ -248,12 +256,12 @@ if slice != none { let slice-txt = "[" + slice.map(b => str(b)).join(":") + "]" - + draw.content( first-pt, anchor: "south-west", padding: 3pt, - text(slice-txt, size: 0.75em) + text(slice-txt, size: 0.75em), ) } }) @@ -267,24 +275,38 @@ /// - 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 stub( + port-id, + side, + name: none, + vertical: false, + length: 1em, + name-offset: 0, + color: black, + directed: none, +) = { let end-offset = ( north: (0, length), east: (length, 0), south: (0, -length), - west: (-length, 0) + west: (-length, 0), ).at(side) - + let name-offset = ( north: (name-offset, length), east: (length, name-offset), south: (name-offset, -length), - west: (-length, name-offset) + west: (-length, name-offset), ).at(side) + let mark = (fill: color) + if directed != none { + mark = ((directed): ">", fill: color) + } draw.line( port-id, - (rel: end-offset, to: port-id) + (rel: end-offset, to: port-id), + mark: mark, ) if name != none { let text-anchor = if vertical { @@ -292,15 +314,21 @@ "north": "west", "south": "east", "west": "south", - "east": "north" + "east": "north", ).at(side) - } else { opposite-anchor(side) } + } else { + opposite-anchor(side) + } draw.content( anchor: text-anchor, padding: 0.2em, - angle: if vertical {90deg} else {0deg}, + angle: if vertical { + 90deg + } else { + 0deg + }, (rel: name-offset, to: port-id), - name + name, ) } } \ No newline at end of file