substrate/layout/
mod.rs

1//! Substrate's layout generator framework.
2
3use std::fmt::Debug;
4use std::ops::{Deref, DerefMut};
5use std::{marker::PhantomData, sync::Arc, thread};
6
7use arcstr::ArcStr;
8use cache::{CacheHandle, error::TryInnerError, mem::TypeCache};
9use geometry::prelude::Rect;
10use geometry::transform::{TransformRef, TranslateRef};
11use geometry::{
12    prelude::{Bbox, Point},
13    transform::{Transform, TransformMut, Transformation, Translate, TranslateMut},
14    union::BoundingUnion,
15};
16use layir::LayerBbox;
17use once_cell::sync::OnceCell;
18use schema::Schema;
19
20use crate::context::Context;
21use crate::error::Error;
22use crate::error::Result;
23use crate::types::layout::LayoutBundle;
24use crate::types::{HasBundleKind, IoKind};
25
26use self::element::{CellId, Element, RawCell, RawInstance};
27
28pub mod conv;
29pub mod element;
30pub mod error;
31pub mod schema;
32#[cfg(test)]
33mod tests;
34pub mod tiling;
35pub mod tracks;
36
37use crate::block::Block;
38
39/// Data exported from a generated layout.
40///
41/// Contained data is transformed with the containing instance
42/// according to its [`TransformRef`] implementation.
43pub trait LayoutData: TransformRef + Send + Sync {}
44impl<T: TransformRef + Send + Sync> LayoutData for T {}
45
46/// The layer type associated with a layout cell.
47pub type CellLayer<T> = <<T as Layout>::Schema as Schema>::Layer;
48/// The bundle associated with a layout cell.
49pub type CellBundle<T> = <T as Layout>::Bundle;
50
51/// A block that can be laid out in a given layout [`Schema`].
52pub trait Layout: Block {
53    /// The schema this layout is associated with.
54    type Schema: Schema;
55    /// The bundle representing this block's layout IO.
56    type Bundle: LayoutBundle<Self::Schema> + HasBundleKind<BundleKind = IoKind<Self>>;
57    /// Extra data to be shared with other blocks that instantiate this block's layout.
58    type Data: LayoutData;
59    /// Generates the block's layout.
60    fn layout(&self, cell: &mut CellBuilder<Self::Schema>) -> Result<(Self::Bundle, Self::Data)>;
61}
62
63impl<T: Layout> Layout for Arc<T> {
64    type Schema = T::Schema;
65    type Bundle = T::Bundle;
66    type Data = T::Data;
67    fn layout(&self, cell: &mut CellBuilder<Self::Schema>) -> Result<(Self::Bundle, Self::Data)> {
68        T::layout(self.as_ref(), cell)
69    }
70}
71
72/// Layout-specific context data.
73///
74/// Stores generated layout cells as well as state used for assigning unique cell IDs.
75#[derive(Debug, Default)]
76pub struct LayoutContext {
77    next_id: CellId,
78    pub(crate) cell_cache: TypeCache,
79}
80
81impl LayoutContext {
82    #[allow(dead_code)]
83    pub(crate) fn new() -> Self {
84        Self::default()
85    }
86
87    pub(crate) fn get_id(&mut self) -> CellId {
88        self.next_id.increment();
89        self.next_id
90    }
91}
92
93/// A generic layout cell.
94///
95/// Stores its underlying block, extra data created during generation, as well as a raw cell
96/// containing its primitive elements.
97#[allow(dead_code)]
98pub struct Cell<T: Layout> {
99    /// Block whose layout this cell represents.
100    block: Arc<T>,
101    /// Extra data created during layout generation.
102    data: T::Data,
103    pub(crate) io: T::Bundle,
104    pub(crate) raw: Arc<RawCell<<T::Schema as Schema>::Layer>>,
105}
106
107impl<T: Layout> Cell<T> {
108    pub(crate) fn new(
109        block: Arc<T>,
110        data: T::Data,
111        io: T::Bundle,
112        raw: Arc<RawCell<CellLayer<T>>>,
113    ) -> Self {
114        Self {
115            block,
116            data,
117            io,
118            raw,
119        }
120    }
121
122    /// Returns the block whose layout this cell represents.
123    pub fn block(&self) -> &T {
124        &self.block
125    }
126
127    /// Returns extra data created by the cell's schematic generator.
128    pub fn data(&self) -> &T::Data {
129        &self.data
130    }
131
132    /// Returns the geometry of the cell's IO.
133    pub fn io(&self) -> &T::Bundle {
134        &self.io
135    }
136
137    /// The raw layout geometry contained by this cell.
138    pub fn raw(&self) -> &Arc<RawCell<CellLayer<T>>> {
139        &self.raw
140    }
141}
142
143impl<T: Layout> Bbox for Cell<T> {
144    fn bbox(&self) -> Option<geometry::rect::Rect> {
145        self.raw.bbox()
146    }
147}
148
149impl<T: Layout> LayerBbox<<T::Schema as Schema>::Layer> for Cell<T>
150where
151    <T::Schema as Schema>::Layer: PartialEq,
152{
153    fn layer_bbox(&self, layer: &<T::Schema as Schema>::Layer) -> Option<Rect> {
154        self.raw.layer_bbox(layer)
155    }
156}
157
158/// A handle to a schematic cell that is being generated.
159pub struct CellHandle<T: Layout> {
160    pub(crate) block: Arc<T>,
161    pub(crate) cell: CacheHandle<Result<Cell<T>>>,
162}
163
164impl<T: Layout> Clone for CellHandle<T> {
165    fn clone(&self) -> Self {
166        Self {
167            block: self.block.clone(),
168            cell: self.cell.clone(),
169        }
170    }
171}
172
173impl<T: Layout> CellHandle<T> {
174    /// Tries to access the underlying [`Cell`].
175    ///
176    /// Blocks until cell generation completes and returns an error if one was thrown during generation.
177    pub fn try_cell(&self) -> Result<&Cell<T>> {
178        self.cell.try_inner().map_err(|e| match e {
179            TryInnerError::CacheError(e) => Error::CacheError(e.clone()),
180            TryInnerError::GeneratorError(e) => e.clone(),
181        })
182    }
183
184    /// Returns the underlying [`Cell`].
185    ///
186    /// Blocks until cell generation completes.
187    ///
188    /// # Panics
189    ///
190    /// Panics if generation fails.
191    pub fn cell(&self) -> &Cell<T> {
192        self.try_cell().expect("cell generation failed")
193    }
194}
195
196/// A transformed view of a cell, usually created by accessing the cell of an instance.
197pub struct TransformedCell<T: Layout> {
198    /// Block whose layout this cell represents.
199    block: Arc<T>,
200    /// Extra data created during layout generation.
201    ///
202    /// This is the result of applying `trans` to the original cell's data.
203    /// If `trans` changes, this field must be updated.
204    data: T::Data,
205    /// The geometry of the cell's IO.
206    ///
207    /// This is the result of applying `trans` to the original cell's IO.
208    /// If `trans` changes, this field must be updated.
209    io: T::Bundle,
210    /// The underlying raw cell.
211    ///
212    /// This field should NOT be modified if `trans` changes.
213    raw: Arc<RawCell<CellLayer<T>>>,
214    /// The transformation applied to all geometry stored in the raw cell (`raw`).
215    trans: Transformation,
216}
217
218impl<T: Layout> TransformedCell<T> {
219    /// Creates a new transformed cell from the given cell and transformation.
220    pub fn new(cell: &Cell<T>, trans: Transformation) -> Self {
221        Self {
222            block: cell.block.clone(),
223            data: cell.data.transform_ref(trans),
224            io: cell.io.transform_ref(trans),
225            raw: cell.raw.clone(),
226            trans,
227        }
228    }
229
230    /// Returns the block whose layout this cell represents.
231    pub fn block(&self) -> &T {
232        &self.block
233    }
234
235    /// Returns extra data created by the cell's schematic generator.
236    pub fn data(&self) -> &T::Data {
237        &self.data
238    }
239}
240
241impl<T: Layout> TranslateRef for TransformedCell<T> {
242    fn translate_ref(&self, p: Point) -> Self {
243        Self {
244            block: self.block.clone(),
245            data: self.data.translate_ref(p),
246            io: self.io.translate_ref(p),
247            raw: self.raw.clone(),
248            trans: self.trans.translate_ref(p.x, p.y),
249        }
250    }
251}
252
253impl<T: Layout> TransformRef for TransformedCell<T> {
254    fn transform_ref(&self, trans: Transformation) -> Self {
255        Self {
256            block: self.block.clone(),
257            data: self.data.transform_ref(trans),
258            io: self.io.transform_ref(trans),
259            raw: self.raw.clone(),
260            trans: Transformation::cascade(trans, self.trans),
261        }
262    }
263}
264
265impl<T: Layout> Bbox for TransformedCell<T> {
266    fn bbox(&self) -> Option<geometry::rect::Rect> {
267        self.raw.bbox().transform(self.trans)
268    }
269}
270
271impl<T: Layout> LayerBbox<<T::Schema as Schema>::Layer> for TransformedCell<T>
272where
273    CellLayer<T>: PartialEq,
274{
275    fn layer_bbox(&self, layer: &<T::Schema as Schema>::Layer) -> Option<Rect> {
276        self.raw.layer_bbox(layer).transform(self.trans)
277    }
278}
279
280/// A generic layout instance.
281///
282/// Stores a pointer to its underlying cell and its instantiated transformation.
283#[allow(dead_code)]
284pub struct Instance<T: Layout> {
285    cell: CellHandle<T>,
286    trans: Transformation,
287}
288
289impl<T: Layout> Clone for Instance<T> {
290    fn clone(&self) -> Self {
291        Self {
292            cell: self.cell.clone(),
293            ..*self
294        }
295    }
296}
297
298impl<T: Layout> Instance<T> {
299    pub(crate) fn new(cell: CellHandle<T>) -> Self {
300        Instance {
301            cell,
302            trans: Transformation::default(),
303        }
304    }
305
306    /// Tries to access a transformed view of the underlying [`Cell`], blocking on generation.
307    ///
308    /// Blocks until cell generation completes.
309    ///
310    /// The returned object provides coordinates in the parent cell's coordinate system.
311    /// If you want coordinates in the child cell's coordinate system,
312    /// consider using [`Instance::try_raw_cell`] instead.
313    ///
314    /// Returns an error if one was thrown during generation.
315    // TODO: this recomputes transformations every time it is called.
316    pub fn try_cell(&self) -> Result<TransformedCell<T>> {
317        self.cell
318            .try_cell()
319            .map(|cell| TransformedCell::new(cell, self.trans))
320    }
321
322    /// Returns a transformed view of the underlying [`Cell`].
323    ///
324    /// Blocks until cell generation completes.
325    ///
326    /// The returned object provides coordinates in the parent cell's coordinate system.
327    /// If you want coordinates in the child cell's coordinate system,
328    /// consider using [`Instance::raw_cell`] instead.
329    ///
330    /// # Panics
331    ///
332    /// Panics if an error was thrown during generation.
333    pub fn cell(&self) -> TransformedCell<T> {
334        self.try_cell().expect("cell generation failed")
335    }
336
337    /// Tries to access a transformed view of the underlying [`Cell`], blocking on generation.
338    ///
339    /// Blocks until cell generation completes.
340    ///
341    /// The returned cell does not store any information related
342    /// to this instance's transformation.
343    /// Consider using [`Instance::try_cell`] instead.
344    ///
345    /// Returns an error if one was thrown during generation.
346    pub fn try_raw_cell(&self) -> Result<&Cell<T>> {
347        self.cell.try_cell()
348    }
349
350    /// Returns a transformed view of the underlying [`Cell`].
351    ///
352    /// Blocks until cell generation completes.
353    ///
354    /// The returned cell does not store any information related
355    /// to this instance's transformation.
356    /// Consider using [`Instance::cell`] instead.
357    ///
358    /// # Panics
359    ///
360    /// Panics if an error was thrown during generation.
361    pub fn raw_cell(&self) -> &Cell<T> {
362        self.try_raw_cell().expect("cell generation failed")
363    }
364
365    /// Tries to access extra data created by the cell's schematic generator.
366    ///
367    /// Blocks until cell generation completes.
368    ///
369    /// Returns an error if one was thrown during generation.
370    pub fn try_data(&self) -> Result<T::Data> {
371        Ok(self.try_cell()?.data)
372    }
373
374    /// Tries to access extra data created by the cell's schematic generator.
375    ///
376    /// Blocks until cell generation completes.
377    ///
378    /// # Panics
379    ///
380    /// Panics if an error was thrown during generation.
381    pub fn data(&self) -> T::Data {
382        self.cell().data
383    }
384
385    /// Returns the underlying block used to create this instance's cell.
386    pub fn block(&self) -> &T {
387        self.cell.block.as_ref()
388    }
389
390    /// Returns a transformed view of the underlying [`Cell`]'s IO.
391    ///
392    /// Blocks until cell generation completes.
393    ///
394    /// Returns an error if one was thrown during generation.
395    pub fn try_io(&self) -> Result<T::Bundle> {
396        Ok(self.try_cell()?.io)
397    }
398
399    /// Returns a transformed view of the underlying [`Cell`]'s IO.
400    ///
401    /// Blocks until cell generation completes.
402    ///
403    /// # Panics
404    ///
405    /// Panics if an error was thrown during generation.
406    pub fn io(&self) -> T::Bundle {
407        self.cell().io
408    }
409
410    /// The transformation of this instance.
411    pub fn transformation(&self) -> &Transformation {
412        &self.trans
413    }
414
415    /// A mutable reference to a transformation of this instance.
416    pub fn transformation_mut(&mut self) -> &mut Transformation {
417        &mut self.trans
418    }
419}
420
421impl<T: Layout> Bbox for Instance<T> {
422    fn bbox(&self) -> Option<geometry::rect::Rect> {
423        self.cell().bbox()
424    }
425}
426
427impl<T: Layout> LayerBbox<<T::Schema as Schema>::Layer> for Instance<T>
428where
429    CellLayer<T>: PartialEq,
430{
431    fn layer_bbox(&self, layer: &<T::Schema as Schema>::Layer) -> Option<Rect> {
432        self.cell().layer_bbox(layer)
433    }
434}
435
436impl<T: Layout> TranslateMut for Instance<T> {
437    fn translate_mut(&mut self, p: Point) {
438        self.transform_mut(Transformation::from_offset(p))
439    }
440}
441
442impl<T: Layout> TransformMut for Instance<T> {
443    fn transform_mut(&mut self, trans: Transformation) {
444        self.trans = Transformation::cascade(trans, self.trans);
445    }
446}
447
448impl<T: Layout> TranslateRef for Instance<T> {
449    fn translate_ref(&self, p: Point) -> Self {
450        self.clone().translate(p)
451    }
452}
453
454impl<T: Layout> TransformRef for Instance<T> {
455    fn transform_ref(&self, trans: Transformation) -> Self {
456        self.clone().transform(trans)
457    }
458}
459
460impl<I: Layout> Draw<I::Schema> for Instance<I> {
461    fn draw(self, recv: &mut DrawReceiver<I::Schema>) -> Result<()> {
462        recv.draw_instance(self);
463        Ok(())
464    }
465}
466
467impl<I: Layout> Draw<I::Schema> for &Instance<I> {
468    fn draw(self, recv: &mut DrawReceiver<I::Schema>) -> Result<()> {
469        recv.draw_instance((*self).clone());
470        Ok(())
471    }
472}
473
474/// A layout cell builder.
475///
476/// Constructed once for each invocation of [`Layout::layout`].
477pub struct CellBuilder<S: Schema> {
478    container: Container<S>,
479    /// The current global context.
480    pub ctx: Context,
481}
482
483impl<S: Schema> CellBuilder<S> {
484    /// Creates a new layout builder.
485    pub fn new(ctx: Context) -> Self {
486        Self {
487            container: Container::new(),
488            ctx,
489        }
490    }
491
492    pub(crate) fn finish(self, id: CellId, name: ArcStr) -> RawCell<S::Layer> {
493        let mut cell = RawCell::new(id, name);
494
495        self.container.finish(&mut cell.elements);
496
497        cell
498    }
499
500    /// Generate an instance of `block`.
501    ///
502    /// Returns immediately, allowing generation to complete in the background. Attempting to
503    /// access the generated instance's cell will block until generation is complete.
504    pub fn generate<I: Layout>(&mut self, block: I) -> Instance<I> {
505        let cell = self.ctx.generate_layout(block);
506        Instance::new(cell)
507    }
508
509    /// Generate an instance of `block`.
510    ///
511    /// Blocks on generation, returning only once the instance's cell is populated. Useful for
512    /// handling errors thrown by the generation of a cell immediately.
513    pub fn generate_blocking<I: Layout>(&mut self, block: I) -> Result<Instance<I>> {
514        let cell = self.ctx.generate_layout(block);
515        cell.try_cell()?;
516        Ok(Instance::new(cell))
517    }
518
519    /// Draw layout object `obj`.
520    ///
521    /// For instances, a new thread is spawned to add the instance once the underlying cell has
522    /// been generated. If generation fails, the spawned thread may panic after this function has
523    /// been called.
524    ///
525    /// For error recovery, instance generation results should be checked using [`Instance::try_cell`]
526    /// before calling `draw`.
527    ///
528    /// # Panics
529    ///
530    /// May cause a panic if generation of an underlying instance fails.
531    pub fn draw(&mut self, obj: impl Draw<S>) -> Result<()> {
532        Container::draw(&mut self.container, obj)
533    }
534
535    /// Gets the global context.
536    pub fn ctx(&self) -> &Context {
537        &self.ctx
538    }
539}
540
541impl<S: Schema> Bbox for CellBuilder<S> {
542    fn bbox(&self) -> Option<geometry::rect::Rect> {
543        self.container.bbox()
544    }
545}
546
547impl<S: Schema> LayerBbox<S::Layer> for CellBuilder<S> {
548    fn layer_bbox(&self, layer: &S::Layer) -> Option<Rect> {
549        self.container.layer_bbox(layer)
550    }
551}
552
553type RawInstanceHandle<S> = Arc<OnceCell<Option<RawInstance<<S as Schema>::Layer>>>>;
554
555/// A receiver for drawing layout objects.
556///
557/// Implements the primitive functions that layout objects need to implement [`Draw`].
558pub struct DrawReceiver<S: Schema> {
559    phantom: PhantomData<S>,
560    containers: Vec<Container<S>>,
561    instances: Vec<RawInstanceHandle<S>>,
562    elements: Vec<Element<S::Layer>>,
563    trans: Transformation,
564}
565
566impl<S: Schema> Debug for DrawReceiver<S>
567where
568    S::Layer: Debug,
569{
570    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
571        f.debug_struct("DrawReceiver")
572            .field("phantom", &self.phantom)
573            .field("containers", &self.containers)
574            .field("instances", &self.instances)
575            .field("elements", &self.elements)
576            .field("trans", &self.trans)
577            .finish()
578    }
579}
580
581impl<S: Schema> Clone for DrawReceiver<S>
582where
583    S::Layer: Clone,
584{
585    fn clone(&self) -> Self {
586        Self {
587            phantom: PhantomData,
588            containers: self.containers.clone(),
589            instances: self.instances.clone(),
590            elements: self.elements.clone(),
591            trans: self.trans,
592        }
593    }
594}
595
596impl<S: Schema> DrawReceiver<S> {
597    pub(crate) fn new() -> Self {
598        Self {
599            phantom: PhantomData,
600            containers: Vec::new(),
601            instances: Vec::new(),
602            elements: Vec::new(),
603            trans: Transformation::default(),
604        }
605    }
606
607    /// Blocks on instances and returns pointers to them.
608    fn get_instances(&self) -> Vec<&RawInstance<S::Layer>> {
609        self.instances
610            .iter()
611            .map(|instance| instance.wait().as_ref().unwrap())
612            .collect()
613    }
614
615    pub(crate) fn finish(self, elements: &mut Vec<Element<S::Layer>>) {
616        for instance in self
617            .instances
618            .into_iter()
619            .map(|instance| instance.wait().clone().unwrap())
620        {
621            elements.push(instance.transform(self.trans).into());
622        }
623
624        elements.extend(
625            self.elements
626                .into_iter()
627                .map(|element| element.transform(self.trans)),
628        );
629
630        for mut container in self.containers {
631            container.transform_mut(self.trans);
632            container.finish(elements);
633        }
634    }
635
636    pub(crate) fn draw_container(&mut self, container: Container<S>) {
637        self.containers.push(container);
638    }
639
640    pub(crate) fn draw_element(&mut self, element: impl Into<Element<S::Layer>>) {
641        let element = element.into();
642        self.elements.push(element);
643    }
644}
645
646impl<S: Schema> DrawReceiver<S> {
647    pub(crate) fn draw_instance<I: Layout<Schema = S>>(&mut self, inst: Instance<I>) {
648        let instance = Arc::new(OnceCell::new());
649        self.instances.push(instance.clone());
650
651        let cell = inst.cell.clone();
652        thread::spawn(move || {
653            instance.set(cell.try_cell().ok().map(|cell| RawInstance {
654                cell: cell.raw.clone(),
655                trans: inst.trans,
656            }))
657        });
658    }
659
660    /// Draw layout object `obj`.
661    ///
662    /// For instances, a new thread is spawned to add the instance once the underlying cell has
663    /// been generated. If generation fails, the spawned thread may panic after this function has
664    /// been called.
665    ///
666    /// For error recovery, instance generation results should be checked using [`Instance::try_cell`]
667    /// before calling `draw`.
668    ///
669    /// # Panics
670    ///
671    /// May cause a panic if generation of an underlying instance fails.
672    pub fn draw(&mut self, obj: impl Draw<S>) -> Result<()> {
673        obj.draw(self)
674    }
675}
676
677impl<S: Schema> Draw<S> for DrawReceiver<S> {
678    fn draw(self, recv: &mut DrawReceiver<S>) -> Result<()> {
679        recv.containers.extend(self.containers);
680        recv.instances.extend(self.instances);
681        recv.elements.extend(self.elements);
682        Ok(())
683    }
684}
685
686impl<S: Schema> Bbox for DrawReceiver<S> {
687    fn bbox(&self) -> Option<geometry::rect::Rect> {
688        self.get_instances()
689            .bbox()
690            .bounding_union(&self.elements.bbox())
691            .bounding_union(&self.containers.bbox())
692    }
693}
694
695impl<S: Schema> LayerBbox<S::Layer> for DrawReceiver<S> {
696    fn layer_bbox(&self, layer: &S::Layer) -> Option<Rect> {
697        self.get_instances()
698            .layer_bbox(layer)
699            .bounding_union(&self.elements.layer_bbox(layer))
700    }
701}
702
703/// An object that can be drawn in a [`CellBuilder`].
704pub trait Draw<S: Schema>: DrawBoxed<S> {
705    /// Draws `self` inside `recv`.
706    fn draw(self, recv: &mut DrawReceiver<S>) -> Result<()>;
707}
708
709/// An object where `Box<Self>` can be drawn.
710pub trait DrawBoxed<S: Schema> {
711    /// Draws `self` inside `recv`.
712    fn draw_boxed(self: Box<Self>, recv: &mut DrawReceiver<S>) -> Result<()>;
713}
714
715impl<S: Schema, T: Draw<S>> DrawBoxed<S> for T {
716    fn draw_boxed(self: Box<Self>, recv: &mut DrawReceiver<S>) -> Result<()> {
717        (*self).draw(recv)
718    }
719}
720
721/// Draws an object into a new [`Container`].
722// TODO: Decide if this trait should be made public.
723#[allow(dead_code)]
724pub(crate) trait DrawContainer<S: Schema>: Draw<S> {
725    /// Draws `self` into a new [`Container`].
726    fn draw_container(self) -> Result<Container<S>>;
727}
728
729impl<S: Schema, T: Draw<S>> DrawContainer<S> for T {
730    fn draw_container(self) -> Result<Container<S>> {
731        let mut container = Container::new();
732        Container::draw(&mut container, self)?;
733        Ok(container)
734    }
735}
736
737impl<S: Schema, T: Draw<S> + ?Sized> Draw<S> for Box<T> {
738    fn draw(self, recv: &mut DrawReceiver<S>) -> Result<()> {
739        self.draw_boxed(recv)
740    }
741}
742
743/// A container for drawn objects.
744pub struct Container<S: Schema> {
745    recvs: Vec<DrawReceiver<S>>,
746    trans: Transformation,
747}
748
749impl<S: Schema> Clone for Container<S>
750where
751    S::Layer: Clone,
752{
753    fn clone(&self) -> Self {
754        Self {
755            recvs: self.recvs.clone(),
756            trans: self.trans,
757        }
758    }
759}
760
761impl<S: Schema> Debug for Container<S>
762where
763    S::Layer: Debug,
764{
765    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
766        f.debug_struct("Container")
767            .field("recvs", &self.recvs)
768            .field("trans", &self.trans)
769            .finish()
770    }
771}
772
773impl<S: Schema> Default for Container<S> {
774    fn default() -> Self {
775        Self {
776            recvs: vec![DrawReceiver::new()],
777            trans: Transformation::default(),
778        }
779    }
780}
781
782impl<S: Schema> Container<S> {
783    /// Creates a new container.
784    pub fn new() -> Self {
785        Self::default()
786    }
787
788    pub(crate) fn finish(self, elements: &mut Vec<Element<S::Layer>>) {
789        for mut recv in self.recvs {
790            recv.trans = Transformation::cascade(self.trans, recv.trans);
791            recv.finish(elements);
792        }
793    }
794
795    pub(crate) fn recv_mut(&mut self) -> &mut DrawReceiver<S> {
796        self.recvs.last_mut().unwrap()
797    }
798
799    /// Draw layout object `obj`.
800    ///
801    /// For instances, a new thread is spawned to add the instance once the underlying cell has
802    /// been generated. If generation fails, the spawned thread may panic after this function has
803    /// been called.
804    ///
805    /// For error recovery, instance generation results should be checked using [`Instance::try_cell`]
806    /// before calling `draw`.
807    ///
808    /// # Panics
809    ///
810    /// May cause a panic if generation of an underlying instance fails.
811    pub fn draw(&mut self, obj: impl Draw<S>) -> Result<()> {
812        self.recv_mut().draw(obj)
813    }
814}
815
816impl<S: Schema> Bbox for Container<S> {
817    fn bbox(&self) -> Option<geometry::rect::Rect> {
818        self.recvs.bbox().transform(self.trans)
819    }
820}
821
822impl<S: Schema> LayerBbox<S::Layer> for Container<S> {
823    fn layer_bbox(&self, layer: &S::Layer) -> Option<Rect> {
824        self.recvs.layer_bbox(layer).transform(self.trans)
825    }
826}
827
828impl<S: Schema> Draw<S> for Container<S> {
829    fn draw(self, recv: &mut DrawReceiver<S>) -> Result<()> {
830        recv.draw_container(self);
831        Ok(())
832    }
833}
834
835impl<S: Schema> TranslateMut for Container<S> {
836    fn translate_mut(&mut self, p: Point) {
837        self.transform_mut(Transformation::from_offset(p))
838    }
839}
840
841impl<S: Schema> TransformMut for Container<S> {
842    fn transform_mut(&mut self, trans: Transformation) {
843        self.trans = Transformation::cascade(trans, self.trans);
844        let mut recv = DrawReceiver::new();
845        recv.trans = self.trans.inv();
846        self.recvs.push(recv);
847    }
848}
849
850/// A layout library in a given schema.
851pub struct LayoutLibrary<S: Schema> {
852    inner: layir::Library<S::Layer>,
853}
854
855impl<S: Schema> Deref for LayoutLibrary<S> {
856    type Target = layir::Library<S::Layer>;
857    fn deref(&self) -> &Self::Target {
858        &self.inner
859    }
860}
861
862impl<S: Schema> DerefMut for LayoutLibrary<S> {
863    fn deref_mut(&mut self) -> &mut Self::Target {
864        &mut self.inner
865    }
866}