libreda_db/layout/
traits.rs

1// Copyright (c) 2020-2021 Thomas Kramer.
2// SPDX-FileCopyrightText: 2022 Thomas Kramer
3//
4// SPDX-License-Identifier: AGPL-3.0-or-later
5
6//! Traits for layout data types.
7
8#![allow(unused_variables)]
9#![allow(missing_docs)] // Necessary because portrait does not generate docs.
10
11use crate::layout::types::{LayerInfo, UInt};
12use crate::prelude::PropertyValue;
13use crate::prelude::{Geometry, Rect};
14use crate::traits::{
15    HierarchyBase, HierarchyBaseMT, HierarchyEdit, HierarchyIds, IdType, IdTypeMT,
16};
17use iron_shapes::transform::SimpleTransform;
18use iron_shapes::CoordinateType;
19use num_traits::Num;
20use std::hash::Hash;
21
22/// Helper trait which constrains [`trait@LayoutBase`] for such that ID types
23/// are [`Send`] and [`Sync`] as commonly used for parallel algorithms.
24#[portrait::make]
25pub trait LayoutBaseMT:
26    LayoutBase<LayerId = Self::LayerIdMT, ShapeId = Self::ShapeIdMT> + HierarchyBaseMT
27{
28    /// Identifier for layers.
29    type LayerIdMT: IdTypeMT;
30    /// Identifier for shapes.
31    type ShapeIdMT: IdTypeMT;
32}
33
34impl<L> LayoutBaseMT for L
35where
36    L: LayoutBase + HierarchyBaseMT,
37    L::LayerId: Send + Sync,
38    L::ShapeId: Send + Sync,
39{
40    type LayerIdMT = L::LayerId;
41    type ShapeIdMT = L::ShapeId;
42}
43
44/// Define ID types used in layouts.
45#[portrait::make(import(crate::prelude::*))]
46pub trait LayoutIds: HierarchyIds {
47    /// Number type used for coordinates and distances.
48    type Coord: CoordinateType + std::fmt::Debug + std::fmt::Display + Hash + 'static + Send + Sync;
49    /// Number type for areas.
50    /// This is possibly another type then `Coord` for the following reasons:
51    /// * Distances and areas are semantically different.
52    /// * In practice `i32` is a good choice for coordinates. However, computing areas in `i32` might
53    /// easily lead to overflows. Hence a 64-bit integer type might be a better choice.
54    type Area: Num + Copy + PartialOrd + From<Self::Coord> + 'static + Send + Sync;
55    /// Layer identifier type.
56    type LayerId: IdType;
57    /// Shape identifier type.
58    type ShapeId: IdType;
59}
60
61/// Most basic trait of a layout.
62///
63/// This traits specifies methods for accessing the components of a layout.
64#[portrait::make(import(crate::prelude::*))]
65pub trait LayoutBase: LayoutIds + HierarchyBase {
66    /// Get the distance unit used in this layout in 'pixels per micron'.
67    fn dbu(&self) -> Self::Coord;
68
69    /// Iterate over all defined layers.
70    fn each_layer(&self) -> Box<dyn Iterator<Item = Self::LayerId> + '_>;
71
72    /// Get the `LayerInfo` data structure for this layer.
73    fn layer_info(&self, layer: &Self::LayerId) -> LayerInfo<Self::NameType>;
74
75    /// Find layer index by the (index, data type) tuple.
76    fn find_layer(&self, index: UInt, datatype: UInt) -> Option<Self::LayerId>;
77
78    /// Find layer index by the name.
79    fn layer_by_name(&self, name: &str) -> Option<Self::LayerId>;
80
81    /// Compute the bounding box of the shapes on one layer.
82    /// The bounding box also includes all child cell instances.
83    fn bounding_box_per_layer(
84        &self,
85        cell: &Self::CellId,
86        layer: &Self::LayerId,
87    ) -> Option<Rect<Self::Coord>>;
88
89    /// Compute the bounding box of the cell over all layers.
90    /// The bounding box is not defined if the cell is empty. In this
91    /// case return `None`.
92    fn bounding_box(&self, cell: &Self::CellId) -> Option<Rect<Self::Coord>> {
93        self.each_layer()
94            .map(|layer| self.bounding_box_per_layer(cell, &layer))
95            .fold(None, |a, b| match (a, b) {
96                (None, None) => None,
97                (Some(a), None) | (None, Some(a)) => Some(a),
98                (Some(a), Some(b)) => Some(a.add_rect(&b)),
99            })
100    }
101
102    /// Iterate over the IDs of all shapes in the cell on a specific layer.
103    fn each_shape_id(
104        &self,
105        cell: &Self::CellId,
106        layer: &Self::LayerId,
107    ) -> Box<dyn Iterator<Item = Self::ShapeId> + '_>;
108
109    /// Call a function for each shape on this layer.
110    fn for_each_shape<F>(&self, cell: &Self::CellId, layer: &Self::LayerId, f: F)
111    where
112        F: FnMut(&Self::ShapeId, &Geometry<Self::Coord>);
113
114    /// Access a shape by its ID.
115    fn with_shape<F, R>(&self, shape_id: &Self::ShapeId, f: F) -> R
116    where
117        F: FnMut(&Self::LayerId, &Geometry<Self::Coord>) -> R;
118
119    /// Get a clone of the shape geometry.
120    fn shape_geometry(&self, shape_id: &Self::ShapeId) -> Geometry<Self::Coord> {
121        self.with_shape(shape_id, |_, geo| geo.clone())
122    }
123
124    /// Get the layer of a shape.
125    fn shape_layer(&self, shape_id: &Self::ShapeId) -> Self::LayerId {
126        self.with_shape(shape_id, |layer, _| layer.clone())
127    }
128
129    /// Get the parent cell and the layer of a shape as a (cell, layer) tuple.
130    fn parent_of_shape(&self, shape_id: &Self::ShapeId) -> (Self::CellId, Self::LayerId);
131
132    /// Call a function `f` for each shape of this cell and its sub cells.
133    /// Along to the geometric shape `f` also gets a transformation as argument.
134    /// The transformation describes the actual position of the geometric shape relative to the `cell`.
135    fn for_each_shape_recursive<F>(&self, cell: &Self::CellId, layer: &Self::LayerId, mut f: F)
136    where
137        F: FnMut(SimpleTransform<Self::Coord>, &Self::ShapeId, &Geometry<Self::Coord>),
138    {
139        // This recursive iteration through the cells is implemented iteratively.
140        // A plain recursive implementation is more difficult to handle due to the type system.
141
142        // Stack for resolved recursion.
143        let mut stack = Vec::new();
144        stack.push((cell.clone(), SimpleTransform::identity()));
145
146        while let Some((cell, tf)) = stack.pop() {
147            // Push child instances.
148            self.for_each_cell_instance(&cell, |inst| {
149                let template = self.template_cell(&inst);
150                let transform = self.get_transform(&inst);
151                let tf2 = transform.then(&tf);
152                stack.push((template, tf2));
153            });
154
155            // Process shapes of this cell.
156            self.for_each_shape(&cell, layer, |id, g| f(tf, id, g));
157        }
158    }
159
160    /// Get the geometric transform that describes the location of a cell instance relative to its parent.
161    fn get_transform(&self, cell_inst: &Self::CellInstId) -> SimpleTransform<Self::Coord>;
162
163    /// Get a property of a shape.
164    fn get_shape_property(
165        &self,
166        shape: &Self::ShapeId,
167        key: &Self::NameType,
168    ) -> Option<PropertyValue> {
169        None
170    }
171}
172
173/// Access shapes and instances in a layout based on their locations.
174#[portrait::make]
175pub trait RegionSearch: LayoutBase {
176    /// Iterate over the IDs of all shapes (on all layers) whose bounding-box overlaps with the `search_region`.
177    fn each_shape_in_region(
178        &self,
179        cell: &Self::CellId,
180        search_region: &Rect<Self::Coord>,
181    ) -> Box<dyn Iterator<Item = Self::ShapeId> + '_> {
182        let cell = cell.clone(); // Get an owned ID.
183        let search_region = *search_region; // Get an owned rectangle.
184        Box::new(self.each_layer().flat_map(move |layer_id| {
185            self.each_shape_in_region_per_layer(&cell, &layer_id, &search_region)
186        }))
187    }
188
189    /// Iterate over the IDs of all shapes (on a specific layer) whose bounding-box overlaps with the `search_region`.
190    fn each_shape_in_region_per_layer(
191        &self,
192        cell: &Self::CellId,
193        layer_id: &Self::LayerId,
194        search_region: &Rect<Self::Coord>,
195    ) -> Box<dyn Iterator<Item = Self::ShapeId> + '_>;
196
197    /// Iterate over the IDs of all instances within the `cell` whose bounding-box overlaps with the `search_region`.
198    fn each_cell_instance_in_region(
199        &self,
200        cell: &Self::CellId,
201        search_region: &Rect<Self::Coord>,
202    ) -> Box<dyn Iterator<Item = Self::CellInstId> + '_>;
203}
204
205/// Trait for layouts that support editing.
206#[portrait::make(import(crate::prelude::*))]
207pub trait LayoutEdit: LayoutBase + HierarchyEdit {
208    /// Set the distance unit used in this layout in 'pixels per micron'.
209    fn set_dbu(&mut self, dbu: Self::Coord) {} // TODO: Remove default implementation.
210
211    /// Create a new layer.
212    /// Use `set_layer_name()` to define a name.
213    fn create_layer(&mut self, index: UInt, datatype: UInt) -> Self::LayerId;
214
215    /// Create a new layer with a specific ID. This is used to clone layer-stacks between layouts while preserving their IDs.
216    /// Returns an `Err` when the ID already exists.
217    fn create_layer_with_id(
218        &mut self,
219        layer_id: Self::LayerId,
220        index: UInt,
221        datatype: UInt,
222    ) -> Result<(), ()>;
223
224    /// Set the name of a layer or clear the layer name when passing `None`.
225    /// This method should not change the ID of the layer.
226    /// Returns the previous name of the layer.
227    fn set_layer_name(
228        &mut self,
229        layer: &Self::LayerId,
230        name: Option<Self::NameType>,
231    ) -> Option<Self::NameType>;
232
233    /// Insert a geometric shape into the parent cell.
234    fn insert_shape(
235        &mut self,
236        parent_cell: &Self::CellId,
237        layer: &Self::LayerId,
238        geometry: Geometry<Self::Coord>,
239    ) -> Self::ShapeId;
240
241    /// Remove shape from the parent cell.
242    fn remove_shape(&mut self, shape_id: &Self::ShapeId) -> Option<Geometry<Self::Coord>>;
243
244    /// Replace the geometry of a shape.
245    fn replace_shape(
246        &mut self,
247        shape_id: &Self::ShapeId,
248        geometry: Geometry<Self::Coord>,
249    ) -> Geometry<Self::Coord>;
250
251    /// Set the geometric transform that describes the location of a cell instance relative to its parent.
252    fn set_transform(&mut self, cell_inst: &Self::CellInstId, tf: SimpleTransform<Self::Coord>);
253
254    /// Set a property of a shape.
255    fn set_shape_property(
256        &mut self,
257        shape: &Self::ShapeId,
258        key: Self::NameType,
259        value: PropertyValue,
260    ) {
261    }
262}