Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 59 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

# Custom Additions
**/resources/
scratch/
Expand All @@ -14,3 +13,62 @@ Cargo.lock

# These are backup files generated by rustfmt
**/*.rs.bk

# Created by https://www.toptal.com/developers/gitignore/api/vim,macos
# Edit at https://www.toptal.com/developers/gitignore?templates=vim,macos

### macOS ###
# General
.DS_Store
.AppleDouble
.LSOverride

# Icon must end with two \r
Icon


# Thumbnails
._*

# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.com.apple.timemachine.donotpresent

# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk

### macOS Patch ###
# iCloud generated files
*.icloud

### Vim ###
# Swap
[._]*.s[a-v][a-z]
!*.svg # comment out if you don't need vector files
[._]*.sw[a-p]
[._]s[a-rt-v][a-z]
[._]ss[a-gi-z]
[._]sw[a-p]

# Session
Session.vim
Sessionx.vim

# Temporary
.netrwhist
*~
# Auto-generated tag files
tags
# Persistent undo
[._]*.un~

# End of https://www.toptal.com/developers/gitignore/api/vim,macos
6 changes: 3 additions & 3 deletions gds21/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@ exclude = ["resources",]
layout21utils = {path = "../layout21utils", version="0.2.1"}
# External dependencies
byteorder = "1.3.4"
chrono = {version = "0.4", features = ["serde"]}
chrono = { version = "0.4.19", features = ["serde"] }
derive_builder = "0.9.0"
derive_more = "0.99.16"
num-derive = "0.3"
num-traits = "0.2"
serde = {version = "1.0", features = ["derive"]}
num-traits = "0.2.15"
serde = { version = "1.0.137", features = ["derive"] }
serde_derive = "1.0.88"
serde_json = "1.0"
tempfile = {version = "3", optional = true}
Expand Down
2 changes: 1 addition & 1 deletion gds21/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1114,7 +1114,7 @@ pub enum GdsError {
ctx: Vec<GdsContext>,
},
/// Boxed (External) Errors
Boxed(Box<dyn Error>),
Boxed(Box<dyn Error + Send + Sync>),
/// Other errors
Str(String),
}
Expand Down
3 changes: 2 additions & 1 deletion layout21converters/src/gds2proto.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use clap::Parser;
use layout21raw as raw;
use std::error::Error;

// => The doc-comment on `ProgramOptions` here is displayed by the `clap`-generated help docs =>
// => The doc-comment on `ProgramOptions` here is displayed by the `clap`-generated help docs =>

/// GDSII to VLSIR Protobuf Schema Converter
#[derive(Parser)]
Expand Down Expand Up @@ -66,6 +66,7 @@ mod tests {
use super::*;

#[test]
#[ignore = "requires layer config info"]
fn roundtrip_to_golden_file() {
// The golden file was created by running the program:
// $ cargo run -- \
Expand Down
1 change: 1 addition & 0 deletions layout21protos/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ workspace = "../"

[dependencies]
vlsir = { path = "vlsir/bindings/rust", version = "2.0.1" }

8 changes: 4 additions & 4 deletions layout21protos/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//!
//! # Layout21Protos
//!
//!
//! # Layout21Protos
//!
//! A wrapper around the [VLSIR](https://crates.io/crates/vlsir)
//!
//!

pub use vlsir::*;
8 changes: 5 additions & 3 deletions layout21raw/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,12 @@ lef21 = {path = "../lef21", version = "0.2.1", optional = true}
# Crates.io
enum_dispatch = "0.3.7"
num-integer = "0.1"
num-traits = "0.2"
serde = {version = "1.0", features = ["derive"]}
serde_derive = "1.0.88"
num-traits = "0.2.15"
serde = { version = "1.0.137", features = ["derive"] }
serde_derive = "1.0"
slotmap = {version = "1.0", features = ["serde"]}
derive_builder = "0.11"
anyhow = "1"

[features]
# Break out each import/export format as a feature
Expand Down
135 changes: 135 additions & 0 deletions layout21raw/src/align.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
use crate::{snap_to_grid, translate::Translate, BoundBox, BoundBoxTrait, Int, Point};
use serde::{Deserialize, Serialize};

#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum AlignMode {
Left,
Right,
Bottom,
Top,
CenterHorizontal,
CenterVertical,
ToTheRight,
ToTheLeft,
Beneath,
Above,
}

pub trait AlignRect: Translate + BoundBoxTrait {
fn align(&mut self, mode: AlignMode, obox: BoundBox, space: Int) -> &mut Self {
let sbox = self.bbox();

match mode {
AlignMode::Left => {
self.translate(Point::new(obox.p0.x - sbox.p0.x + space, 0));
}
AlignMode::Right => {
self.translate(Point::new(obox.p1.x - sbox.p1.x + space, 0));
}
AlignMode::Bottom => {
self.translate(Point::new(0, obox.p0.y - sbox.p0.y + space));
}
AlignMode::Top => {
self.translate(Point::new(0, obox.p1.y - sbox.p1.y + space));
}
AlignMode::ToTheRight => {
self.translate(Point::new(obox.p1.x - sbox.p0.x + space, 0));
}
AlignMode::ToTheLeft => {
self.translate(Point::new(obox.p0.x - sbox.p1.x - space, 0));
}
AlignMode::CenterHorizontal => {
self.translate(Point::new(
((obox.p0.x + obox.p1.x) - (sbox.p0.x + sbox.p1.x)) / 2 + space,
0,
));
}
AlignMode::CenterVertical => {
self.translate(Point::new(
0,
((obox.p0.y + obox.p1.y) - (sbox.p0.y + sbox.p1.y)) / 2 + space,
));
}
AlignMode::Beneath => {
self.translate(Point::new(0, obox.p0.y - sbox.p1.y - space));
}
AlignMode::Above => {
self.translate(Point::new(0, obox.p1.y - sbox.p0.y + space));
}
}

self
}

fn align_left(&mut self, other: BoundBox) {
self.align(AlignMode::Left, other, 0);
}

fn align_right(&mut self, other: BoundBox) {
self.align(AlignMode::Right, other, 0);
}

fn align_bottom(&mut self, other: BoundBox) {
self.align(AlignMode::Bottom, other, 0);
}

fn align_top(&mut self, other: BoundBox) {
self.align(AlignMode::Top, other, 0);
}

fn align_to_the_right_of(&mut self, other: BoundBox, space: Int) {
self.align(AlignMode::ToTheRight, other, space);
}

fn align_to_the_left_of(&mut self, other: BoundBox, space: Int) {
self.align(AlignMode::ToTheLeft, other, space);
}

fn align_centers_horizontally(&mut self, other: BoundBox) {
self.align(AlignMode::CenterHorizontal, other, 0);
}

fn align_centers_vertically(&mut self, other: BoundBox) {
self.align(AlignMode::CenterVertical, other, 0);
}

fn align_centers(&mut self, other: BoundBox) {
self.align_centers_vertically(other);
self.align_centers_vertically(other);
}

fn align_beneath(&mut self, other: BoundBox, space: Int) {
self.align(AlignMode::Beneath, other, space);
}

fn align_above(&mut self, other: BoundBox, space: Int) {
self.align(AlignMode::Above, other, space);
}

fn align_centers_horizontally_gridded(&mut self, other: BoundBox, grid: Int) {
// Align the center
self.align(AlignMode::CenterHorizontal, other, 0);

// Then snap to the nearest grid location
let bbox = self.bbox();
assert_eq!(bbox.width() % grid, 0);
let offset = snap_to_grid(bbox.p0.x, grid) - bbox.p0.x;
self.translate(Point::new(offset, 0));
}

fn align_centers_vertically_gridded(&mut self, other: BoundBox, grid: Int) {
// Align the center
self.align(AlignMode::CenterVertical, other, 0);

// Then snap to the nearest grid location
let bbox = self.bbox();
assert_eq!(bbox.height() % grid, 0);
let offset = snap_to_grid(bbox.p0.y, grid) - bbox.p0.y;
self.translate(Point::new(0, offset));
}

fn align_centers_gridded(&mut self, other: BoundBox, grid: Int) {
self.align_centers_horizontally_gridded(other, grid);
self.align_centers_vertically_gridded(other, grid);
}
}
28 changes: 28 additions & 0 deletions layout21raw/src/bbox.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,14 @@ impl BoundBox {
fn new(p0: Point, p1: Point) -> Self {
Self { p0, p1 }
}
#[inline]
pub fn width(&self) -> Int {
self.p1.x - self.p0.x
}
#[inline]
pub fn height(&self) -> Int {
self.p1.y - self.p0.y
}
/// Create a new [BoundBox] from a single [Point].
/// The resultant [BoundBox] comprises solely the point, having zero area.
pub fn from_point(pt: &Point) -> Self {
Expand Down Expand Up @@ -73,6 +81,19 @@ impl BoundBox {
pub fn center(&self) -> Point {
Point::new((self.p0.x + self.p1.x) / 2, (self.p0.y + self.p1.y) / 2)
}

#[inline]
pub fn into_rect(self) -> Rect {
Rect::from(self)
}
}

impl From<Rect> for BoundBox {
fn from(r: Rect) -> Self {
debug_assert!(r.p0.x <= r.p1.x);
debug_assert!(r.p0.y <= r.p1.y);
Self { p0: r.p0, p1: r.p1 }
}
}

///
Expand Down Expand Up @@ -115,6 +136,12 @@ impl BoundBoxTrait for BoundBox {
BoundBox::new(pmin, pmax)
}
fn union(&self, bbox: &BoundBox) -> BoundBox {
if bbox.is_empty() {
return *self;
}
if self.is_empty() {
return *bbox;
}
// Take the minimum and maximum of the two bounding boxes
BoundBox::new(
Point::new(self.p0.x.min(bbox.p0.x), self.p0.y.min(bbox.p0.y)),
Expand Down Expand Up @@ -146,6 +173,7 @@ impl BoundBoxTrait for Shape {
Shape::Rect(ref r) => BoundBox::from_points(&r.p0, &r.p1),
Shape::Polygon(ref p) => (&p.points).bbox(),
Shape::Path(ref p) => (&p.points).bbox(),
Shape::Point(ref p) => BoundBox::from_point(p),
}
}
}
Expand Down
Loading