diff --git a/src/object_pool/colour.rs b/src/object_pool/colour.rs index 7d0af04..3e9b735 100644 --- a/src/object_pool/colour.rs +++ b/src/object_pool/colour.rs @@ -14,13 +14,7 @@ impl Colour { } pub fn new_by_rgb(r: u8, g: u8, b: u8) -> Self { - for colour in Colour::COLOUR_PALETTE.iter() { - if colour.r == r && colour.g == g && colour.b == b { - return *colour; - } - } - - Colour::BLACK + Colour::COLOUR_PALETTE[16 + (r * 36 + g * 6 + b) as usize] } pub fn new_by_rgba(r: u8, g: u8, b: u8, _a: u8) -> Self { diff --git a/src/object_pool/mod.rs b/src/object_pool/mod.rs index aab41de..2f2bae0 100644 --- a/src/object_pool/mod.rs +++ b/src/object_pool/mod.rs @@ -7,7 +7,7 @@ pub mod object_attributes; mod object_id; mod object_pool; mod object_type; -mod vt_version; +pub mod vt_version; use crate::network_management::name::NAME; diff --git a/src/object_pool/object.rs b/src/object_pool/object.rs index eb4acb0..5dd8fc0 100644 --- a/src/object_pool/object.rs +++ b/src/object_pool/object.rs @@ -11,9 +11,10 @@ use crate::object_pool::object_attributes::{ use crate::object_pool::object_id::ObjectId; use crate::object_pool::{Colour, ObjectType}; +use super::object_attributes::{DataCodeType, PictureGraphicFormat}; use super::object_id::NullableObjectId; -#[derive(Debug)] +#[derive(Debug, Clone, PartialEq)] pub enum Object { WorkingSet(WorkingSet), DataMask(DataMask), @@ -121,6 +122,60 @@ impl Object { } } + pub fn mut_id(&mut self) -> &mut ObjectId { + match self { + Object::WorkingSet(o) => &mut o.id, + Object::DataMask(o) => &mut o.id, + Object::AlarmMask(o) => &mut o.id, + Object::Container(o) => &mut o.id, + Object::SoftKeyMask(o) => &mut o.id, + Object::Key(o) => &mut o.id, + Object::Button(o) => &mut o.id, + Object::InputBoolean(o) => &mut o.id, + Object::InputString(o) => &mut o.id, + Object::InputNumber(o) => &mut o.id, + Object::InputList(o) => &mut o.id, + Object::OutputString(o) => &mut o.id, + Object::OutputNumber(o) => &mut o.id, + Object::OutputList(o) => &mut o.id, + Object::OutputLine(o) => &mut o.id, + Object::OutputRectangle(o) => &mut o.id, + Object::OutputEllipse(o) => &mut o.id, + Object::OutputPolygon(o) => &mut o.id, + Object::OutputMeter(o) => &mut o.id, + Object::OutputLinearBarGraph(o) => &mut o.id, + Object::OutputArchedBarGraph(o) => &mut o.id, + Object::PictureGraphic(o) => &mut o.id, + Object::NumberVariable(o) => &mut o.id, + Object::StringVariable(o) => &mut o.id, + Object::FontAttributes(o) => &mut o.id, + Object::LineAttributes(o) => &mut o.id, + Object::FillAttributes(o) => &mut o.id, + Object::InputAttributes(o) => &mut o.id, + Object::ObjectPointer(o) => &mut o.id, + Object::Macro(o) => &mut o.id, + Object::AuxiliaryFunctionType1(o) => &mut o.id, + Object::AuxiliaryInputType1(o) => &mut o.id, + Object::AuxiliaryFunctionType2(o) => &mut o.id, + Object::AuxiliaryInputType2(o) => &mut o.id, + Object::AuxiliaryControlDesignatorType2(o) => &mut o.id, + Object::WindowMask(o) => &mut o.id, + Object::KeyGroup(o) => &mut o.id, + Object::GraphicsContext(o) => &mut o.id, + Object::ExtendedInputAttributes(o) => &mut o.id, + Object::ColourMap(o) => &mut o.id, + Object::ObjectLabelReferenceList(o) => &mut o.id, + Object::ExternalObjectDefinition(o) => &mut o.id, + Object::ExternalReferenceName(o) => &mut o.id, + Object::ExternalObjectPointer(o) => &mut o.id, + Object::Animation(o) => &mut o.id, + Object::ColourPalette(o) => &mut o.id, + Object::GraphicData(o) => &mut o.id, + Object::WorkingSetSpecialControls(o) => &mut o.id, + Object::ScaledGraphic(o) => &mut o.id, + } + } + pub fn object_type(&self) -> ObjectType { match self { Object::WorkingSet(_) => ObjectType::WorkingSet, @@ -341,12 +396,41 @@ impl Object { refs } + + pub fn as_sized_object(&self) -> Option<&dyn SizedObject> { + match self { + Object::Container(o) => Some(o), + Object::Button(o) => Some(o), + Object::InputBoolean(o) => Some(o), + Object::InputString(o) => Some(o), + Object::InputNumber(o) => Some(o), + Object::InputList(o) => Some(o), + Object::OutputString(o) => Some(o), + Object::OutputNumber(o) => Some(o), + Object::OutputList(o) => Some(o), + Object::OutputLine(o) => Some(o), + Object::OutputRectangle(o) => Some(o), + Object::OutputEllipse(o) => Some(o), + Object::OutputPolygon(o) => Some(o), + Object::OutputMeter(o) => Some(o), + Object::OutputLinearBarGraph(o) => Some(o), + Object::OutputArchedBarGraph(o) => Some(o), + Object::PictureGraphic(o) => Some(o), + Object::ScaledGraphic(o) => Some(o), + _ => None, + } + } +} + +pub trait SizedObject { + fn width(&self) -> u16; + fn height(&self) -> u16; } -#[derive(Debug, PartialEq)] +#[derive(Debug, PartialEq, Clone)] pub struct WorkingSet { pub id: ObjectId, - pub background_colour: Colour, + pub background_colour: u8, pub selectable: bool, pub active_mask: ObjectId, pub object_refs: Vec, @@ -354,7 +438,7 @@ pub struct WorkingSet { pub language_codes: Vec, } -#[derive(Debug, PartialEq)] +#[derive(Debug, PartialEq, Clone)] pub struct DataMask { pub id: ObjectId, pub background_colour: u8, @@ -363,7 +447,7 @@ pub struct DataMask { pub macro_refs: Vec, } -#[derive(Debug, PartialEq)] +#[derive(Debug, PartialEq, Clone)] pub struct AlarmMask { pub id: ObjectId, pub background_colour: u8, @@ -374,7 +458,7 @@ pub struct AlarmMask { pub macro_refs: Vec, } -#[derive(Debug, PartialEq)] +#[derive(Debug, PartialEq, Clone)] pub struct Container { pub id: ObjectId, pub width: u16, @@ -384,7 +468,17 @@ pub struct Container { pub macro_refs: Vec, } -#[derive(Debug, PartialEq)] +impl SizedObject for Container { + fn width(&self) -> u16 { + self.width + } + + fn height(&self) -> u16 { + self.height + } +} + +#[derive(Debug, PartialEq, Clone)] pub struct SoftKeyMask { pub id: ObjectId, pub background_colour: u8, @@ -392,7 +486,7 @@ pub struct SoftKeyMask { pub macro_refs: Vec, } -#[derive(Debug, PartialEq)] +#[derive(Debug, PartialEq, Clone)] pub struct Key { pub id: ObjectId, pub background_colour: u8, @@ -401,7 +495,7 @@ pub struct Key { pub macro_refs: Vec, } -#[derive(Debug, PartialEq)] +#[derive(Debug, PartialEq, Clone)] pub struct Button { pub id: ObjectId, pub width: u16, @@ -414,7 +508,17 @@ pub struct Button { pub macro_refs: Vec, } -#[derive(Debug, PartialEq)] +impl SizedObject for Button { + fn width(&self) -> u16 { + self.width + } + + fn height(&self) -> u16 { + self.height + } +} + +#[derive(Debug, PartialEq, Clone)] pub struct InputBoolean { pub id: ObjectId, pub background_colour: u8, @@ -426,7 +530,17 @@ pub struct InputBoolean { pub macro_refs: Vec, } -#[derive(Debug, PartialEq)] +impl SizedObject for InputBoolean { + fn width(&self) -> u16 { + self.width + } + + fn height(&self) -> u16 { + self.width + } +} + +#[derive(Debug, PartialEq, Clone)] pub struct InputString { pub id: ObjectId, pub width: u16, @@ -442,6 +556,16 @@ pub struct InputString { pub macro_refs: Vec, } +impl SizedObject for InputString { + fn width(&self) -> u16 { + self.width + } + + fn height(&self) -> u16 { + self.height + } +} + #[derive(Debug, Clone, PartialEq)] pub struct InputNumber { pub id: ObjectId, @@ -463,6 +587,16 @@ pub struct InputNumber { pub macro_refs: Vec, } +impl SizedObject for InputNumber { + fn width(&self) -> u16 { + self.width + } + + fn height(&self) -> u16 { + self.height + } +} + #[derive(Debug, PartialEq, Clone)] pub struct InputList { pub id: ObjectId, @@ -475,6 +609,16 @@ pub struct InputList { pub macro_refs: Vec, } +impl SizedObject for InputList { + fn width(&self) -> u16 { + self.width + } + + fn height(&self) -> u16 { + self.height + } +} + #[derive(Debug, PartialEq, Clone)] pub struct OutputString { pub id: ObjectId, @@ -489,7 +633,17 @@ pub struct OutputString { pub macro_refs: Vec, } -#[derive(Debug, PartialEq)] +impl SizedObject for OutputString { + fn width(&self) -> u16 { + self.width + } + + fn height(&self) -> u16 { + self.height + } +} + +#[derive(Debug, PartialEq, Clone)] pub struct OutputNumber { pub id: ObjectId, pub width: u16, @@ -507,6 +661,16 @@ pub struct OutputNumber { pub macro_refs: Vec, } +impl SizedObject for OutputNumber { + fn width(&self) -> u16 { + self.width + } + + fn height(&self) -> u16 { + self.height + } +} + #[derive(Debug, PartialEq, Clone)] pub struct OutputList { pub id: ObjectId, @@ -518,6 +682,16 @@ pub struct OutputList { pub macro_refs: Vec, } +impl SizedObject for OutputList { + fn width(&self) -> u16 { + self.width + } + + fn height(&self) -> u16 { + self.height + } +} + #[derive(Debug, PartialEq, Clone)] pub struct OutputLine { pub id: ObjectId, @@ -528,7 +702,17 @@ pub struct OutputLine { pub macro_refs: Vec, } -#[derive(Debug)] +impl SizedObject for OutputLine { + fn width(&self) -> u16 { + self.width + } + + fn height(&self) -> u16 { + self.height + } +} + +#[derive(Debug, PartialEq, Clone)] pub struct OutputRectangle { pub id: ObjectId, pub line_attributes: ObjectId, @@ -539,7 +723,17 @@ pub struct OutputRectangle { pub macro_refs: Vec, } -#[derive(Debug)] +impl SizedObject for OutputRectangle { + fn width(&self) -> u16 { + self.width + } + + fn height(&self) -> u16 { + self.height + } +} + +#[derive(Debug, PartialEq, Clone)] pub struct OutputEllipse { pub id: ObjectId, pub line_attributes: ObjectId, @@ -552,7 +746,17 @@ pub struct OutputEllipse { pub macro_refs: Vec, } -#[derive(Debug)] +impl SizedObject for OutputEllipse { + fn width(&self) -> u16 { + self.width + } + + fn height(&self) -> u16 { + self.height + } +} + +#[derive(Debug, PartialEq, Clone)] pub struct OutputPolygon { pub id: ObjectId, pub width: u16, @@ -564,7 +768,17 @@ pub struct OutputPolygon { pub macro_refs: Vec, } -#[derive(Debug)] +impl SizedObject for OutputPolygon { + fn width(&self) -> u16 { + self.width + } + + fn height(&self) -> u16 { + self.height + } +} + +#[derive(Debug, PartialEq, Clone)] pub struct OutputMeter { pub id: ObjectId, pub width: u16, @@ -582,7 +796,17 @@ pub struct OutputMeter { pub macro_refs: Vec, } -#[derive(Debug, Clone, PartialEq, Eq)] +impl SizedObject for OutputMeter { + fn width(&self) -> u16 { + self.width + } + + fn height(&self) -> u16 { + self.width + } +} + +#[derive(Debug, Clone, PartialEq)] pub struct OutputLinearBarGraph { pub id: ObjectId, pub width: u16, @@ -600,7 +824,17 @@ pub struct OutputLinearBarGraph { pub macro_refs: Vec, } -#[derive(Debug)] +impl SizedObject for OutputLinearBarGraph { + fn width(&self) -> u16 { + self.width + } + + fn height(&self) -> u16 { + self.height + } +} + +#[derive(Debug, PartialEq, Clone)] pub struct OutputArchedBarGraph { pub id: ObjectId, pub width: u16, @@ -620,32 +854,89 @@ pub struct OutputArchedBarGraph { pub macro_refs: Vec, } -#[derive(Debug)] +impl SizedObject for OutputArchedBarGraph { + fn width(&self) -> u16 { + self.width + } + + fn height(&self) -> u16 { + self.height + } +} + +#[derive(Debug, PartialEq, Clone)] pub struct PictureGraphic { pub id: ObjectId, pub width: u16, pub actual_width: u16, pub actual_height: u16, - pub format: u8, + pub format: PictureGraphicFormat, pub options: PictureGraphicOptions, pub transparency_colour: u8, pub data: Vec, pub macro_refs: Vec, } -#[derive(Debug)] +impl PictureGraphic { + pub fn data_as_raw_encoded(&self) -> Vec { + match self.options.data_code_type { + DataCodeType::Raw => self.data.clone(), + DataCodeType::RunLength => { + let mut raw_data = vec![]; + let mut i = 0; + while i < self.data.len() { + let count = self.data[i] as usize; + let value = self.data[i + 1]; + raw_data.extend(vec![value; count]); + i += 2; + } + raw_data + } + } + } + + pub fn data_as_run_length_encoded(&self) -> Vec { + match self.options.data_code_type { + DataCodeType::Raw => { + let mut run_length_data = vec![]; + let mut i = 0; + while i < self.data.len() { + let value = self.data[i]; + let count = self.data[i..].iter().take_while(|&&x| x == value).count(); + run_length_data.push(count as u8); + run_length_data.push(value); + i += count; + } + run_length_data + } + DataCodeType::RunLength => self.data.clone(), + } + } +} + +impl SizedObject for PictureGraphic { + fn width(&self) -> u16 { + self.width + } + + fn height(&self) -> u16 { + (self.actual_height as f32 * (self.width as f32 / self.actual_width as f32)) as u16 + } +} + +#[derive(Debug, PartialEq, Clone)] pub struct NumberVariable { pub id: ObjectId, pub value: u32, } -#[derive(Debug)] +#[derive(Debug, PartialEq, Clone)] pub struct StringVariable { pub id: ObjectId, pub value: String, } -#[derive(Debug)] +#[derive(Debug, PartialEq, Clone)] pub struct FontAttributes { pub id: ObjectId, pub font_colour: u8, @@ -655,7 +946,7 @@ pub struct FontAttributes { pub macro_refs: Vec, } -#[derive(Debug)] +#[derive(Debug, PartialEq, Clone)] pub struct LineAttributes { pub id: ObjectId, pub line_colour: u8, @@ -664,7 +955,7 @@ pub struct LineAttributes { pub macro_refs: Vec, } -#[derive(Debug)] +#[derive(Debug, PartialEq, Clone)] pub struct FillAttributes { pub id: ObjectId, pub fill_type: u8, @@ -673,7 +964,7 @@ pub struct FillAttributes { pub macro_refs: Vec, } -#[derive(Debug)] +#[derive(Debug, PartialEq, Clone)] pub struct InputAttributes { pub id: ObjectId, pub validation_type: u8, @@ -681,7 +972,7 @@ pub struct InputAttributes { pub macro_refs: Vec, } -#[derive(Debug, Copy, Clone)] +#[derive(Debug, PartialEq, Copy, Clone)] pub enum ValidationType { ValidCharacters, InvalidCharacters, @@ -706,38 +997,38 @@ impl From for ValidationType { } } -#[derive(Debug)] +#[derive(Debug, PartialEq, Clone)] pub struct CharacterRange { pub first_character: u16, pub last_character: u16, } -#[derive(Debug)] +#[derive(Debug, PartialEq, Clone)] pub struct CodePlane { pub number: u8, pub character_ranges: Vec, } -#[derive(Debug)] +#[derive(Debug, PartialEq, Clone)] pub struct ExtendedInputAttributes { pub id: ObjectId, pub validation_type: ValidationType, pub code_planes: Vec, } -#[derive(Debug)] +#[derive(Debug, PartialEq, Clone)] pub struct ObjectPointer { pub id: ObjectId, pub value: NullableObjectId, } -#[derive(Debug)] +#[derive(Debug, PartialEq, Clone)] pub struct Macro { pub id: ObjectId, pub commands: Vec, } -#[derive(Debug)] +#[derive(Debug, PartialEq, Clone)] pub struct AuxiliaryFunctionType1 { pub id: ObjectId, pub background_colour: u8, @@ -745,7 +1036,7 @@ pub struct AuxiliaryFunctionType1 { pub object_refs: Vec, } -#[derive(Debug)] +#[derive(Debug, PartialEq, Clone)] pub struct AuxiliaryInputType1 { pub id: ObjectId, pub background_colour: u8, @@ -754,7 +1045,7 @@ pub struct AuxiliaryInputType1 { pub object_refs: Vec, } -#[derive(Debug)] +#[derive(Debug, PartialEq, Clone)] pub struct AuxiliaryFunctionType2 { pub id: ObjectId, pub background_colour: u8, @@ -762,7 +1053,7 @@ pub struct AuxiliaryFunctionType2 { pub object_refs: Vec, } -#[derive(Debug)] +#[derive(Debug, PartialEq, Clone)] pub struct AuxiliaryInputType2 { pub id: ObjectId, pub background_colour: u8, @@ -770,14 +1061,14 @@ pub struct AuxiliaryInputType2 { pub object_refs: Vec, } -#[derive(Debug)] +#[derive(Debug, PartialEq, Clone)] pub struct AuxiliaryControlDesignatorType2 { pub id: ObjectId, pub pointer_type: u8, pub auxiliary_object_id: ObjectId, } -#[derive(Debug)] +#[derive(Debug, PartialEq, Clone)] pub struct ColourMap { pub id: ObjectId, pub colour_map: Vec, @@ -805,6 +1096,16 @@ pub struct GraphicsContext { pub transparency_colour: u8, } +impl SizedObject for GraphicsContext { + fn width(&self) -> u16 { + self.viewport_width + } + + fn height(&self) -> u16 { + self.viewport_height + } +} + #[derive(Debug, Clone, PartialEq)] pub struct WindowMask { pub id: ObjectId, @@ -820,7 +1121,7 @@ pub struct WindowMask { pub macro_refs: Vec, } -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq)] pub struct KeyGroup { pub id: ObjectId, pub options: KeyGroupOptions, @@ -830,7 +1131,7 @@ pub struct KeyGroup { pub macro_refs: Vec, } -#[derive(Debug)] +#[derive(Debug, PartialEq, Clone)] pub struct ObjectLabelReferenceList { pub id: ObjectId, pub object_labels: Vec, @@ -844,14 +1145,14 @@ pub struct ExternalObjectDefinition { pub objects: Vec, } -#[derive(Debug)] +#[derive(Debug, PartialEq, Clone)] pub struct ExternalReferenceName { pub id: ObjectId, pub options: ExternalReferenceNameOptions, pub name: NAME, } -#[derive(Debug)] +#[derive(Debug, PartialEq, Clone)] pub struct ExternalObjectPointer { pub id: ObjectId, pub default_object_id: NullableObjectId, @@ -859,7 +1160,7 @@ pub struct ExternalObjectPointer { pub external_object_id: NullableObjectId, } -#[derive(Debug)] +#[derive(Debug, PartialEq, Clone)] pub struct Animation { pub id: ObjectId, pub width: u16, @@ -875,21 +1176,31 @@ pub struct Animation { pub macro_refs: Vec, } -#[derive(Debug)] +impl SizedObject for Animation { + fn width(&self) -> u16 { + self.width + } + + fn height(&self) -> u16 { + self.height + } +} + +#[derive(Debug, PartialEq, Clone)] pub struct ColourPalette { pub id: ObjectId, pub options: ColourPaletteOptions, pub colours: Vec, } -#[derive(Debug)] +#[derive(Debug, PartialEq, Clone)] pub struct GraphicData { pub id: ObjectId, pub format: u8, pub data: Vec, } -#[derive(Debug)] +#[derive(Debug, PartialEq, Clone)] pub struct ScaledGraphic { pub id: ObjectId, pub width: u16, @@ -900,7 +1211,17 @@ pub struct ScaledGraphic { pub macro_refs: Vec, } -#[derive(Debug)] +impl SizedObject for ScaledGraphic { + fn width(&self) -> u16 { + self.width + } + + fn height(&self) -> u16 { + self.height + } +} + +#[derive(Debug, PartialEq, Clone)] pub struct WorkingSetSpecialControls { pub id: ObjectId, pub id_of_colour_map: NullableObjectId, diff --git a/src/object_pool/object_attributes.rs b/src/object_pool/object_attributes.rs index ce42ed0..468589b 100644 --- a/src/object_pool/object_attributes.rs +++ b/src/object_pool/object_attributes.rs @@ -39,7 +39,7 @@ impl From for WindowType { impl From for u8 { fn from(value: WindowType) -> Self { - value.into() + value as u8 } } @@ -131,12 +131,82 @@ impl From for u8 { let mut bit_data: BitVec = BitVec::new(); bit_data.push(value.available); bit_data.push(value.transparent); - bit_data.extend([0; 6]); + bit_data.extend([false; 6]); bit_data.load::() } } -#[derive(Debug, PartialEq, Clone)] +#[derive(FromRepr, Debug, PartialEq, Clone, Copy)] +#[repr(u8)] +pub enum Event { + Reserved = 0, + OnActivate = 1, + OnDeactivate = 2, + OnShow = 3, + OnHide = 4, + // OnRefresh = N/A + OnEnable = 5, + OnDisable = 6, + OnChangeActiveMask = 7, + OnChangeSoftKeyMask = 8, + OnChangeAttribute = 9, + OnChangeBackgroundColour = 10, + OnChangeFontAttributes = 11, + OnChangeLineAttributes = 12, + OnChangeFillAttributes = 13, + OnChangeChildLocation = 14, + OnChangeSize = 15, + OnChangeValue = 16, + OnChangePriority = 17, + OnChangeEndPoint = 18, + OnInputFieldSelection = 19, + OnInputFieldDeselection = 20, + OnESC = 21, + OnEntryOfValue = 22, + OnEntryOfNewValue = 23, + OnKeyPress = 24, + OnKeyRelease = 25, + OnChangeChildPosition = 26, + OnPointingEventPress = 27, + OnPointingEventRelease = 28, + // Reserved 29-239 + ProprietaryEvent1 = 240, + ProprietaryEvent2 = 241, + ProprietaryEvent3 = 242, + ProprietaryEvent4 = 243, + ProprietaryEvent5 = 244, + ProprietaryEvent6 = 245, + ProprietaryEvent7 = 246, + ProprietaryEvent8 = 247, + ProprietaryEvent9 = 248, + ProprietaryEvent10 = 249, + ProprietaryEvent11 = 250, + ProprietaryEvent12 = 251, + ProprietaryEvent13 = 252, + ProprietaryEvent14 = 253, + ProprietaryEvent15 = 254, + UseExtendedMacro = 255, +} + +impl Event { + pub fn iter() -> impl Iterator { + (0..=255).map(Event::from).filter(|e| *e != Event::Reserved) + } +} + +impl From for Event { + fn from(value: u8) -> Self { + Event::from_repr(value).unwrap_or(Event::Reserved) + } +} + +impl From for u8 { + fn from(value: Event) -> Self { + value as u8 + } +} + +#[derive(Debug, PartialEq, Clone, Copy)] pub struct ObjectRef { pub id: ObjectId, pub offset: Point, @@ -144,10 +214,10 @@ pub struct ObjectRef { // pub y: i16, } -#[derive(Debug, PartialEq, Eq, Clone)] +#[derive(Debug, PartialEq, Clone)] pub struct MacroRef { pub macro_id: u8, - pub event_id: u8, + pub event_id: Event, } #[derive(Debug, Default, Clone, Copy, PartialEq)] @@ -167,7 +237,7 @@ impl core::ops::Add> for Point { } } -#[derive(Debug)] +#[derive(Debug, PartialEq, Clone)] pub struct ObjectLabel { pub id: ObjectId, pub string_variable_reference: NullableObjectId, @@ -208,7 +278,7 @@ impl From for u8 { bit_data.push(value.transparent_background); bit_data.push(value.disabled); bit_data.push(value.no_border); - bit_data.extend([0; 3]); + bit_data.extend([false; 2]); bit_data.load::() } } @@ -261,7 +331,7 @@ impl From for u8 { bit_data.push(value.transparent); bit_data.push(value.auto_wrap); bit_data.push(value.wrap_on_hyphen); - bit_data.extend([0; 5]); + bit_data.extend([false; 5]); bit_data.load::() } } @@ -274,7 +344,7 @@ pub struct Alignment { impl From for Alignment { fn from(value: u8) -> Self { - let mut bit_data = value.view_bits::().to_bitvec(); + let mut bit_data = value.view_bits::().to_bitvec(); Alignment { horizontal: HorizontalAlignment::from([ bit_data.pop().unwrap(), @@ -390,7 +460,7 @@ impl From for u8 { let mut bit_data: BitVec = BitVec::new(); bit_data.push(value.enabled); bit_data.push(value.real_time_editing); - bit_data.extend([0; 6]); + bit_data.extend([false; 6]); bit_data.load::() } } @@ -440,7 +510,7 @@ impl From for u8 { let mut bit_data: BitVec = BitVec::new(); bit_data.push(value.enabled); bit_data.push(value.real_time_editing); - bit_data.extend([0; 6]); + bit_data.extend([false; 6]); bit_data.load::() } } @@ -515,7 +585,7 @@ impl From for u8 { bit_data.push(value.display_leading_zeros); bit_data.push(value.display_zero_as_blank); bit_data.push(value.truncate); - bit_data.extend([0; 4]); + bit_data.extend([false; 4]); bit_data.load::() } } @@ -526,7 +596,7 @@ impl From for u8 { bit_data.push(value.transparent); bit_data.push(value.auto_wrap); bit_data.push(value.wrap_on_hyphen); - bit_data.extend([0; 5]); + bit_data.extend([false; 5]); bit_data.load::() } } @@ -591,7 +661,7 @@ pub struct GraphicsContextOptions { impl From for GraphicsContextOptions { fn from(value: u8) -> Self { - let mut bit_data = value.view_bits::().to_bitvec(); + let mut bit_data = value.view_bits::().to_bitvec(); GraphicsContextOptions { transparent: bit_data.pop().unwrap(), color: bit_data.pop().unwrap().into(), @@ -604,7 +674,7 @@ impl From for u8 { let mut bit_data: BitVec = BitVec::new(); bit_data.push(value.transparent); bit_data.push(value.color.into()); - bit_data.extend([0; 6]); + bit_data.extend([false; 6]); bit_data.load::() } } @@ -617,7 +687,7 @@ pub struct KeyGroupOptions { impl From for KeyGroupOptions { fn from(value: u8) -> Self { - let mut bit_data = value.view_bits::().to_bitvec(); + let mut bit_data = value.view_bits::().to_bitvec(); KeyGroupOptions { available: bit_data.pop().unwrap(), transparent: bit_data.pop().unwrap(), @@ -630,7 +700,7 @@ impl From for u8 { let mut bit_data: BitVec = BitVec::new(); bit_data.push(value.available); bit_data.push(value.transparent); - bit_data.extend([0; 6]); + bit_data.extend([false; 6]); bit_data.load::() } } @@ -669,7 +739,7 @@ pub struct OutputMeterOptions { impl From for OutputMeterOptions { fn from(value: u8) -> Self { - let mut bit_data = value.view_bits::().to_bitvec(); + let mut bit_data = value.view_bits::().to_bitvec(); OutputMeterOptions { draw_arc: bit_data.pop().unwrap(), draw_border: bit_data.pop().unwrap(), @@ -686,7 +756,7 @@ impl From for u8 { bit_data.push(value.draw_border); bit_data.push(value.draw_ticks); bit_data.push(value.deflection_direction.into()); - bit_data.extend([0; 4]); + bit_data.extend([false; 4]); bit_data.load::() } } @@ -775,7 +845,7 @@ pub struct OutputLinearBarGraphOptions { impl From for OutputLinearBarGraphOptions { fn from(value: u8) -> Self { - let mut bit_data = value.view_bits::().to_bitvec(); + let mut bit_data = value.view_bits::().to_bitvec(); OutputLinearBarGraphOptions { draw_border: bit_data.pop().unwrap(), draw_target_line: bit_data.pop().unwrap(), @@ -796,7 +866,7 @@ impl From for u8 { bit_data.push(value.bar_graph_type.into()); bit_data.push(value.axis_orientation.into()); bit_data.push(value.grow_direction.into()); - bit_data.extend([0; 2]); + bit_data.extend([false; 2]); bit_data.load::() } } @@ -813,7 +883,7 @@ pub struct OutputArchedBarGraphOptions { impl From for OutputArchedBarGraphOptions { fn from(value: u8) -> Self { - let mut bit_data = value.view_bits::().to_bitvec(); + let mut bit_data = value.view_bits::().to_bitvec(); let draw_border = bit_data.pop().unwrap(); let draw_target_line = bit_data.pop().unwrap(); bit_data.pop(); //undefined bit @@ -839,7 +909,7 @@ impl From for u8 { bit_data.push(value.axis_orientation.into()); bit_data.push(value.grow_direction.into()); bit_data.push(value.deflection_direction.into()); - bit_data.extend([0; 1]); + bit_data.extend([false; 1]); bit_data.load::() } } @@ -868,6 +938,26 @@ impl From for bool { } } +#[derive(FromRepr, Debug, PartialEq, Clone, Copy)] +#[repr(u8)] +pub enum PictureGraphicFormat { + Monochrome = 0, + FourBit = 1, + EightBit = 2, +} + +impl From for PictureGraphicFormat { + fn from(value: u8) -> Self { + PictureGraphicFormat::from_repr(value).unwrap() + } +} + +impl From for u8 { + fn from(value: PictureGraphicFormat) -> Self { + value as u8 + } +} + #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct PictureGraphicOptions { pub transparent: bool, @@ -877,7 +967,7 @@ pub struct PictureGraphicOptions { impl From for PictureGraphicOptions { fn from(value: u8) -> Self { - let mut bit_data = value.view_bits::().to_bitvec(); + let mut bit_data = value.view_bits::().to_bitvec(); PictureGraphicOptions { transparent: bit_data.pop().unwrap(), flashing: bit_data.pop().unwrap(), @@ -892,7 +982,7 @@ impl From for u8 { bit_data.push(value.transparent); bit_data.push(value.flashing); bit_data.push(value.data_code_type.into()); - bit_data.extend([0; 5]); + bit_data.extend([false; 5]); bit_data.load::() } } @@ -904,7 +994,7 @@ pub struct ExternalObjectDefinitionOptions { impl From for ExternalObjectDefinitionOptions { fn from(value: u8) -> Self { - let mut bit_data = value.view_bits::().to_bitvec(); + let mut bit_data = value.view_bits::().to_bitvec(); ExternalObjectDefinitionOptions { enabled: bit_data.pop().unwrap(), } @@ -915,7 +1005,7 @@ impl From for u8 { fn from(value: ExternalObjectDefinitionOptions) -> u8 { let mut bit_data: BitVec = BitVec::new(); bit_data.push(value.enabled); - bit_data.extend([0; 7]); + bit_data.extend([false; 7]); bit_data.load::() } } @@ -927,7 +1017,7 @@ pub struct ExternalReferenceNameOptions { impl From for ExternalReferenceNameOptions { fn from(value: u8) -> Self { - let mut bit_data = value.view_bits::().to_bitvec(); + let mut bit_data = value.view_bits::().to_bitvec(); ExternalReferenceNameOptions { enabled: bit_data.pop().unwrap(), } @@ -938,7 +1028,7 @@ impl From for u8 { fn from(value: ExternalReferenceNameOptions) -> u8 { let mut bit_data: BitVec = BitVec::new(); bit_data.push(value.enabled); - bit_data.extend([0; 7]); + bit_data.extend([false; 7]); bit_data.load::() } } @@ -1023,7 +1113,7 @@ impl From for u8 { let disabled_behaviour: [bool; 2] = value.disabled_behaviour.into(); bit_data.push(disabled_behaviour[0]); bit_data.push(disabled_behaviour[1]); - bit_data.extend([0; 5]); + bit_data.extend([false; 5]); bit_data.load::() } } @@ -1041,7 +1131,7 @@ impl From for ColourPaletteOptions { impl From for u8 { fn from(_value: ColourPaletteOptions) -> u8 { let mut bit_data: BitVec = BitVec::new(); - bit_data.extend([0; 8]); + bit_data.extend([false; 8]); bit_data.load::() } } @@ -1064,7 +1154,7 @@ impl From for u8 { fn from(value: ScaledGraphicOptions) -> u8 { let mut bit_data: BitVec = BitVec::new(); bit_data.push(value.flashing); - bit_data.extend([0; 7]); + bit_data.extend([false; 7]); bit_data.load::() } } diff --git a/src/object_pool/object_id.rs b/src/object_pool/object_id.rs index fd42461..d2dff66 100644 --- a/src/object_pool/object_id.rs +++ b/src/object_pool/object_id.rs @@ -15,6 +15,19 @@ impl ObjectId { Ok(ObjectId { id }) } } + + pub fn value(&self) -> u16 { + self.id + } + + pub fn set_value(&mut self, id: u16) -> Result<(), ParseError> { + if id == Self::NULL.id { + Err(ParseError::UnexpectedNullObjectId) + } else { + self.id = id; + Ok(()) + } + } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] diff --git a/src/object_pool/object_pool.rs b/src/object_pool/object_pool.rs index 952315b..f2d8e71 100644 --- a/src/object_pool/object_pool.rs +++ b/src/object_pool/object_pool.rs @@ -7,16 +7,13 @@ use crate::object_pool::object::{ use crate::object_pool::object_id::ObjectId; use crate::object_pool::vt_version::VtVersion; use crate::object_pool::ObjectType; -use core::cell::Cell; -#[derive(Debug)] +#[derive(Debug, Clone, PartialEq)] pub struct ObjectPool { objects: Vec, colour_map: [u8; 256], colour_palette: [Colour; 256], _supported_vt_version: VtVersion, - - size_cache: Cell>, } impl ObjectPool { @@ -32,16 +29,11 @@ impl ObjectPool { colour_map, colour_palette: Colour::COLOUR_PALETTE, _supported_vt_version: VtVersion::default(), - - size_cache: Cell::new(None), } } pub fn size(&self) -> usize { - if self.size_cache.get().is_none() { - self.size_cache.set(Some(self.as_iop().len())); - } - self.size_cache.get().unwrap_or_default() + self.objects.len() } /// @@ -112,10 +104,18 @@ impl ObjectPool { self.objects.push(obj); } + pub fn remove(&mut self, id: ObjectId) { + self.objects.retain(|x| x.id() != id); + } + pub fn object_by_id(&self, id: ObjectId) -> Option<&Object> { self.objects.iter().find(|&o| o.id() == id) } + pub fn object_mut_by_id(&mut self, id: ObjectId) -> Option<&mut Object> { + self.objects.iter_mut().find(|o| o.id() == id) + } + pub fn objects_by_type(&self, object_type: ObjectType) -> Vec<&Object> { self.objects .iter() @@ -123,6 +123,24 @@ impl ObjectPool { .collect() } + pub fn objects_by_types(&self, object_types: &[ObjectType]) -> Vec<&Object> { + self.objects + .iter() + .filter(|&o| object_types.contains(&o.object_type())) + .collect() + } + + pub fn parent_objects(&self, id: ObjectId) -> Vec<&Object> { + self.objects + .iter() + .filter(|&o| o.referenced_objects().contains(&id)) + .collect() + } + + pub fn objects(&self) -> &[Object] { + &self.objects + } + // Get objects by type pub fn working_set_object(&self) -> Option<&WorkingSet> { @@ -287,6 +305,97 @@ impl ObjectPool { pub fn color_by_index(&self, index: u8) -> Colour { self.colour_palette[self.colour_map[index as usize] as usize] } + + pub fn color_to_index(&self, color: Colour) -> Option { + self.colour_map + .iter() + .find(|&&c| self.colour_palette[c as usize] == color) + .map(|&c| c) + } + + /// + /// Returns the needed width and height of the object to fit its content. + /// + pub fn content_size(&self, object: &Object) -> (u16, u16) { + // If the object is a sized object, return its size + if let Some(sized) = object.as_sized_object() { + return (sized.width(), sized.height()); + } + + // Some special cases where the content is not an object ref + match object { + Object::SoftKeyMask(o) => { + let mut width = 0; + let mut height = 0; + for object_id in o.objects.iter() { + if let Some(object) = self.object_by_id(*object_id) { + let (object_width, object_height) = self.content_size(object); + width = width.max(object_width); + height = height.max(object_height); + } + } + return (width, height); + } + Object::ObjectPointer(o) => { + if let Some(id) = o.value.into() { + if let Some(object) = self.object_by_id(id) { + return self.content_size(object); + } + } + } + _ => (), + } + + // Otherwise, return the largest x and y reached by one of the object refs + let object_refs = match object { + Object::WorkingSet(o) => o.object_refs.iter(), + Object::DataMask(o) => o.object_refs.iter(), + Object::AlarmMask(o) => o.object_refs.iter(), + Object::Key(o) => o.object_refs.iter(), + Object::AuxiliaryFunctionType1(o) => o.object_refs.iter(), + Object::AuxiliaryInputType1(o) => o.object_refs.iter(), + Object::AuxiliaryFunctionType2(o) => o.object_refs.iter(), + Object::AuxiliaryInputType2(o) => o.object_refs.iter(), + _ => return (0, 0), + }; + + let mut width = 0; + let mut height = 0; + for object_ref in object_refs { + if let Some(object) = self.object_by_id(object_ref.id) { + let (object_width, object_height) = self.content_size(object); + width = width.max(object_width as i16 + object_ref.offset.x); + height = height.max(object_height as i16 + object_ref.offset.y); + } + } + (width.max(0) as u16, height.max(0) as u16) + } + + /// + /// Calculates the minimum size for all data masks and keys in soft key masks + /// + pub fn get_minimum_mask_sizes(&self) -> (u16, (u16, u16)) { + let mut mask_size = 0; + let mut soft_key_size = (0, 0); + + for mask in self.objects_by_types(&[ObjectType::DataMask, ObjectType::AlarmMask]) { + let size = self.content_size(mask); + mask_size = mask_size.max(size.0.max(size.1)); + + let soft_key_mask_id = match mask { + Object::DataMask(o) => o.soft_key_mask.0, + Object::AlarmMask(o) => o.soft_key_mask.0, + _ => None, + }; + if let Some(soft_key_mask_id) = soft_key_mask_id { + if let Some(soft_key_mask) = self.object_by_id(soft_key_mask_id) { + soft_key_size = soft_key_size.max(self.content_size(soft_key_mask)); + } + } + } + + (mask_size, soft_key_size) + } } impl Default for ObjectPool { @@ -295,6 +404,15 @@ impl Default for ObjectPool { } } +impl IntoIterator for ObjectPool { + type Item = Object; + type IntoIter = std::vec::IntoIter; + + fn into_iter(self) -> Self::IntoIter { + self.objects.into_iter() + } +} + /* !todo: implement tests / fix tests #[cfg(test)] mod tests { diff --git a/src/object_pool/object_type.rs b/src/object_pool/object_type.rs index 950384e..0eef64b 100644 --- a/src/object_pool/object_type.rs +++ b/src/object_pool/object_type.rs @@ -168,3 +168,15 @@ impl From for u8 { } } } + +impl ObjectType { + pub fn values() -> Vec { + let mut values = Vec::new(); + for idx in u8::MIN..=u8::MAX { + if let Ok(obj_type) = ObjectType::try_from(idx) { + values.push(obj_type); + } + } + values + } +} diff --git a/src/object_pool/reader.rs b/src/object_pool/reader.rs index df58023..75965d0 100644 --- a/src/object_pool/reader.rs +++ b/src/object_pool/reader.rs @@ -77,7 +77,7 @@ impl Object { ) -> Result, ParseError> { let mut objs = Vec::new(); for _ in 0..nr_of_objects { - objs.push(Self::read_u16(data)?.try_into()?); + objs.push(Self::read_u16(data)?.clamp(0, u16::MAX - 1).try_into()?); } Ok(objs) } @@ -116,7 +116,7 @@ impl Object { let mut refs = Vec::new(); for _ in 0..nr_of_macros { refs.push(MacroRef { - event_id: Self::read_u8(data)?, + event_id: Self::read_u8(data)?.into(), macro_id: Self::read_u8(data)?, }) } @@ -375,7 +375,7 @@ impl Object { ) -> Result { let mut o = DataMask { id, - background_colour: Self::read_u8(data)?, + background_colour: Self::read_u8(data)?.into(), soft_key_mask: Self::read_u16(data)?.into(), object_refs: Vec::with_capacity(Self::read_u8(data)?.into()), macro_refs: Vec::with_capacity(Self::read_u8(data)?.into()), @@ -395,7 +395,7 @@ impl Object { ) -> Result { let mut o = AlarmMask { id, - background_colour: Self::read_u8(data)?, + background_colour: Self::read_u8(data)?.into(), soft_key_mask: Self::read_u16(data)?.into(), priority: Self::read_u8(data)?, acoustic_signal: Self::read_u8(data)?, @@ -438,7 +438,7 @@ impl Object { ) -> Result { let mut o = SoftKeyMask { id, - background_colour: Self::read_u8(data)?, + background_colour: Self::read_u8(data)?.into(), objects: Vec::with_capacity(Self::read_u8(data)?.into()), macro_refs: Vec::with_capacity(Self::read_u8(data)?.into()), }; @@ -454,7 +454,7 @@ impl Object { fn read_key(id: ObjectId, data: &mut dyn Iterator) -> Result { let mut o = Key { id, - background_colour: Self::read_u8(data)?, + background_colour: Self::read_u8(data)?.into(), key_code: Self::read_u8(data)?, object_refs: Vec::with_capacity(Self::read_u8(data)?.into()), macro_refs: Vec::with_capacity(Self::read_u8(data)?.into()), @@ -473,8 +473,8 @@ impl Object { id, width: Self::read_u16(data)?, height: Self::read_u16(data)?, - background_colour: Self::read_u8(data)?, - border_colour: Self::read_u8(data)?, + background_colour: Self::read_u8(data)?.into(), + border_colour: Self::read_u8(data)?.into(), key_code: Self::read_u8(data)?, options: Self::read_u8(data)?.into(), object_refs: Vec::with_capacity(Self::read_u8(data)?.into()), @@ -495,7 +495,7 @@ impl Object { ) -> Result { let mut o = InputBoolean { id, - background_colour: Self::read_u8(data)?, + background_colour: Self::read_u8(data)?.into(), width: Self::read_u16(data)?, foreground_colour: Self::read_u16(data)?.try_into()?, variable_reference: Self::read_u16(data)?.into(), @@ -518,7 +518,7 @@ impl Object { id, width: Self::read_u16(data)?, height: Self::read_u16(data)?, - background_colour: Self::read_u8(data)?, + background_colour: Self::read_u8(data)?.into(), font_attributes: Self::read_u16(data)?.try_into()?, input_attributes: Self::read_u16(data)?.into(), options: Self::read_u8(data)?.into(), @@ -543,7 +543,7 @@ impl Object { id, width: Self::read_u16(data)?, height: Self::read_u16(data)?, - background_colour: Self::read_u8(data)?, + background_colour: Self::read_u8(data)?.into(), font_attributes: Self::read_u16(data)?.try_into()?, options: Self::read_u8(data)?.into(), variable_reference: Self::read_u16(data)?.into(), @@ -598,7 +598,7 @@ impl Object { id, width: Self::read_u16(data)?, height: Self::read_u16(data)?, - background_colour: Self::read_u8(data)?, + background_colour: Self::read_u8(data)?.into(), font_attributes: Self::read_u16(data)?.try_into()?, options: Self::read_u8(data)?.into(), variable_reference: Self::read_u16(data)?.into(), @@ -621,7 +621,7 @@ impl Object { id, width: Self::read_u16(data)?, height: Self::read_u16(data)?, - background_colour: Self::read_u8(data)?, + background_colour: Self::read_u8(data)?.into(), font_attributes: Self::read_u16(data)?.try_into()?, options: Self::read_u8(data)?.into(), variable_reference: Self::read_u16(data)?.into(), @@ -731,9 +731,9 @@ impl Object { let mut o = OutputMeter { id, width: Self::read_u16(data)?, - needle_colour: Self::read_u8(data)?, - border_colour: Self::read_u8(data)?, - arc_and_tick_colour: Self::read_u8(data)?, + needle_colour: Self::read_u8(data)?.into(), + border_colour: Self::read_u8(data)?.into(), + arc_and_tick_colour: Self::read_u8(data)?.into(), options: Self::read_u8(data)?.into(), nr_of_ticks: Self::read_u8(data)?, start_angle: Self::read_u8(data)?, @@ -759,8 +759,8 @@ impl Object { id, width: Self::read_u16(data)?, height: Self::read_u16(data)?, - colour: Self::read_u8(data)?, - target_line_colour: Self::read_u8(data)?, + colour: Self::read_u8(data)?.into(), + target_line_colour: Self::read_u8(data)?.into(), options: Self::read_u8(data)?.into(), nr_of_ticks: Self::read_u8(data)?, min_value: Self::read_u16(data)?, @@ -786,8 +786,8 @@ impl Object { id, width: Self::read_u16(data)?, height: Self::read_u16(data)?, - colour: Self::read_u8(data)?, - target_line_colour: Self::read_u8(data)?, + colour: Self::read_u8(data)?.into(), + target_line_colour: Self::read_u8(data)?.into(), options: Self::read_u8(data)?.into(), start_angle: Self::read_u8(data)?, end_angle: Self::read_u8(data)?, @@ -816,16 +816,19 @@ impl Object { width: Self::read_u16(data)?, actual_width: Self::read_u16(data)?, actual_height: Self::read_u16(data)?, - format: Self::read_u8(data)?, + format: Self::read_u8(data)?.into(), options: Self::read_u8(data)?.into(), - transparency_colour: Self::read_u8(data)?, - data: Vec::with_capacity(Self::read_u32(data)? as usize), - macro_refs: Vec::with_capacity(Self::read_u8(data)?.into()), + transparency_colour: Self::read_u8(data)?.into(), + data: Vec::new(), + macro_refs: Vec::new(), }; - o.data.extend(Self::read_bytes(data, o.data.capacity())?); + let data_len = Self::read_u32(data)? as usize; + let macro_refs_len = Self::read_u8(data)? as usize; + + o.data.extend(Self::read_bytes(data, data_len)?); o.macro_refs - .extend(Self::read_macro_refs(data, o.macro_refs.capacity())?); + .extend(Self::read_macro_refs(data, macro_refs_len)?); Ok(Object::PictureGraphic(o)) } @@ -860,7 +863,7 @@ impl Object { ) -> Result { let mut o = FontAttributes { id, - font_colour: Self::read_u8(data)?, + font_colour: Self::read_u8(data)?.into(), font_size: Self::read_u8(data)?, font_type: Self::read_u8(data)?, font_style: Self::read_u8(data)?, @@ -879,7 +882,7 @@ impl Object { ) -> Result { let mut o = LineAttributes { id, - line_colour: Self::read_u8(data)?, + line_colour: Self::read_u8(data)?.into(), line_width: Self::read_u8(data)?, line_art: Self::read_u16(data)?, macro_refs: Vec::with_capacity(Self::read_u8(data)?.into()), @@ -898,7 +901,7 @@ impl Object { let mut o = FillAttributes { id, fill_type: Self::read_u8(data)?, - fill_colour: Self::read_u8(data)?, + fill_colour: Self::read_u8(data)?.into(), fill_pattern: Self::read_u16(data)?.into(), macro_refs: Vec::with_capacity(Self::read_u8(data)?.into()), }; @@ -956,7 +959,7 @@ impl Object { ) -> Result { let mut o = AuxiliaryFunctionType1 { id, - background_colour: Self::read_u8(data)?, + background_colour: Self::read_u8(data)?.into(), function_type: Self::read_u8(data)?, object_refs: Vec::with_capacity(Self::read_u8(data)?.into()), }; @@ -973,7 +976,7 @@ impl Object { ) -> Result { let mut o = AuxiliaryInputType1 { id, - background_colour: Self::read_u8(data)?, + background_colour: Self::read_u8(data)?.into(), function_type: Self::read_u8(data)?, input_id: Self::read_u8(data)?, object_refs: Vec::with_capacity(Self::read_u8(data)?.into()), @@ -991,7 +994,7 @@ impl Object { ) -> Result { let mut o = AuxiliaryFunctionType2 { id, - background_colour: Self::read_u8(data)?, + background_colour: Self::read_u8(data)?.into(), function_attributes: Self::read_u8(data)?, object_refs: Vec::with_capacity(Self::read_u8(data)?.into()), }; @@ -1008,7 +1011,7 @@ impl Object { ) -> Result { let mut o = AuxiliaryInputType2 { id, - background_colour: Self::read_u8(data)?, + background_colour: Self::read_u8(data)?.into(), function_attributes: Self::read_u8(data)?, object_refs: Vec::with_capacity(Self::read_u8(data)?.into()), }; @@ -1040,7 +1043,7 @@ impl Object { id, cell_format: Self::read_u16(data)?.into(), window_type: Self::read_u8(data)?.into(), - background_colour: Self::read_u8(data)?, + background_colour: Self::read_u8(data)?.into(), options: Self::read_u8(data)?.into(), name: Self::read_u16(data)?.try_into()?, window_title: Self::read_u16(data)?.into(), @@ -1096,14 +1099,14 @@ impl Object { viewport_zoom: Self::read_f32(data)?, graphics_cursor_x: Self::read_i16(data)?, graphics_cursor_y: Self::read_i16(data)?, - foreground_colour: Self::read_u8(data)?, - background_colour: Self::read_u8(data)?, + foreground_colour: Self::read_u8(data)?.into(), + background_colour: Self::read_u8(data)?.into(), font_attributes_object: Self::read_u16(data)?.into(), line_attributes_object: Self::read_u16(data)?.into(), fill_attributes_object: Self::read_u16(data)?.into(), format: Self::read_u8(data)?.into(), options: Self::read_u8(data)?.into(), - transparency_colour: Self::read_u8(data)?, + transparency_colour: Self::read_u8(data)?.into(), }; Ok(Object::GraphicsContext(o)) } diff --git a/src/object_pool/vt_version.rs b/src/object_pool/vt_version.rs index da1f63a..cfc7d3e 100644 --- a/src/object_pool/vt_version.rs +++ b/src/object_pool/vt_version.rs @@ -1,7 +1,7 @@ use crate::object_pool::ParseError; use crate::object_pool::ParseError::UnsupportedVtVersion; -#[derive(Debug, Default)] +#[derive(Debug, Default, Clone, PartialEq, PartialOrd)] pub enum VtVersion { Version0, Version1, diff --git a/src/object_pool/writer.rs b/src/object_pool/writer.rs index 91a8edb..a77c373 100644 --- a/src/object_pool/writer.rs +++ b/src/object_pool/writer.rs @@ -308,6 +308,7 @@ impl Object { Self::write_u8(data, o.options); Self::write_u16(data, o.variable_reference); Self::write_u8(data, o.justification); + Self::write_u8(data, o.value.len() as u8); Self::write_string(data, &o.value); Self::write_u8(data, o.enabled); Self::write_u8(data, o.macro_refs.len() as u8); @@ -518,6 +519,7 @@ impl Object { fn write_string_variable(data: &mut Vec, o: &StringVariable) { Self::write_u16(data, o.id); Self::write_u8(data, ObjectType::StringVariable); + Self::write_u16(data, o.value.len() as u16); Self::write_string(data, &o.value); } fn write_font_attributes(data: &mut Vec, o: &FontAttributes) { @@ -555,6 +557,7 @@ impl Object { Self::write_u16(data, o.id); Self::write_u8(data, ObjectType::InputAttributes); Self::write_u8(data, o.validation_type); + Self::write_u8(data, o.validation_string.len() as u8); Self::write_string(data, &o.validation_string); Self::write_u8(data, o.macro_refs.len() as u8);