use std::collections::HashMap;
use crate::db;
use db::{ToPolygon, WindingNumber};
use libreda_db::prelude::Geometry;
use log;
pub fn find_pin_geometries_from_text_labels<L: db::LayoutBase<Coord=db::Coord>>(
layout: &L,
cell: &L::CellId,
pin_shape_layer: &L::LayerId,
label_layer: &L::LayerId,
) -> HashMap<String, Vec<db::Geometry<L::Coord>>> {
let shape_ids = find_pin_shapes_from_text_labels(layout, cell, pin_shape_layer, label_layer);
shape_ids.into_iter()
.map(|(name, ids)| {
let geometries = ids.into_iter()
.map(|id| layout.with_shape(&id, |_layer, geo| geo.clone()))
.collect();
(name, geometries)
})
.collect()
}
pub fn assign_pin_shapes_from_text_labels<L: db::L2NEdit<Coord=db::Coord>>(
layout: &mut L,
cell: &L::CellId,
pin_shape_layer: &L::LayerId,
label_layer: &L::LayerId,
) {
let pin_shapes = find_pin_shapes_from_text_labels(layout, cell, pin_shape_layer, label_layer);
for (pin_name, shapes) in pin_shapes {
if let Some(pin) = layout.pin_by_name(cell, &pin_name) {
for shape in &shapes {
let previous_pin = layout.set_pin_of_shape(shape, Some(pin.clone()));
if let Some(previous_pin) = previous_pin {
if previous_pin != pin {
log::debug!("Overwriting pin of shape: '{}' -> '{}'",
layout.pin_name(&previous_pin), layout.pin_name(&pin));
}
}
}
} else {
let cell_name = layout.cell_name(cell);
log::warn!("No such pin in netlist view of cell '{}': '{}'", cell_name, &pin_name);
}
}
}
pub fn find_pin_shapes_from_text_labels<L: db::LayoutBase<Coord=db::Coord>>(
layout: &L,
cell: &L::CellId,
pin_shape_layer: &L::LayerId,
label_layer: &L::LayerId,
) -> HashMap<String, Vec<L::ShapeId>> {
let mut labels = Vec::new();
layout.for_each_shape(cell, label_layer, |_id, geometry| {
match geometry {
Geometry::Text(t) => labels.push(t.clone()),
_ => { }
}
});
let result = labels.into_iter()
.filter_map(|label| {
let mut touching_shapes = Vec::new();
layout.for_each_shape(cell, pin_shape_layer, |shape_id, geometry| {
let touches = geometry.to_polygon()
.contains_point(label.location());
if touches {
touching_shapes.push(shape_id.clone())
}
});
if touching_shapes.is_empty() {
None
} else {
Some((label.text().clone(), touching_shapes))
}
})
.collect();
result
}