Compare commits

..

3 Commits
main ... main

Author SHA1 Message Date
3aca407ce5 add arrow on stub 2024-10-06 16:05:41 +07:00
64278c924c disable font 2024-10-06 00:19:26 +07:00
4e125ef40c change y logic to relative 2024-10-05 00:18:25 +07:00
3 changed files with 85 additions and 53 deletions

View File

@ -9,6 +9,6 @@
/// - length (length, ratio): Optional base unit /// - length (length, ratio): Optional base unit
/// -> none /// -> none
#let circuit(body, length: 2em) = { #let circuit(body, length: 2em) = {
set text(font: "Source Sans 3") // set text(font: "Source Sans 3")
canvas(length: length, body) canvas(length: length, body)
} }

View File

@ -54,20 +54,24 @@
let (ctx, to-pos) = coordinate.resolve(ctx, (rel: (offset, 0), to: to)) let (ctx, to-pos) = coordinate.resolve(ctx, (rel: (offset, 0), to: to))
x = to-pos.at(0) x = to-pos.at(0)
} }
if (type(y) == dictionary) { if (type(y) == dictionary) {
let from = y.from let offset = y.rel
let to = y.to let to = y.to
let (ctx, to-pos) = coordinate.resolve(ctx, (rel: (0, offset), to: to))
let dy y = to-pos.at(1)
if to == "out" { // let from = y.from
dy = height / 2 // let to = y.to
} else {
dy = height * (i + 0.5) / inputs // let dy
} // if to == "out" {
// dy = height / 2
let (ctx, from-pos) = coordinate.resolve(ctx, from) // } else {
y = from-pos.at(1) + dy - height // dy = height * (i + 0.5) / inputs
// }
// let (ctx, from-pos) = coordinate.resolve(ctx, from)
// y = from-pos.at(1) + dy - height
} }
let tl = (x, y + height) let tl = (x, y + height)

View File

@ -19,7 +19,7 @@
#let get-direct-wire(pts) = { #let get-direct-wire(pts) = {
let anchors = ( let anchors = (
"start": pts.first(), "start": pts.first(),
"end": pts.last() "end": pts.last(),
) )
return (pts, anchors) return (pts, anchors)
} }
@ -38,21 +38,21 @@
start, start,
(horizontal: mid, vertical: ()), (horizontal: mid, vertical: ()),
(horizontal: (), vertical: end), (horizontal: (), vertical: end),
end end,
) )
} else { } else {
( (
start, start,
(horizontal: (), vertical: mid), (horizontal: (), vertical: mid),
(horizontal: end, vertical: ()), (horizontal: end, vertical: ()),
end end,
) )
} }
let anchors = ( let anchors = (
"start": start, "start": start,
"zig": points.at(1), "zig": points.at(1),
"zag": points.at(2), "zag": points.at(2),
"end": end "end": end,
) )
return (points, anchors) return (points, anchors)
} }
@ -65,7 +65,7 @@
let p1 = (start, margin-start, end) let p1 = (start, margin-start, end)
let p2 = (end, margin-end, start) let p2 = (end, margin-end, start)
let (ctx, p0) = coordinate.resolve(ctx, start) let (ctx, p0) = coordinate.resolve(ctx, start)
let (ctx, p3) = coordinate.resolve(ctx, end) let (ctx, p3) = coordinate.resolve(ctx, end)
p0 = (x: p0.first(), y: p0.last()) p0 = (x: p0.first(), y: p0.last())
@ -73,7 +73,7 @@
let dx1 = margin-start let dx1 = margin-start
let dx2 = margin-end let dx2 = margin-end
if type(margin-start) == ratio { if type(margin-start) == ratio {
dx1 = calc.abs(p3.x - p0.x) * margin-start / 100% dx1 = calc.abs(p3.x - p0.x) * margin-start / 100%
} }
@ -95,7 +95,7 @@
(horizontal: (), vertical: (0, dodge-y)), (horizontal: (), vertical: (0, dodge-y)),
(horizontal: p2, vertical: ()), (horizontal: p2, vertical: ()),
(horizontal: (), vertical: end), (horizontal: (), vertical: end),
end end,
) )
let anchors = ( let anchors = (
"start": start, "start": start,
@ -103,7 +103,7 @@
"dodge-start": points.at(2), "dodge-start": points.at(2),
"dodge-end": points.at(3), "dodge-end": points.at(3),
"end2": points.at(4), "end2": points.at(4),
"end": end "end": end,
) )
return (points, anchors) 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-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") /// - dodge-margins (array): The start and end margins (i.e. space before dodging) of the wire (only with style "dodge")
#let wire( #let wire(
id, pts, id,
pts,
bus: false, bus: false,
name: none, name: none,
name-pos: "middle", name-pos: "middle",
@ -143,7 +144,7 @@
zigzag-dir: "vertical", zigzag-dir: "vertical",
dodge-y: 0, dodge-y: 0,
dodge-sides: ("east", "west"), dodge-sides: ("east", "west"),
dodge-margins: (5%, 5%) dodge-margins: (5%, 5%),
) = draw.get-ctx(ctx => { ) = draw.get-ctx(ctx => {
if not style in wire-styles { if not style in wire-styles {
panic("Invalid wire style '" + style + "'") panic("Invalid wire style '" + style + "'")
@ -152,10 +153,14 @@
if pts.len() != 2 { if pts.len() != 2 {
panic("Wrong number of points (got " + str(pts.len()) + " instead of 2)") panic("Wrong number of points (got " + str(pts.len()) + " instead of 2)")
} }
let stroke = ( let stroke = (
paint: color, paint: color,
thickness: if bus {bus-width} else {signal-width} thickness: if bus {
bus-width
} else {
signal-width
},
) )
if dashed { if dashed {
stroke.insert("dash", "dashed") stroke.insert("dash", "dashed")
@ -166,17 +171,17 @@
if style == "direct" { if style == "direct" {
(points, anchors) = get-direct-wire(pts) (points, anchors) = get-direct-wire(pts)
} else if style == "zigzag" { } else if style == "zigzag" {
(points, anchors) = get-zigzag-wire(pts, zigzag-ratio, zigzag-dir) (points, anchors) = get-zigzag-wire(pts, zigzag-ratio, zigzag-dir)
} else if style == "dodge" { } else if style == "dodge" {
(points, anchors) = get-dodge-wire( (points, anchors) = get-dodge-wire(
pts, pts,
dodge-y, dodge-y,
dodge-margins, dodge-margins,
dodge-sides, dodge-sides,
ctx ctx,
) )
} }
@ -184,12 +189,15 @@
if directed { if directed {
mark = (end: ">", fill: color) mark = (end: ">", fill: color)
} }
draw.group(name: id, { draw.group(
draw.line(..points, stroke: stroke, mark: mark) name: id,
for (anchor-name, anchor-pos) in anchors { {
draw.anchor(anchor-name, anchor-pos) 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 first-pt = id + ".start"
let last-pt = id + ".end" let last-pt = id + ".end"
@ -198,12 +206,12 @@
if reverse { if reverse {
(first-pt, last-pt) = (last-pt, first-pt) (first-pt, last-pt) = (last-pt, first-pt)
} }
let angle = 0deg let angle = 0deg
if rotate-name { if rotate-name {
(ctx, first-pos) = coordinate.resolve(ctx, first-pos) (ctx, first-pos) = coordinate.resolve(ctx, first-pos)
(ctx, second-pos) = coordinate.resolve(ctx, second-pos) (ctx, second-pos) = coordinate.resolve(ctx, second-pos)
if reverse { if reverse {
(first-pos, second-pos) = (second-pos, first-pos) (first-pos, second-pos) = (second-pos, first-pos)
} }
@ -211,24 +219,24 @@
let (x2, y2, ..) = second-pos let (x2, y2, ..) = second-pos
angle = calc.atan2(x2 - x1, y2 - y1) angle = calc.atan2(x2 - x1, y2 - y1)
} }
if name != none { if name != none {
let names = () let names = ()
if type(name) == str { if type(name) == str or type(name) == content {
names = ((name, name-pos),) names = ((name, name-pos),)
} else if type(name) == array { } else if type(name) == array {
names = ( names = (
(name.at(0), "start"), (name.at(0), "start"),
(name.at(1), "end") (name.at(1), "end"),
) )
} }
for (name, pos) in names { for (name, pos) in names {
let point let point
let anchor let anchor
if pos == "middle" { if pos == "middle" {
point = (first-pt, 50%, last-pt) point = (first-pt, 50%, last-pt)
anchor = "south" anchor = "south"
@ -248,12 +256,12 @@
if slice != none { if slice != none {
let slice-txt = "[" + slice.map(b => str(b)).join(":") + "]" let slice-txt = "[" + slice.map(b => str(b)).join(":") + "]"
draw.content( draw.content(
first-pt, first-pt,
anchor: "south-west", anchor: "south-west",
padding: 3pt, 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 /// - vertical (bool): Whether the name should be displayed vertically
/// - length (number): The length of the stub /// - length (number): The length of the stub
/// - name-offset (number): The name offset, perpendicular to 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 = ( let end-offset = (
north: (0, length), north: (0, length),
east: (length, 0), east: (length, 0),
south: (0, -length), south: (0, -length),
west: (-length, 0) west: (-length, 0),
).at(side) ).at(side)
let name-offset = ( let name-offset = (
north: (name-offset, length), north: (name-offset, length),
east: (length, name-offset), east: (length, name-offset),
south: (name-offset, -length), south: (name-offset, -length),
west: (-length, name-offset) west: (-length, name-offset),
).at(side) ).at(side)
let mark = (fill: color)
if directed != none {
mark = ((directed): ">", fill: color)
}
draw.line( draw.line(
port-id, port-id,
(rel: end-offset, to: port-id) (rel: end-offset, to: port-id),
mark: mark,
) )
if name != none { if name != none {
let text-anchor = if vertical { let text-anchor = if vertical {
@ -292,15 +314,21 @@
"north": "west", "north": "west",
"south": "east", "south": "east",
"west": "south", "west": "south",
"east": "north" "east": "north",
).at(side) ).at(side)
} else { opposite-anchor(side) } } else {
opposite-anchor(side)
}
draw.content( draw.content(
anchor: text-anchor, anchor: text-anchor,
padding: 0.2em, padding: 0.2em,
angle: if vertical {90deg} else {0deg}, angle: if vertical {
90deg
} else {
0deg
},
(rel: name-offset, to: port-id), (rel: name-offset, to: port-id),
name name,
) )
} }
} }