mod.rs 9.4 KB

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