Skip to main content

altium_format/records/sch/
text_frame.rs

1//! SchTextFrame - Schematic text frame (Record 28) and variant (Record 209).
2
3use crate::error::Result;
4use crate::traits::{FromParams, ToParams};
5use crate::types::{Coord, CoordRect, ParameterCollection, UnknownFields};
6use altium_format_derive::AltiumRecord;
7
8use super::{LineWidth, SchGraphicalBase, SchPrimitive, TextOrientations};
9
10fn text_frame_bounds(location_x: i32, location_y: i32, corner_x: i32, corner_y: i32) -> CoordRect {
11    CoordRect::from_points(
12        Coord::from_raw(location_x),
13        Coord::from_raw(location_y),
14        Coord::from_raw(corner_x),
15        Coord::from_raw(corner_y),
16    )
17}
18
19/// Schematic text frame primitive.
20#[derive(Debug, Clone, Default, AltiumRecord)]
21#[altium(record_id = 28, format = "params")]
22pub struct SchTextFrame {
23    /// Graphical base (location = lower-left, color).
24    #[altium(flatten)]
25    pub graphical: SchGraphicalBase,
26
27    /// Corner point X (opposite corner).
28    #[altium(param = "CORNER.X", frac = "CORNER.X_FRAC")]
29    pub corner_x: i32,
30
31    /// Corner point Y (opposite corner).
32    #[altium(param = "CORNER.Y", frac = "CORNER.Y_FRAC")]
33    pub corner_y: i32,
34
35    /// Line width.
36    #[altium(param = "LINEWIDTH", default)]
37    pub line_width: LineWidth,
38
39    /// Whether the frame is solid (filled).
40    #[altium(param = "ISSOLID", default)]
41    pub is_solid: bool,
42
43    /// Whether the fill is transparent.
44    #[altium(param = "TRANSPARENT", default)]
45    pub transparent: bool,
46
47    /// Font ID (references fonts in the document).
48    #[altium(param = "FONTID", default)]
49    pub font_id: i32,
50
51    /// Text alignment.
52    #[altium(param = "ALIGNMENT", default)]
53    pub alignment: i32,
54
55    /// Whether to wrap words.
56    #[altium(param = "WORDWRAP", default)]
57    pub word_wrap: bool,
58
59    /// Whether to clip text to the frame.
60    #[altium(param = "CLIPTORECT", default)]
61    pub clip_to_rect: bool,
62
63    /// Text color.
64    #[altium(param = "TEXTCOLOR", default)]
65    pub text_color: i32,
66
67    /// Text contents.
68    #[altium(param = "TEXT", default)]
69    pub text: String,
70
71    /// Text orientation.
72    #[altium(param = "ORIENTATION", default)]
73    pub orientation: TextOrientations,
74
75    /// Text margin (raw coord units).
76    #[altium(param = "TEXTMARGIN", frac = "TEXTMARGIN_FRAC")]
77    pub text_margin: i32,
78
79    /// Whether to show the border.
80    #[altium(param = "SHOWBORDER", default)]
81    pub show_border: bool,
82
83    /// Unknown parameters (preserved for non-destructive editing).
84    #[altium(unknown)]
85    pub unknown_params: UnknownFields,
86}
87
88impl SchPrimitive for SchTextFrame {
89    const RECORD_ID: i32 = 28;
90
91    fn location(&self) -> Option<crate::types::CoordPoint> {
92        Some(crate::types::CoordPoint::from_raw(
93            self.graphical.location_x,
94            self.graphical.location_y,
95        ))
96    }
97
98    fn record_type_name(&self) -> &'static str {
99        "TextFrame"
100    }
101
102    fn get_property(&self, name: &str) -> Option<String> {
103        match name {
104            "TEXT" => Some(self.text.clone()),
105            _ => None,
106        }
107    }
108
109    fn import_from_params(params: &ParameterCollection) -> Result<Self> {
110        Self::from_params(params)
111    }
112
113    fn export_to_params(&self) -> ParameterCollection {
114        self.to_params()
115    }
116
117    fn owner_index(&self) -> i32 {
118        self.graphical.base.owner_index
119    }
120
121    fn calculate_bounds(&self) -> CoordRect {
122        text_frame_bounds(
123            self.graphical.location_x,
124            self.graphical.location_y,
125            self.corner_x,
126            self.corner_y,
127        )
128    }
129}
130
131/// Schematic text frame variant (Record 209).
132#[derive(Debug, Clone, Default, AltiumRecord)]
133#[altium(record_id = 209, format = "params")]
134pub struct SchTextFrameVariant {
135    /// Graphical base (location = lower-left, color).
136    #[altium(flatten)]
137    pub graphical: SchGraphicalBase,
138
139    /// Corner point X (opposite corner).
140    #[altium(param = "CORNER.X", frac = "CORNER.X_FRAC")]
141    pub corner_x: i32,
142
143    /// Corner point Y (opposite corner).
144    #[altium(param = "CORNER.Y", frac = "CORNER.Y_FRAC")]
145    pub corner_y: i32,
146
147    /// Line width.
148    #[altium(param = "LINEWIDTH", default)]
149    pub line_width: LineWidth,
150
151    /// Whether the frame is solid (filled).
152    #[altium(param = "ISSOLID", default)]
153    pub is_solid: bool,
154
155    /// Whether the fill is transparent.
156    #[altium(param = "TRANSPARENT", default)]
157    pub transparent: bool,
158
159    /// Font ID (references fonts in the document).
160    #[altium(param = "FONTID", default)]
161    pub font_id: i32,
162
163    /// Text alignment.
164    #[altium(param = "ALIGNMENT", default)]
165    pub alignment: i32,
166
167    /// Whether to wrap words.
168    #[altium(param = "WORDWRAP", default)]
169    pub word_wrap: bool,
170
171    /// Whether to clip text to the frame.
172    #[altium(param = "CLIPTORECT", default)]
173    pub clip_to_rect: bool,
174
175    /// Text color.
176    #[altium(param = "TEXTCOLOR", default)]
177    pub text_color: i32,
178
179    /// Text contents.
180    #[altium(param = "TEXT", default)]
181    pub text: String,
182
183    /// Text orientation.
184    #[altium(param = "ORIENTATION", default)]
185    pub orientation: TextOrientations,
186
187    /// Text margin (raw coord units).
188    #[altium(param = "TEXTMARGIN", frac = "TEXTMARGIN_FRAC")]
189    pub text_margin: i32,
190
191    /// Whether to show the border.
192    #[altium(param = "SHOWBORDER", default)]
193    pub show_border: bool,
194
195    /// Unknown parameters (preserved for non-destructive editing).
196    #[altium(unknown)]
197    pub unknown_params: UnknownFields,
198}
199
200impl SchPrimitive for SchTextFrameVariant {
201    const RECORD_ID: i32 = 209;
202
203    fn location(&self) -> Option<crate::types::CoordPoint> {
204        Some(crate::types::CoordPoint::from_raw(
205            self.graphical.location_x,
206            self.graphical.location_y,
207        ))
208    }
209
210    fn record_type_name(&self) -> &'static str {
211        "TextFrameVariant"
212    }
213
214    fn get_property(&self, name: &str) -> Option<String> {
215        match name {
216            "TEXT" => Some(self.text.clone()),
217            _ => None,
218        }
219    }
220
221    fn import_from_params(params: &ParameterCollection) -> Result<Self> {
222        Self::from_params(params)
223    }
224
225    fn export_to_params(&self) -> ParameterCollection {
226        self.to_params()
227    }
228
229    fn owner_index(&self) -> i32 {
230        self.graphical.base.owner_index
231    }
232
233    fn calculate_bounds(&self) -> CoordRect {
234        text_frame_bounds(
235            self.graphical.location_x,
236            self.graphical.location_y,
237            self.corner_x,
238            self.corner_y,
239        )
240    }
241}