mod.rs 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302
  1. use std::{
  2. fmt::Debug,
  3. fs::File,
  4. io::{Cursor, Read, Write},
  5. path::PathBuf,
  6. };
  7. use binrw::{BinRead, BinWrite, BinWriterExt};
  8. use diff::Diff;
  9. use modular_bitfield::{
  10. bitfield,
  11. specifiers::{B1, B14},
  12. };
  13. use crate::{
  14. field_of::FieldOf,
  15. types::{Coordinate, Field, ObjectType, WString, F64, U16, U32},
  16. };
  17. use self::{
  18. circle::Circle, ellipse::Ellipse, hatch::Hatch, line::Lines, polygon::Polygon,
  19. rectangle::Rectangle,
  20. };
  21. pub mod circle;
  22. pub mod ellipse;
  23. pub mod hatch;
  24. pub mod line;
  25. pub mod polygon;
  26. pub mod rectangle;
  27. pub trait Translate {
  28. /// Move origin of object to point
  29. fn move_absolute(&mut self, origin: Option<Coordinate>, z: Option<f64>);
  30. fn move_relative(&mut self, delta: Option<Coordinate>, z: Option<f64>);
  31. }
  32. #[bitfield(bits = 16)]
  33. #[derive(BinRead, BinWrite, Copy, Clone, Debug, Default, Diff, PartialEq)]
  34. #[diff(attr(
  35. #[derive(Debug, PartialEq)]
  36. ))]
  37. #[br(map = Self::from_bytes)]
  38. #[bw(map = |&x| Self::into_bytes(x))]
  39. pub struct ObjectFlags {
  40. pub disabled: B1,
  41. pub aspect_ratio_unlocked: B1,
  42. #[skip]
  43. __: B14,
  44. }
  45. /// Core properties defined for all object types
  46. #[cfg_attr(feature = "default-debug", derive(Debug))]
  47. #[derive(BinRead, BinWrite, Clone, Diff, PartialEq)]
  48. #[diff(attr(
  49. #[derive(Debug, PartialEq)]
  50. ))]
  51. #[brw(magic(17u32))]
  52. pub struct ObjectCore {
  53. pub pen: U32,
  54. pub obj_type: FieldOf<ObjectType>,
  55. pub flags: FieldOf<ObjectFlags>,
  56. pub name: WString,
  57. pub count: U32,
  58. pub _unknown_1: Field,
  59. pub io_control_enable_mask: U16,
  60. pub io_control_disable_mask: U16,
  61. pub _unknown_2: [Field; 5],
  62. pub origin: FieldOf<Coordinate>,
  63. pub z: F64,
  64. pub a: F64,
  65. pub index: U32, // Increments for each hatch fill line (types 1/2) or 0xFFFF_FFFF (types 3/4/5/7/8)
  66. }
  67. // Custom Debug implementation to only print known fields
  68. #[cfg(not(feature = "default-debug"))]
  69. impl Debug for ObjectCore {
  70. fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
  71. f.debug_struct("ObjectCore")
  72. .field("pen", &self.pen)
  73. .field("obj_type", &self.obj_type)
  74. .field("flags", &self.flags)
  75. .field("name", &self.name)
  76. .field("count", &self.count)
  77. .field("io_control_enable_mask", &self.io_control_enable_mask)
  78. .field("io_control_disable_mask", &self.io_control_disable_mask)
  79. .field("origin", &self.origin)
  80. .field("z", &self.z)
  81. .field("a", &self.a)
  82. .field("index", &self.index)
  83. .finish()
  84. }
  85. }
  86. impl Translate for ObjectCore {
  87. fn move_absolute(&mut self, origin: Option<Coordinate>, z: Option<f64>) {
  88. origin.map(|origin| *self.origin = origin);
  89. z.map(|z| self.z = z.into());
  90. }
  91. fn move_relative(&mut self, delta: Option<Coordinate>, z: Option<f64>) {
  92. delta.map(|delta| *self.origin += delta);
  93. z.map(|z| *self.z += z);
  94. }
  95. }
  96. impl ObjectCore {
  97. pub fn default(obj_type: ObjectType) -> Self {
  98. Self {
  99. pen: 0.into(),
  100. obj_type: obj_type.into(),
  101. flags: ObjectFlags::new()
  102. .with_disabled(0)
  103. .with_aspect_ratio_unlocked(0)
  104. .into(),
  105. name: "\0".to_string().into(),
  106. count: 1.into(),
  107. _unknown_1: vec![0, 0].into(), // 0_u16
  108. io_control_enable_mask: Default::default(),
  109. io_control_disable_mask: Default::default(),
  110. _unknown_2: [
  111. vec![0, 0].into(), // 0_u16
  112. vec![1, 0, 0, 0].into(), // 1_u32
  113. vec![1, 0, 0, 0].into(), // 1_u32
  114. vec![0, 0, 0, 0, 0, 0, 36, 64].into(), // 10.0_f64
  115. vec![0, 0, 0, 0, 0, 0, 36, 64].into(), // 10.0_f64
  116. ]
  117. .into(),
  118. origin: Coordinate { x: 0.0, y: 0.0 }.into(),
  119. z: 0.0.into(),
  120. a: 0.0.into(),
  121. index: 0.into(),
  122. }
  123. }
  124. }
  125. #[derive(BinRead, BinWrite, Clone, Debug, Diff, PartialEq, strum::Display)]
  126. #[diff(attr(
  127. #[derive(Debug, PartialEq)]
  128. ))]
  129. pub enum Object {
  130. #[brw(magic = 1u32)]
  131. Curve(Lines),
  132. #[brw(magic = 2u32)]
  133. Point(Lines),
  134. #[brw(magic = 3u32)]
  135. Rectangle(Rectangle),
  136. #[brw(magic = 4u32)]
  137. Circle(Circle),
  138. #[brw(magic = 5u32)]
  139. Ellipse(Ellipse),
  140. #[brw(magic = 6u32)]
  141. Polygon(Polygon),
  142. #[brw(magic = 32u32)]
  143. Hatch(Hatch),
  144. }
  145. impl Translate for Object {
  146. fn move_absolute(&mut self, origin: Option<Coordinate>, z: Option<f64>) {
  147. match self {
  148. Object::Curve(x) => x.move_absolute(origin, z),
  149. Object::Point(x) => x.move_absolute(origin, z),
  150. Object::Rectangle(x) => x.move_absolute(origin, z),
  151. Object::Circle(x) => x.move_absolute(origin, z),
  152. Object::Ellipse(x) => x.move_absolute(origin, z),
  153. Object::Polygon(x) => x.move_absolute(origin, z),
  154. Object::Hatch(x) => x.move_absolute(origin, z),
  155. }
  156. }
  157. fn move_relative(&mut self, delta: Option<Coordinate>, z: Option<f64>) {
  158. match self {
  159. Object::Curve(x) => x.move_relative(delta, z),
  160. Object::Point(x) => x.move_relative(delta, z),
  161. Object::Rectangle(x) => x.move_relative(delta, z),
  162. Object::Circle(x) => x.move_relative(delta, z),
  163. Object::Ellipse(x) => x.move_relative(delta, z),
  164. Object::Polygon(x) => x.move_relative(delta, z),
  165. Object::Hatch(x) => x.move_relative(delta, z),
  166. }
  167. }
  168. }
  169. impl Object {
  170. pub fn read_from_file(path: &PathBuf) -> Self {
  171. let mut input: File = File::open(path).expect("Failed to open input file");
  172. let mut buffer: Cursor<Vec<u8>> = Cursor::new(vec![]);
  173. input
  174. .read_to_end(buffer.get_mut())
  175. .expect("Failed to read input file");
  176. Object::read_le(&mut buffer).expect("Failed to deserialize input as object")
  177. }
  178. pub fn write_to_file(&self, path: &PathBuf) {
  179. let mut buffer: Cursor<Vec<u8>> = Cursor::new(vec![]);
  180. buffer.write_le(self).expect("Failed to serialize object");
  181. let mut output: File = File::create(path).expect("Failed to open output file");
  182. output
  183. .write_all(buffer.into_inner().as_slice())
  184. .expect("Failed to write to output file");
  185. }
  186. pub fn set_pen(&mut self, pen: u32) {
  187. match self {
  188. Object::Curve(x) => x.core.pen = pen.into(),
  189. Object::Point(x) => x.core.pen = pen.into(),
  190. Object::Rectangle(x) => x.core.pen = pen.into(),
  191. Object::Circle(x) => x.core.pen = pen.into(),
  192. Object::Ellipse(x) => x.core.pen = pen.into(),
  193. Object::Polygon(x) => x.core.pen = pen.into(),
  194. Object::Hatch(x) => {
  195. x.core.pen = pen.into();
  196. x.hatch_settings.iter_mut().for_each(|y| y.pen = pen.into());
  197. x.legacy_setting.hatch_0_pen = pen.into();
  198. x.legacy_setting.hatch_1_pen = pen.into();
  199. x.legacy_setting.hatch_2_pen = pen.into();
  200. }
  201. }
  202. }
  203. pub fn core(&mut self) -> &mut ObjectCore {
  204. match self {
  205. Object::Curve(x) => &mut x.core,
  206. Object::Point(x) => &mut x.core,
  207. Object::Rectangle(x) => &mut x.core,
  208. Object::Circle(x) => &mut x.core,
  209. Object::Ellipse(x) => &mut x.core,
  210. Object::Polygon(x) => &mut x.core,
  211. Object::Hatch(x) => &mut x.core,
  212. }
  213. }
  214. }
  215. #[derive(BinRead, BinWrite, Clone, Debug, Diff, PartialEq)]
  216. #[diff(attr(
  217. #[derive(Debug, PartialEq)]
  218. ))]
  219. pub struct ObjectModified {
  220. pub default: U32, // 0 if values are default, 255 otherwise
  221. pub changes: FieldOf<ScaleValues>,
  222. }
  223. impl Default for ObjectModified {
  224. fn default() -> Self {
  225. Self {
  226. default: 0.into(),
  227. changes: ScaleValues::default().into(),
  228. }
  229. }
  230. }
  231. #[derive(BinRead, BinWrite, Clone, Diff, PartialEq)]
  232. #[diff(attr(
  233. #[derive(Debug, PartialEq)]
  234. ))]
  235. pub struct ScaleValues {
  236. pub width_scale: f64,
  237. #[br(assert(_unknown_1 == 0.0))]
  238. _unknown_1: f64,
  239. #[br(assert(_unknown_2 == 0.0))]
  240. _unknown_2: f64,
  241. #[br(assert(_unknown_3 == 0.0))]
  242. _unknown_3: f64,
  243. pub height_scale: f64,
  244. #[br(assert(_unknown_4 == 0.0))]
  245. _unknown_4: f64,
  246. pub origin_x_delta: f64,
  247. pub origin_y_delta: f64,
  248. #[br(assert(_unknown_5 == 1.0))]
  249. _unknown_5: f64,
  250. }
  251. impl Default for ScaleValues {
  252. fn default() -> Self {
  253. Self {
  254. width_scale: 1.0.into(),
  255. _unknown_1: 0.0.into(),
  256. _unknown_2: 0.0.into(),
  257. _unknown_3: 0.0.into(),
  258. height_scale: 1.0.into(),
  259. _unknown_4: 0.0.into(),
  260. origin_x_delta: 0.0.into(),
  261. origin_y_delta: 0.0.into(),
  262. _unknown_5: 1.0.into(),
  263. }
  264. }
  265. }
  266. // Custom Debug implementation to only print known fields
  267. impl Debug for ScaleValues {
  268. fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
  269. f.debug_struct("ScaleValues")
  270. .field("width_scale", &self.width_scale)
  271. .field("height_scale", &self.height_scale)
  272. .field("origin_x_delta", &self.origin_x_delta)
  273. .field("origin_y_delta", &self.origin_y_delta)
  274. .finish()
  275. }
  276. }