initial rewrite of drawing pipeline + positioning
This commit is contained in:
parent
2bb7e3b5a9
commit
358de4825d
BIN
gallery/target_api.pdf
Normal file
BIN
gallery/target_api.pdf
Normal file
Binary file not shown.
297
gallery/target_api.typ
Normal file
297
gallery/target_api.typ
Normal file
@ -0,0 +1,297 @@
|
||||
#import "../src/lib.typ": *
|
||||
#import "@preview/cetz:0.3.4": draw
|
||||
#circuit({
|
||||
element.block(
|
||||
size: (1.5, 2.2),
|
||||
id: "PCBuf",
|
||||
fill: util.colors.orange,
|
||||
ports: (
|
||||
west: "PCNext",
|
||||
north: (id: "CLK", clock: true),
|
||||
east: "PC",
|
||||
south: (("EN", "EN"),)
|
||||
),
|
||||
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")
|
||||
),
|
||||
size: (1, 2),
|
||||
id: "AdrSrc-MP",
|
||||
fill: util.colors.orange,
|
||||
entries: 2
|
||||
)
|
||||
wire.wire(
|
||||
"PCBuf.PC",
|
||||
"AdrSrc-MP.in0",
|
||||
id: "wPCBuf-InstDataMgr",
|
||||
name: "PC",
|
||||
bus: true
|
||||
)
|
||||
wire.stub("AdrSrc-MP.north", name: "AdrSrc")
|
||||
|
||||
element.block(
|
||||
pos: (
|
||||
6, (align: "A", with: "AdrSrc-MP.out")
|
||||
),
|
||||
size: (3, 4),
|
||||
id: "InstDataMgr",
|
||||
fill: util.colors.yellow,
|
||||
ports: (
|
||||
west: (
|
||||
("A", "A"),
|
||||
("WD", "WD")
|
||||
),
|
||||
north: (
|
||||
(id: "CLK", clock: true),
|
||||
(id: "WE", name: "WE", vertical: true),
|
||||
(id: "IRWrite", name: "IRWrite", vertical: true)
|
||||
),
|
||||
east: (
|
||||
("Instr", "Instr."),
|
||||
("RD", "RD")
|
||||
)
|
||||
),
|
||||
ports-margins: (
|
||||
west: (30%, 0%),
|
||||
east: (40%, 0%)
|
||||
)
|
||||
)
|
||||
wire.wire(
|
||||
"AdrSrc-MP.out",
|
||||
"InstDataMgr.A",
|
||||
id: "wAdrSrcMP-InstDataMgr",
|
||||
name: (none, "Adr"),
|
||||
bus: true
|
||||
)
|
||||
|
||||
wire.stub("InstDataMgr.CLK", name: "CLK")
|
||||
wire.stub("InstDataMgr.WE")
|
||||
wire.stub("InstDataMgr.IRWrite")
|
||||
wire.stub("InstDataMgr.WD")
|
||||
|
||||
element.block(
|
||||
pos: (
|
||||
15, (align: "WD3", with: "InstDataMgr.RD")
|
||||
),
|
||||
size: (3, 4),
|
||||
id: "RegFile",
|
||||
fill: util.colors.pink,
|
||||
ports: (
|
||||
west: (
|
||||
("A1", "A1"),
|
||||
("A2", "A2"),
|
||||
("A3", "A3"),
|
||||
("WD3", "WD3"),
|
||||
),
|
||||
north: (
|
||||
(id: "CLK", clock: true),
|
||||
(id: "WE3", name: "WE3", vertical: true)
|
||||
),
|
||||
east: (
|
||||
("RD1", "RD1"),
|
||||
("RD2", "RD2"),
|
||||
)
|
||||
),
|
||||
ports-margins: (
|
||||
east: (20%, 20%)
|
||||
)
|
||||
)
|
||||
wire.stub("RegFile.CLK", name: "CLK")
|
||||
wire.stub("RegFile.WE3", name: "Regwrite", name-offset: 0.6)
|
||||
wire.stub("RegFile.A2")
|
||||
wire.stub("RegFile.RD2")
|
||||
|
||||
element.extender(
|
||||
pos: (15, -3.5),
|
||||
size: (3, 1),
|
||||
id: "Extender",
|
||||
fill: util.colors.green
|
||||
)
|
||||
wire.wire(
|
||||
"Extender.north",
|
||||
(18, -2),
|
||||
id: "wExtender-ImmSrc",
|
||||
style: "zigzag",
|
||||
zigzag-ratio: 0%,
|
||||
name: (none, "ImmSrc"),
|
||||
bus: true
|
||||
)
|
||||
|
||||
let mid = ("InstDataMgr.east", 50%, "RegFile.west")
|
||||
wire.wire(
|
||||
"InstDataMgr.Instr",
|
||||
(vertical: (), horizontal: mid),
|
||||
id: "wInstDataMgr-Bus"
|
||||
name: ("Instr", none),
|
||||
bus: true
|
||||
)
|
||||
wire.wire(
|
||||
(v => (v.at(0), -3.5), mid),
|
||||
(horizontal: (), vertical: (0, 3.5)),
|
||||
id: "wBus",
|
||||
bus: true
|
||||
)
|
||||
wire.wire(
|
||||
"RegFile.A1",
|
||||
(horizontal: mid, vertical: ()),
|
||||
id: "wBus-RegFile-A1"
|
||||
name: (none, "RS1"),
|
||||
slice: (19, 15),
|
||||
reverse: true,
|
||||
bus: true
|
||||
)
|
||||
wire.wire(
|
||||
"RegFile.A3",
|
||||
(horizontal: mid, vertical: ()),
|
||||
id: "wBus-RegFile-A3"
|
||||
name: (none, "RD"),
|
||||
slice: (11, 7),
|
||||
reverse: true,
|
||||
bus: true
|
||||
)
|
||||
wire.wire(
|
||||
"Extender.in",
|
||||
(horizontal: mid, vertical: ()),
|
||||
id: "wBus-Extender"
|
||||
slice: (31, 7),
|
||||
reverse: true,
|
||||
bus: true
|
||||
)
|
||||
|
||||
element.alu(
|
||||
pos: (
|
||||
22, (align: "in1", with: "RegFile.RD1")
|
||||
),
|
||||
size: (1, 2),
|
||||
id: "ALU",
|
||||
fill: util.colors.purple
|
||||
)
|
||||
wire.wire(
|
||||
"RegFile.RD1",
|
||||
"ALU.in1",
|
||||
id: "wRegFile-ALU"
|
||||
name: ("A", "SrcA"),
|
||||
bus: true
|
||||
)
|
||||
|
||||
element.block(
|
||||
pos: (
|
||||
26, (align: "in", with: "ALU.out")
|
||||
),
|
||||
size: (1.5, 2),
|
||||
id: "OutBuf",
|
||||
fill: util.colors.orange,
|
||||
ports: (
|
||||
west: "in",
|
||||
north: (id: "CLK", clock: true),
|
||||
east: "out"
|
||||
)
|
||||
)
|
||||
wire.stub("OutBuf.CLK", name: "CLK")
|
||||
wire.wire(
|
||||
"ALU.out",
|
||||
"OutBuf.in",
|
||||
id: "wALU-OutBuf"
|
||||
name: "ALUResult",
|
||||
bus: true
|
||||
)
|
||||
|
||||
element.multiplexer(
|
||||
pos: (
|
||||
30, (align: "in0", with: "OutBuf.out")
|
||||
),
|
||||
size: (1, 2.5),
|
||||
id: "Res-MP",
|
||||
fill: util.colors.orange,
|
||||
entries: 3
|
||||
)
|
||||
wire.stub("Res-MP.north", name: "ResultSrc")
|
||||
wire.stub("Res-MP.in2")
|
||||
wire.wire(
|
||||
"OutBuf.out",
|
||||
"Res-MP.in0",
|
||||
id: "wOutBuf-ResMP"
|
||||
name: "ALUOut",
|
||||
bus: true
|
||||
)
|
||||
|
||||
wire.wire(
|
||||
"Extender.out",
|
||||
"ALU.in2",
|
||||
id: "wExt-ALU"
|
||||
name: ("ImmExt", "SrcB"),
|
||||
bus: true,
|
||||
style: "zigzag",
|
||||
zigzag-ratio: 60%
|
||||
)
|
||||
|
||||
wire.wire(
|
||||
"InstDataMgr.RD",
|
||||
"Res-MP.in1",
|
||||
id: "wInstDataMgr-ResMP"
|
||||
style: "dodge",
|
||||
dodge-y: -4,
|
||||
dodge-sides: ("east", "west"),
|
||||
name: ("Data", none),
|
||||
bus: true
|
||||
)
|
||||
|
||||
wire.wire(
|
||||
"Res-MP.out",
|
||||
"AdrSrc-MP.in1",
|
||||
id: "wResMP-AdrSrc"
|
||||
style: "dodge",
|
||||
dodge-y: -5,
|
||||
dodge-sides: ("east", "west"),
|
||||
dodge-margins: (0.5, 1),
|
||||
bus: true
|
||||
)
|
||||
|
||||
wire.wire(
|
||||
"Res-MP.out",
|
||||
"RegFile.WD3",
|
||||
id: "wResMP-RegFile"
|
||||
style: "dodge",
|
||||
dodge-y: -5,
|
||||
dodge-sides: ("east", "west"),
|
||||
dodge-margins: (0.5, 1),
|
||||
bus: true
|
||||
)
|
||||
|
||||
wire.wire(
|
||||
"Res-MP.out",
|
||||
"PCBuf.PCNext",
|
||||
id: "wResMP-PCBuf"
|
||||
style: "dodge",
|
||||
dodge-y: -5,
|
||||
dodge-sides: ("east", "west"),
|
||||
dodge-margins: (0.5, 1.5),
|
||||
name: (none, "PCNext"),
|
||||
bus: true
|
||||
)
|
||||
|
||||
wire.intersection("wResMP-RegFile.dodge-end", radius: .2)
|
||||
wire.intersection("wResMP-AdrSrc.dodge-end", radius: .2)
|
||||
*/
|
||||
})
|
@ -9,6 +9,38 @@
|
||||
/// - length (length, ratio): Optional base unit
|
||||
/// -> none
|
||||
#let circuit(body, length: 2em) = {
|
||||
set text(font: "Source Sans 3")
|
||||
canvas(length: length, body)
|
||||
let next-id = 0
|
||||
let elements = (:)
|
||||
|
||||
for element in body {
|
||||
let internal = type(element) == dictionary and "id" in element
|
||||
let eid = if internal {element.id} else {none}
|
||||
if eid == none {
|
||||
while str(next-id) in elements {
|
||||
next-id += 1
|
||||
}
|
||||
eid = str(next-id)
|
||||
if internal {
|
||||
element.id = eid
|
||||
}
|
||||
next-id += 1
|
||||
}
|
||||
elements.insert(eid, element)
|
||||
}
|
||||
|
||||
for element in elements.values() {
|
||||
if type(element) == dictionary and "pre-process" in element {
|
||||
elements = (element.pre-process)(elements, element)
|
||||
}
|
||||
}
|
||||
|
||||
canvas(length: length, {
|
||||
for element in elements.values() {
|
||||
if type(element) == dictionary and "draw" in element {
|
||||
(element.draw)(element)
|
||||
} else {
|
||||
(element,)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
@ -1,16 +1,15 @@
|
||||
#import "@preview/cetz:0.3.2": draw
|
||||
#import "element.typ"
|
||||
|
||||
#let draw-shape(id, tl, tr, br, bl, fill, stroke) = {
|
||||
#let draw-shape(elmt, bounds) = {
|
||||
let f = draw.rect(
|
||||
radius: 0.5em,
|
||||
inset: 0.5em,
|
||||
fill: fill,
|
||||
stroke: stroke,
|
||||
name: id,
|
||||
bl, tr
|
||||
fill: elmt.fill,
|
||||
stroke: elmt.stroke,
|
||||
bounds.bl, bounds.tr
|
||||
)
|
||||
return (f, tl, tr, br, bl)
|
||||
return (f, bounds)
|
||||
}
|
||||
|
||||
/// Draws a block element
|
||||
@ -18,32 +17,8 @@
|
||||
/// #examples.block
|
||||
/// For parameters description, see #doc-ref("element.elmt")
|
||||
#let block(
|
||||
x: none,
|
||||
y: none,
|
||||
w: none,
|
||||
h: none,
|
||||
name: none,
|
||||
name-anchor: "center",
|
||||
ports: (),
|
||||
ports-margins: (),
|
||||
fill: none,
|
||||
stroke: black + 1pt,
|
||||
id: "",
|
||||
debug: (
|
||||
ports: false
|
||||
)
|
||||
..args
|
||||
) = element.elmt(
|
||||
draw-shape: draw-shape,
|
||||
x: x,
|
||||
y: y,
|
||||
w: w,
|
||||
h: h,
|
||||
name: name,
|
||||
name-anchor: name-anchor,
|
||||
ports: ports,
|
||||
ports-margins: ports-margins,
|
||||
fill: fill,
|
||||
stroke: stroke,
|
||||
id: id,
|
||||
debug: debug
|
||||
..args
|
||||
)
|
@ -1,4 +1,4 @@
|
||||
#import "@preview/cetz:0.3.2": draw, coordinate
|
||||
#import "@preview/cetz:0.3.2": draw, coordinate, matrix, vector
|
||||
#import "ports.typ": add-ports, add-port
|
||||
#import "../util.typ"
|
||||
|
||||
@ -13,10 +13,163 @@
|
||||
panic("Could not find port with id " + str(id))
|
||||
}
|
||||
|
||||
#let default-draw-shape(id, tl, tr, br, bl, fill, stroke) = {
|
||||
return ({}, tl, tr, br, bl)
|
||||
#let local-to-global(origin, u, v, points) = {
|
||||
return points-real = points.map(p => {
|
||||
let (pu, pv) = p
|
||||
return vector.add(
|
||||
origin,
|
||||
vector.add(
|
||||
vector.scale(u, pu),
|
||||
vector.scale(v, pv)
|
||||
)
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
#let default-draw-shape(elmt, bounds) = {
|
||||
return ({}, bounds)
|
||||
}
|
||||
|
||||
#let default-pre-process(elements, element) = {
|
||||
return elements
|
||||
}
|
||||
|
||||
#let resolve-offset(ctx, offset, from, axis) = {
|
||||
let (ctx, pos) = coordinate.resolve(
|
||||
ctx,
|
||||
(rel: offset, to: from)
|
||||
)
|
||||
return pos.at(axis)
|
||||
}
|
||||
|
||||
#let resolve-align(ctx, elmt, align, with, axis) = {
|
||||
let (align-side, i) = find-port(elmt.ports, align)
|
||||
let margins = (0%, 0%)
|
||||
if align-side in elmt.ports-margins {
|
||||
margins = elmt.ports-margins.at(align-side)
|
||||
}
|
||||
|
||||
let parallel-sides = (
|
||||
("north", "south"),
|
||||
("west", "east")
|
||||
).at(axis)
|
||||
|
||||
let ortho-sides = (
|
||||
("west", "east"),
|
||||
("north", "south")
|
||||
).at(axis)
|
||||
|
||||
let dl
|
||||
let start-margin
|
||||
let len = elmt.size.at(axis)
|
||||
if align-side in parallel-sides {
|
||||
let used-pct = 100% - margins.at(0) - margins.at(1)
|
||||
let used-len = len * used-pct / 100%
|
||||
start-margin = len * margins.at(0) / 100%
|
||||
|
||||
dl = used-len * (i + 1) / (elmt.ports.at(align-side).len() + 1)
|
||||
|
||||
if not elmt.auto-ports {
|
||||
start-margin = 0
|
||||
dl = elmt.ports-pos.at(with)(len)
|
||||
}
|
||||
} else if align-side == ortho-sides.first() {
|
||||
dl = 0
|
||||
start-margin = 0
|
||||
} else {
|
||||
dl = len
|
||||
start-margin = 0
|
||||
}
|
||||
|
||||
if axis == 1 {
|
||||
dl = len - dl
|
||||
}
|
||||
|
||||
let (ctx, with-pos) = coordinate.resolve(ctx, with)
|
||||
return with-pos.at(axis) - dl + start-margin
|
||||
}
|
||||
|
||||
#let resolve-coordinate(ctx, elmt, coord, axis) = {
|
||||
if type(coord) == dictionary {
|
||||
let offset = coord.at("offset", default: none)
|
||||
let from = coord.at("from", default: none)
|
||||
let align = coord.at("align", default: none)
|
||||
let with = coord.at("with", default: none)
|
||||
|
||||
if none not in (offset, from) {
|
||||
if type(offset) != array {
|
||||
let a = (0, 0)
|
||||
a.at(axis) = offset
|
||||
offset = a
|
||||
}
|
||||
return resolve-offset(ctx, offset, from, axis)
|
||||
|
||||
} else if none not in (align, with) {
|
||||
return resolve-align(ctx, elmt, align, with, axis)
|
||||
} else {
|
||||
panic("Dictionnary must either provide both 'offset' and 'from', or 'align' and 'with'")
|
||||
}
|
||||
}
|
||||
if type(coord) not in (int, float, length) {
|
||||
panic("Invalid " + "xy".at(axis) + " coordinate: " + repr(coord))
|
||||
}
|
||||
return coord
|
||||
}
|
||||
|
||||
#let make-bounds(x, y, w, h) = {
|
||||
let w2 = w / 2
|
||||
let h2 = h / 2
|
||||
|
||||
return (
|
||||
bl: (x, y),
|
||||
tl: (x, y + h),
|
||||
tr: (x + w, y + h),
|
||||
br: (x + w, y),
|
||||
center: (x + w2, y + h2),
|
||||
b: (x + w2, y),
|
||||
t: (x + w2, y + h),
|
||||
l: (x, y + h2),
|
||||
r: (x + w, y + h2),
|
||||
)
|
||||
}
|
||||
|
||||
#let render(draw-shape, elmt) = draw.group(name: elmt.id, ctx => {
|
||||
let width = elmt.size.first()
|
||||
let height = elmt.size.last()
|
||||
|
||||
let x = elmt.pos.first()
|
||||
let y = elmt.pos.last()
|
||||
|
||||
x = resolve-coordinate(ctx, elmt, x, 0)
|
||||
y = resolve-coordinate(ctx, elmt, y, 1)
|
||||
|
||||
let bounds = make-bounds(x, y, width, height)
|
||||
|
||||
// Workaround because CeTZ needs to have all draw functions in the body
|
||||
let func = {}
|
||||
(func, bounds) = draw-shape(elmt, bounds)
|
||||
func
|
||||
|
||||
if elmt.name != none {
|
||||
draw.content(
|
||||
(name: elmt.id, anchor: elmt.name-anchor),
|
||||
anchor: if elmt.name-anchor in util.valid-anchors {elmt.name-anchor} else {"center"},
|
||||
padding: 0.5em,
|
||||
align(center)[*#elmt.name*]
|
||||
)
|
||||
}
|
||||
|
||||
if elmt.auto-ports {
|
||||
add-ports(
|
||||
elmt.id,
|
||||
bounds,
|
||||
elmt.ports,
|
||||
elmt.ports-margins,
|
||||
debug: elmt.debug.ports
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
/// Draws an element
|
||||
/// - draw-shape (function): Draw function
|
||||
/// - x (number, dictionary): The x position (bottom-left corner).
|
||||
@ -46,10 +199,9 @@
|
||||
/// - `ports`: if true, shows dots on all ports of the element
|
||||
#let elmt(
|
||||
draw-shape: default-draw-shape,
|
||||
x: none,
|
||||
y: none,
|
||||
w: none,
|
||||
h: none,
|
||||
pre-process: default-pre-process,
|
||||
pos: (0, 0),
|
||||
size: (1, 1),
|
||||
name: none,
|
||||
name-anchor: "center",
|
||||
ports: (:),
|
||||
@ -62,84 +214,42 @@
|
||||
debug: (
|
||||
ports: false
|
||||
)
|
||||
) = draw.get-ctx(ctx => {
|
||||
let width = w
|
||||
let height = h
|
||||
|
||||
let x = x
|
||||
let y = y
|
||||
if x == none { panic("Parameter x must be set") }
|
||||
if y == none { panic("Parameter y must be set") }
|
||||
if w == none { panic("Parameter w must be set") }
|
||||
if h == none { panic("Parameter h must be set") }
|
||||
|
||||
if (type(x) == dictionary) {
|
||||
let offset = x.rel
|
||||
let to = x.to
|
||||
let (ctx, to-pos) = coordinate.resolve(ctx, (rel: (offset, 0), to: to))
|
||||
x = to-pos.at(0)
|
||||
}
|
||||
|
||||
if (type(y) == dictionary) {
|
||||
let from = y.from
|
||||
let to = y.to
|
||||
let (to-side, i) = find-port(ports, to)
|
||||
let margins = (0%, 0%)
|
||||
if to-side in ports-margins {
|
||||
margins = ports-margins.at(to-side)
|
||||
) = {
|
||||
for (key, side-ports) in ports.pairs() {
|
||||
if type(side-ports) == str {
|
||||
side-ports = ((id: side-ports),)
|
||||
} else if type(side-ports) == dictionary {
|
||||
side-ports = (side-ports,)
|
||||
}
|
||||
|
||||
let dy
|
||||
let top-margin
|
||||
if to-side in ("east", "west") {
|
||||
let used-pct = 100% - margins.at(0) - margins.at(1)
|
||||
let used-height = height * used-pct / 100%
|
||||
top-margin = height * margins.at(0) / 100%
|
||||
|
||||
dy = used-height * (i + 1) / (ports.at(to-side).len() + 1)
|
||||
|
||||
if not auto-ports {
|
||||
top-margin = 0
|
||||
dy = ports-y.at(to)(height)
|
||||
for (i, port) in side-ports.enumerate() {
|
||||
if type(port) == array {
|
||||
side-ports.at(i) = (
|
||||
id: port.at(0, default: ""),
|
||||
name: port.at(1, default: "")
|
||||
)
|
||||
} else if type(port) == str {
|
||||
side-ports.at(i) = (id: port)
|
||||
}
|
||||
} else if to-side == "north" {
|
||||
dy = 0
|
||||
top-margin = 0
|
||||
} else if to-side == "south" {
|
||||
dy = height
|
||||
top-margin = 0
|
||||
}
|
||||
|
||||
let (ctx, from-pos) = coordinate.resolve(ctx, from)
|
||||
y = from-pos.at(1) + dy - height + top-margin
|
||||
ports.at(key) = side-ports
|
||||
}
|
||||
|
||||
let tl = (x, y + height)
|
||||
let tr = (x + width, y + height)
|
||||
let br = (x + width, y)
|
||||
let bl = (x, y)
|
||||
|
||||
// Workaround because CeTZ needs to have all draw functions in the body
|
||||
let func = {}
|
||||
(func, tl, tr, br, bl) = draw-shape(id, tl, tr, br, bl, fill, stroke)
|
||||
func
|
||||
|
||||
if (name != none) {
|
||||
draw.content(
|
||||
(name: id, anchor: name-anchor),
|
||||
anchor: if name-anchor in util.valid-anchors {name-anchor} else {"center"},
|
||||
padding: 0.5em,
|
||||
align(center)[*#name*]
|
||||
)
|
||||
}
|
||||
|
||||
if auto-ports {
|
||||
add-ports(
|
||||
id,
|
||||
tl, tr, br, bl,
|
||||
ports,
|
||||
ports-margins,
|
||||
debug: debug.ports
|
||||
)
|
||||
}
|
||||
})
|
||||
return ((
|
||||
id: id,
|
||||
draw: render.with(draw-shape),
|
||||
pre-process: pre-process,
|
||||
pos: pos,
|
||||
size: size,
|
||||
name: name,
|
||||
name-anchor: name-anchor,
|
||||
ports: ports,
|
||||
ports-margins: ports-margins,
|
||||
fill: fill,
|
||||
stroke: stroke,
|
||||
auto-ports: auto-ports,
|
||||
ports-y: ports-y,
|
||||
debug: debug
|
||||
),)
|
||||
}
|
||||
|
@ -34,12 +34,10 @@
|
||||
angle: if name-rotate {90deg} else {0deg},
|
||||
name
|
||||
)
|
||||
let id = elmt-id + "-port-" + port.at("id")
|
||||
|
||||
if debug {
|
||||
draw.circle(
|
||||
pos,
|
||||
name: id,
|
||||
radius: .1,
|
||||
stroke: none,
|
||||
fill: red
|
||||
@ -49,24 +47,24 @@
|
||||
draw.hide(draw.circle(
|
||||
pos,
|
||||
radius: 0,
|
||||
stroke: none,
|
||||
name: id
|
||||
stroke: none
|
||||
))
|
||||
}
|
||||
draw.anchor(port.id, pos)
|
||||
}
|
||||
|
||||
#let add-ports(
|
||||
elmt-id,
|
||||
tl, tr, br, bl,
|
||||
bounds,
|
||||
ports,
|
||||
ports-margins,
|
||||
debug: false
|
||||
) = {
|
||||
let sides = (
|
||||
"north": (tl, tr),
|
||||
"east": (tr, br),
|
||||
"south": (bl, br),
|
||||
"west": (tl, bl)
|
||||
"north": (bounds.tl, bounds.tr),
|
||||
"east": (bounds.tr, bounds.br),
|
||||
"south": (bounds.bl, bounds.br),
|
||||
"west": (bounds.tl, bounds.bl)
|
||||
)
|
||||
|
||||
if type(ports) != dictionary {
|
||||
|
Loading…
x
Reference in New Issue
Block a user