Closed DorianRudolph closed 1 year ago
Hi @DorianRudolph , yes, Pdfium does support rendering into an external buffer. We would need to add a new constructor to PdfBitmap
. Are you wanting to provide a buffer in the form of a &mut [u8]
slice?
(This approach is fundamentally incompatible with WASM because Pdfium and pdfium-render
inhabit separate memory address spaces when running in the browser.)
Under the assumption that you will be providing a &mut [u8]
, added a new PdfBitmap::external()
function that lets you pass in a buffer. You can test the function by using pdfium-render
as a git dependency in your project's Cargo.toml
.
Thanks, this is what I had in mind. I should be able to test it sometime this week.
Eventually I would like to get my project running in the web. Why would this not work in WASM? I guess your concern is that pdfium and pdfium-render are compiled to two different .wasm modules? I'm just learning about WASM, but could something like this work to establish a shared memory between WASM modules?
Because Pdfium and pdfium-render
are compiled separately, they inhabit independent WASM modules with independent linear address spaces. In theory it might be possible to combine these; in practice I highly doubt it could ever work safely, because the two modules have two different memory allocators that would have no knowledge of one-another and would therefore be endlessly clobbering one another's memory allocations.
So long as the WASM memory address spaces are separate, it will never be possible to share a buffer between Pdfium and pdfium-render
without a copy.
Because Javascript does have access to all memory irrespective of WASM modules, it is possible to work around this to a certain degree. The WASM-specific PdfBitmap::as_array()
function lets you pass through the array data of a Pdfium FPDF_BITMAP
buffer directly to Javascript without copying it into pdfium-render
's address space first.
My suggestion is that you have two code paths: one using PdfBitmap::external()
for your non-WASM builds, and one using PdfBitmap::as_array()
for your WASM build.
You are welcome to try getting Pdfium and pdfium-render
to share a single linear address space, but I would not be able to help you with this.
I will rename the PdfBitmap::external()
function in the next commit, and restrict it to non-WASM builds only.
Renamed PdfBitmap::external()
as PdfBitmap::from_bytes()
. Restricted compilation to non-WASM targets.
Added unit test for PdfBitmap::from_bytes()
. As there have been no further comments, and I believe PdfBitmap::from_bytes()
provides the functionality you require, I am closing the issue. Feel free to reopen if you feel the issue has not been resolved.
Yes thank you it works for me.
Btw, this is how I render into a skia image:
let w: f32 = page.width().value;
let h = page.height().value;
let scale = (2_000_000.0 / (w * h)).sqrt();
let width = (w * scale) as i32;
let height = (h * scale) as i32;
let data = unsafe { Data::new_uninitialized((width * height * 4) as usize) };
assert!(data.inner()._base.fRefCnt == 1);
let mut bitmap = unsafe {
let mut_data = std::slice::from_raw_parts_mut(data.inner().fPtr as _, data.size());
PdfBitmap::from_bytes(width, height, PdfBitmapFormat::BGRA, mut_data, pdfium.bindings())
.expect("Could not create bitmap")
};
page
.render_into_bitmap(&mut bitmap, width, height, None)
.expect("Could not render page");
let size = ISize::new(width, height);
let info = ImageInfo::new(size, ColorType::RGBA8888, AlphaType::Premul, None); // need RGB and not BGR, not sure why
let image = Image::from_raster_data(&info, data, (width * 4) as usize).unwrap();
I would like to render a PdfPage into an external buffer via a raw pointer. My use case is to render directly into a skia bitmap. This way I don't have to copy the data from the PdfBitmap to the skia bitmap, saving one copy.
Right now there does not appear to be a way to give pdfium-render a pointer or slice to render into.