Skip to content

Commit

Permalink
Allow creating fonts with Arc<dyn AsRef[u8] + Send + Sync> (#57)
Browse files Browse the repository at this point in the history
This has advantages over a simple `Arc<Vec<u8>>` because it can avoid
data copies. A common case that this happens is when Servo creates
fonts from shared memory. In addition, this maintains full compatability
with `Arc<Vec<u8>>` because it fulfills the trait.

Finally, this bumps the version so that the changes can be deployed.

Signed-off-by: Martin Robinson <[email protected]>
  • Loading branch information
mrobinson authored Oct 8, 2024
1 parent 5a9070f commit 8276985
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 12 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name = "dwrote"
description = "Lightweight binding to DirectWrite."
repository = "https://github.com/servo/dwrote-rs"
license = "MPL-2.0"
version = "0.11.1"
version = "0.11.2"
authors = ["The Servo Project Developers", "Vladimir Vukicevic <[email protected]>"]
edition = "2018"

Expand Down
14 changes: 12 additions & 2 deletions src/font_file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,13 @@ impl FontFile {
}
}

#[deprecated(since = "0.11.2", note = "please use `new_from_buffer` instead")]
pub fn new_from_data(data: Arc<Vec<u8>>) -> Option<FontFile> {
let (font_file, font_file_stream, key) = DataFontHelper::register_font_data(data);
Self::new_from_buffer(data)
}

pub fn new_from_buffer(data: Arc<dyn AsRef<[u8]> + Sync + Send>) -> Option<FontFile> {
let (font_file, font_file_stream, key) = DataFontHelper::register_font_buffer(data);

let mut ff = FontFile {
native: UnsafeCell::new(font_file),
Expand All @@ -80,8 +85,13 @@ impl FontFile {
}
}

#[deprecated(since = "0.11.2", note = "please use `analyze_buffer` instead")]
pub fn analyze_data(data: Arc<Vec<u8>>) -> u32 {
let (font_file, font_file_stream, key) = DataFontHelper::register_font_data(data);
Self::analyze_buffer(data)
}

pub fn analyze_buffer(buffer: Arc<dyn AsRef<[u8]> + Sync + Send>) -> u32 {
let (font_file, font_file_stream, key) = DataFontHelper::register_font_buffer(buffer);

let mut ff = FontFile {
native: UnsafeCell::new(font_file),
Expand Down
17 changes: 9 additions & 8 deletions src/font_file_loader_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ unsafe impl Sync for FontFileLoader {}
struct FontFileStream {
refcount: atomic::AtomicUsize,
key: usize,
data: Arc<Vec<u8>>,
data: Arc<dyn AsRef<[u8]> + Sync + Send>,
}

const FontFileStreamVtbl: &'static IDWriteFontFileStreamVtbl = &IDWriteFontFileStreamVtbl {
Expand All @@ -95,11 +95,12 @@ const FontFileStreamVtbl: &'static IDWriteFontFileStreamVtbl = &IDWriteFontFileS
) -> HRESULT {
let this = FontFileStream::from_interface(This);
*fragmentContext = ptr::null_mut();
if (fileOffset + fragmentSize) as usize > this.data.len() {
let data = (*this.data).as_ref();
if (fileOffset + fragmentSize) as usize > data.len() {
return E_INVALIDARG;
}
let index = fileOffset as usize;
*fragmentStart = this.data[index..].as_ptr() as *const c_void;
*fragmentStart = data[index..].as_ptr() as *const c_void;
S_OK
}
ReadFileFragment
Expand All @@ -118,7 +119,7 @@ const FontFileStreamVtbl: &'static IDWriteFontFileStreamVtbl = &IDWriteFontFileS
fileSize: *mut UINT64,
) -> HRESULT {
let this = FontFileStream::from_interface(This);
*fileSize = this.data.len() as UINT64;
*fileSize = (*this.data).as_ref().len() as UINT64;
S_OK
}
GetFileSize
Expand All @@ -135,7 +136,7 @@ const FontFileStreamVtbl: &'static IDWriteFontFileStreamVtbl = &IDWriteFontFileS
};

impl FontFileStream {
pub fn new(key: usize, data: Arc<Vec<u8>>) -> FontFileStream {
pub fn new(key: usize, data: Arc<dyn AsRef<[u8]> + Sync + Send>) -> FontFileStream {
FontFileStream {
refcount: AtomicUsize::new(1),
key,
Expand Down Expand Up @@ -190,11 +191,11 @@ lazy_static! {
};
}

pub struct DataFontHelper;
pub(crate) struct DataFontHelper;

impl DataFontHelper {
pub fn register_font_data(
font_data: Arc<Vec<u8>>,
pub(crate) fn register_font_buffer(
font_data: Arc<dyn AsRef<[u8]> + Sync + Send>,
) -> (
ComPtr<IDWriteFontFile>,
ComPtr<IDWriteFontFileStream>,
Expand Down
6 changes: 5 additions & 1 deletion src/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,11 @@ fn test_create_font_file_from_bytes() {
assert!(bytes.len() > 0);

// now go back
let new_font = FontFile::new_from_data(Arc::new(bytes));
#[allow(deprecated)]
let new_font = FontFile::new_from_data(Arc::new(bytes.clone()));
assert!(new_font.is_some());

let new_font = FontFile::new_from_buffer(Arc::new(bytes));
assert!(new_font.is_some());

let _new_font = new_font.unwrap();
Expand Down

0 comments on commit 8276985

Please sign in to comment.