diff --git a/skia-safe/src/core/document.rs b/skia-safe/src/core/document.rs index 1bbfbcbb9..91c764f80 100644 --- a/skia-safe/src/core/document.rs +++ b/skia-safe/src/core/document.rs @@ -1,7 +1,9 @@ -use crate::{interop::DynamicMemoryWStream, prelude::*, Canvas, Data, Rect, Size}; +use std::{pin::Pin, ptr}; + use core::fmt; use skia_bindings::{self as sb, SkDocument, SkRefCntBase}; -use std::{pin::Pin, ptr}; + +use crate::{interop::DynamicMemoryWStream, prelude::*, Canvas, Data, Rect, Size}; pub struct Document { // note: order matters here, first the document must be diff --git a/skia-safe/src/docs/pdf_document.rs b/skia-safe/src/docs/pdf_document.rs index a9c9e5ba6..72bad1613 100644 --- a/skia-safe/src/docs/pdf_document.rs +++ b/skia-safe/src/docs/pdf_document.rs @@ -1,13 +1,15 @@ pub mod pdf { + use std::{ffi::CString, fmt, mem, ptr}; + use crate::{ interop::{AsStr, DynamicMemoryWStream, SetStr}, prelude::*, scalar, DateTime, Document, }; + use skia_bindings::{ self as sb, SkPDF_AttributeList, SkPDF_Metadata, SkPDF_StructureElementNode, }; - use std::{ffi::CString, fmt, mem, ptr}; pub type AttributeList = Handle; unsafe_send_sync!(AttributeList); @@ -286,9 +288,13 @@ pub mod pdf { } } -#[test] -fn create_attribute_list() { - use pdf::AttributeList; - let mut _al = AttributeList::default(); - _al.append_float_array("Owner", "Name", &[1.0, 2.0, 3.0]); +#[cfg(test)] +mod tests { + use super::pdf::AttributeList; + + #[test] + fn create_attribute_list() { + let mut _al = AttributeList::default(); + _al.append_float_array("Owner", "Name", &[1.0, 2.0, 3.0]); + } } diff --git a/skia-safe/src/interop/stream.rs b/skia-safe/src/interop/stream.rs index f44e15c80..af9ece871 100644 --- a/skia-safe/src/interop/stream.rs +++ b/skia-safe/src/interop/stream.rs @@ -7,7 +7,7 @@ use crate::{prelude::*, Data}; use skia_bindings::{ self as sb, SkDynamicMemoryWStream, SkMemoryStream, SkStream, SkStreamAsset, SkWStream, }; -use std::{ffi, fmt, io, marker::PhantomData, mem, ptr}; +use std::{ffi, fmt, io, marker::PhantomData, mem, ops::Deref, pin::Pin, ptr}; /// Trait representing an Skia allocated Stream type with a base class of SkStream. #[repr(transparent)] @@ -355,15 +355,22 @@ impl<'a> RustStream<'a> { } #[allow(unused)] -pub struct RustWStream<'a> { - inner: Handle, - _phantom: PhantomData<&'a mut ()>, +pub struct RustWStream { + writer: Pin>, + rust_stream: Handle, } -#[allow(unused)] -impl RustWStream<'_> { +impl RustWStream { pub fn stream_mut(&mut self) -> &mut SkWStream { - self.inner.native_mut().base_mut() + self.rust_stream.native_mut().base_mut() + } + + pub fn into_writer(mut self) -> W + where + W: Deref, + { + drop(self.rust_stream); + *unsafe { Pin::into_inner_unchecked(self.writer) } } } @@ -375,21 +382,26 @@ impl NativeDrop for sb::RustWStream { } } -impl<'a> RustWStream<'a> { - pub fn new(writer: &'a mut T) -> Self { +impl RustWStream { + pub(crate) fn new(writer: W) -> Self + where + W: io::Write, + { + let mut writer = Box::pin(writer); + let writer_ptr: *mut W = unsafe { writer.as_mut().get_unchecked_mut() }; return RustWStream { - inner: Handle::construct(|ptr| unsafe { + writer, + rust_stream: Handle::construct(|ptr| unsafe { sb::C_RustWStream_construct( ptr, - writer as *mut T as *mut ffi::c_void, - Some(write_trampoline::), - Some(flush_trampoline::), + writer_ptr as *mut ffi::c_void, + Some(write_trampoline::), + Some(flush_trampoline::), ); }), - _phantom: PhantomData, }; - unsafe extern "C" fn write_trampoline( + unsafe extern "C" fn write_trampoline( val: *mut ffi::c_void, buf: *const ffi::c_void, count: usize, @@ -398,7 +410,7 @@ impl<'a> RustWStream<'a> { return true; } let buf: &[u8] = std::slice::from_raw_parts(buf as _, count as _); - let val: &mut T = &mut *(val as *mut _); + let val: &mut W = &mut *(val as *mut _); // This is OK because we just abort if it panics anyway. let mut val = std::panic::AssertUnwindSafe(val); @@ -423,8 +435,8 @@ impl<'a> RustWStream<'a> { } } - unsafe extern "C" fn flush_trampoline(val: *mut ffi::c_void) { - let val: &mut T = &mut *(val as *mut _); + unsafe extern "C" fn flush_trampoline(val: *mut ffi::c_void) { + let val: &mut W = &mut *(val as *mut _); // This is OK because we just abort if it panics anyway. let mut val = std::panic::AssertUnwindSafe(val); match std::panic::catch_unwind(move || {