forked from 1b-agent/opencadstudio-upstream
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>
29 lines
1.1 KiB
Rust
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),
|
|
}
|
|
}
|