font_info/
vmo_stream.rs
1#![cfg(target_os = "fuchsia")]
6
7use crate::sources::FTStreamProvider;
8use anyhow::Error;
9use freetype_ffi::{FT_Stream, FT_StreamRec};
10
11use libc::{c_uchar, c_ulong, c_void};
12use std::{cmp, ptr, slice};
13
14struct VmoStreamInternal {
15 vmo: zx::Vmo,
16 stream_rec: FT_StreamRec,
17}
18
19impl VmoStreamInternal {
20 unsafe fn ft_stream(&self) -> FT_Stream {
22 &self.stream_rec as FT_Stream
23 }
24
25 fn read(&mut self, offset: u64, read_buffer: &mut [u8]) -> u64 {
26 if read_buffer.len() == 0 || offset >= self.stream_rec.size as u64 {
27 return 0;
28 }
29 let read_size = cmp::min(read_buffer.len(), (self.stream_rec.size - offset) as usize);
30 match self.vmo.read(&mut read_buffer[..read_size], offset) {
31 Ok(_) => read_size as u64,
32 Err(err) => {
33 println!("Error when reading from font VMO: {:?}", err);
34 0
35 }
36 }
37 }
38
39 unsafe extern "C" fn read_func(
41 stream: FT_Stream,
42 offset: c_ulong,
43 buffer: *mut c_uchar,
44 count: c_ulong,
45 ) -> c_ulong {
46 let wrapper = &mut *((*stream).descriptor as *mut VmoStreamInternal);
47 if buffer.is_null() || count == 0 {
48 return 0;
49 }
50 let buffer_slice = slice::from_raw_parts_mut(buffer as *mut u8, count as usize);
51 wrapper.read(offset as u64, buffer_slice) as c_ulong
52 }
53
54 extern "C" fn close_func(_stream: FT_Stream) {
55 }
57}
58
59pub(crate) struct VmoStream {
61 internal: Box<VmoStreamInternal>,
64}
65
66impl VmoStream {
67 pub fn new(vmo: zx::Vmo, vmo_size: usize) -> Result<VmoStream, Error> {
68 let mut internal = Box::new(VmoStreamInternal {
69 vmo,
70 stream_rec: FT_StreamRec {
71 base: ptr::null(),
72 size: vmo_size as c_ulong,
73 pos: 0,
74
75 descriptor: ptr::null_mut(),
76 pathname: ptr::null_mut(),
77 read: VmoStreamInternal::read_func,
78 close: VmoStreamInternal::close_func,
79
80 memory: ptr::null_mut(),
81 cursor: ptr::null_mut(),
82 limit: ptr::null_mut(),
83 },
84 });
85
86 internal.stream_rec.descriptor = &mut *internal as *mut VmoStreamInternal as *mut c_void;
87
88 Ok(VmoStream { internal })
89 }
90
91 pub unsafe fn ft_stream(&self) -> FT_Stream {
94 self.internal.ft_stream()
95 }
96}
97
98impl FTStreamProvider for VmoStream {
99 unsafe fn ft_stream(&self) -> FT_Stream {
102 VmoStream::ft_stream(self)
103 }
104}