forked from 1b-agent/opencadstudio-upstream
feat(ole): render EMF/WMF OLE presentations
OLE2FRAME entities whose compound file carries a metafile presentation (Excel/Word previews, scanned WMF pages) drew only their border frame — the old decoder scanned the raw blob for a contiguous BMP, which the CFB sector layout almost never provides. acadrust now extracts the picture bytes tagged by kind; the new scene/model/gdi player rasterizes EMF and WMF record streams on the CPU (pens/brushes, polygons, paths, DIB blits, clipping, transforms) with text drawn through the existing system-font glyph cache, and image_model feeds the result into the raster pipeline. Rasters (BMP/PNG/JPEG/GIF, CF_DIB) decode as before via the image crate. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
1cfb856224
commit
e8411c1b6d
10 files changed
+2088
-42
No files matched your search
@@ -0,0 +1,28 @@
|
||||
// OLE2FRAME binary data → presentation RGBA image.
|
||||
//
|
||||
// Extraction (compound-file walk, OlePres header parse, WMFC → EMF
|
||||
// reassembly) lives in acadrust — `extract_presentation` returns the picture
|
||||
// bytes tagged by kind. This module only decodes them: rasters through the
|
||||
// `image` crate, metafiles through the `gdi` player.
|
||||
|
||||
use acadrust::entities::{extract_presentation, OlePresentation};
|
||||
|
||||
use super::gdi;
|
||||
|
||||
/// Decode the picture for an OLE2FRAME data blob. Returns RGBA + dimensions.
|
||||
pub fn decode(data: &[u8]) -> Option<(Vec<u8>, u32, u32)> {
|
||||
match extract_presentation(data)? {
|
||||
OlePresentation::Raster(bytes) => {
|
||||
let img = image::load_from_memory(&bytes).ok()?;
|
||||
let rgba = img.to_rgba8();
|
||||
let (w, h) = rgba.dimensions();
|
||||
if w == 0 || h == 0 {
|
||||
return None;
|
||||
}
|
||||
Some((rgba.into_raw(), w, h))
|
||||
}
|
||||
OlePresentation::Dib(bytes) => gdi::dib::decode_packed(&bytes),
|
||||
OlePresentation::Emf(bytes) => gdi::render_emf(&bytes),
|
||||
OlePresentation::Wmf(bytes) => gdi::render_wmf(&bytes),
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user