Files
OneCAD-Draft/src/scene/model/ole_pres.rs
T
Hakan SevenandClaude Fable 5 e8411c1b6d 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>
2026-07-21 01:23:31 +03:00

29 lines
1.1 KiB
Rust

// 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),
}
}