diff --git a/crates/metafile/src/emfplus.rs b/crates/metafile/src/emfplus.rs index a4dcd4c2..62e8f714 100644 --- a/crates/metafile/src/emfplus.rs +++ b/crates/metafile/src/emfplus.rs @@ -286,10 +286,20 @@ impl Plus { if !self.active { return None; } + match typ { + 0x4008 => self.object(flags, r), + 0x4009 | 0x4013 | 0x401A..=0x401C | 0x4036 => self.record_image_text_region(cv, typ, flags, r), + 0x4025..=0x4035 => self.record_state(cv, typ, flags, r), + 0x4010..=0x4012 | 0x4016..=0x4019 => self.record_curve(cv, typ, flags, r), + _ => self.record_shape(cv, typ, flags, r), + } + } + + /// Rectangle, polygon, ellipse and path records. + fn record_shape(&mut self, cv: &mut Canvas, typ: u16, flags: u16, r: Bytes) -> Option<()> { let compressed = flags & 0x4000 != 0; let id = usize::from(flags & 0xFF); match typ { - 0x4008 => self.object(flags, r), 0x400A => { let fill = self.brush_of(flags, r.u32(0)?)?; let p = self.painter(); @@ -348,6 +358,15 @@ impl Plus { self.painter().stroke(cv, &ops, pen); Some(()) } + _ => None, + } + } + + /// Curve, bezier and arc records. + fn record_curve(&mut self, cv: &mut Canvas, typ: u16, flags: u16, r: Bytes) -> Option<()> { + let compressed = flags & 0x4000 != 0; + let id = usize::from(flags & 0xFF); + match typ { 0x4019 => { let pen = self.pen(id)?; let pts = points(r, 4, r.u32(0)? as usize, compressed)?; @@ -380,6 +399,29 @@ impl Plus { self.painter().stroke(cv, &curve_ops(&pts, tension, false, offset, segments), pen); Some(()) } + 0x4010 => { + let fill = self.brush_of(flags, r.u32(0)?)?; + let [start, sweep] = floats::<2>(r, 4)?; + let rect = *rects(r, 12, 1, compressed)?.first()?; + self.painter().fill(cv, &arc_ops(rect, start, sweep, true), &fill); + Some(()) + } + 0x4011 | 0x4012 => { + let pen = self.pen(id)?; + let [start, sweep] = floats::<2>(r, 0)?; + let rect = *rects(r, 8, 1, compressed)?.first()?; + self.painter().stroke(cv, &arc_ops(rect, start, sweep, typ == 0x4011), pen); + Some(()) + } + _ => None, + } + } + + /// Clear, region fill, image and text records. + fn record_image_text_region(&mut self, cv: &mut Canvas, typ: u16, flags: u16, r: Bytes) -> Option<()> { + let compressed = flags & 0x4000 != 0; + let id = usize::from(flags & 0xFF); + match typ { // Clear: the whole picture in one colour, whatever the clip (a transparent clear // leaves nothing to draw). 0x4009 => { @@ -419,6 +461,14 @@ impl Plus { } 0x401C => self.draw_string(cv, flags, r), 0x4036 => self.draw_driver_string(cv, flags, r), + _ => None, + } + } + + /// Save / restore, transform and clip records. + fn record_state(&mut self, cv: &mut Canvas, typ: u16, flags: u16, r: Bytes) -> Option<()> { + let id = usize::from(flags & 0xFF); + match typ { 0x4025 | 0x4028 => r.u32(0).map(|i| self.push(i)), 0x4027 => r.u32(24).map(|i| self.push(i)), 0x4026 | 0x4029 => r.u32(0).map(|i| self.pop(i)), @@ -470,20 +520,6 @@ impl Plus { } Some(()) } - 0x4010 => { - let fill = self.brush_of(flags, r.u32(0)?)?; - let [start, sweep] = floats::<2>(r, 4)?; - let rect = *rects(r, 12, 1, compressed)?.first()?; - self.painter().fill(cv, &arc_ops(rect, start, sweep, true), &fill); - Some(()) - } - 0x4011 | 0x4012 => { - let pen = self.pen(id)?; - let [start, sweep] = floats::<2>(r, 0)?; - let rect = *rects(r, 8, 1, compressed)?.first()?; - self.painter().stroke(cv, &arc_ops(rect, start, sweep, typ == 0x4011), pen); - Some(()) - } _ => None, } }