1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
use crate::preparse::{FaceSubtables, PreParsedSubtables};
#[cfg(not(feature = "std"))]
use alloc::{boxed::Box, vec::Vec};
use core::{fmt, marker::PhantomPinned, mem, pin::Pin, slice};

/// An owned version of font [`Face`](struct.Face.html).
pub struct OwnedFace(Pin<Box<SelfRefVecFace>>);

impl OwnedFace {
    /// Creates an `OwnedFace` from owned data.
    ///
    /// You can set index for font collections. For simple ttf fonts set index to 0.
    ///
    /// # Example
    /// ```
    /// # use owned_ttf_parser::OwnedFace;
    /// # let owned_font_data = include_bytes!("../fonts/font.ttf").to_vec();
    /// let owned_face = OwnedFace::from_vec(owned_font_data, 0).unwrap();
    /// ```
    // Note: not `try_from_vec` to better mimic `ttf_parser::Face::from_data`.
    pub fn from_vec(data: Vec<u8>, index: u32) -> Result<Self, ttf_parser::FaceParsingError> {
        let inner = SelfRefVecFace::try_from_vec(data, index)?;
        Ok(Self(inner))
    }

    pub(crate) fn pre_parse_subtables(self) -> PreParsedSubtables<'static, Self> {
        // build subtables referencing fake static data
        let subtables = FaceSubtables::from(match self.0.face.as_ref() {
            Some(f) => f,
            None => unsafe { core::hint::unreachable_unchecked() },
        });

        // bundle everything together so self-reference lifetimes hold
        PreParsedSubtables {
            face: self,
            subtables,
        }
    }

    /// Extracts a slice containing the data passed into [`OwnedFace::from_vec`].
    ///
    /// # Example
    /// ```
    /// # use owned_ttf_parser::OwnedFace;
    /// # let owned_font_data = include_bytes!("../fonts/font.ttf").to_vec();
    /// let data_clone = owned_font_data.clone();
    /// let owned_face = OwnedFace::from_vec(owned_font_data, 0).unwrap();
    /// assert_eq!(owned_face.as_slice(), data_clone);
    /// ```
    pub fn as_slice(&self) -> &[u8] {
        &self.0.data
    }

    /// Unwraps the data passed into [`OwnedFace::from_vec`].
    ///
    /// # Example
    /// ```
    /// # use owned_ttf_parser::OwnedFace;
    /// # let owned_font_data = include_bytes!("../fonts/font.ttf").to_vec();
    /// let data_clone = owned_font_data.clone();
    /// let owned_face = OwnedFace::from_vec(owned_font_data, 0).unwrap();
    /// assert_eq!(owned_face.into_vec(), data_clone);
    /// ```
    pub fn into_vec(self) -> Vec<u8> {
        self.0.into_vec()
    }
}

impl fmt::Debug for OwnedFace {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "OwnedFace()")
    }
}

impl crate::convert::AsFaceRef for OwnedFace {
    #[inline]
    fn as_face_ref(&self) -> &ttf_parser::Face<'_> {
        self.0.inner_ref()
    }
}

impl crate::convert::AsFaceRef for &OwnedFace {
    #[inline]
    fn as_face_ref(&self) -> &ttf_parser::Face<'_> {
        self.0.inner_ref()
    }
}

impl crate::convert::FaceMut for OwnedFace {
    fn set_variation(&mut self, axis: ttf_parser::Tag, value: f32) -> Option<()> {
        unsafe {
            let mut_ref = Pin::as_mut(&mut self.0);
            let mut_inner = mut_ref.get_unchecked_mut();
            match mut_inner.face.as_mut() {
                Some(face) => face.set_variation(axis, value),
                None => None,
            }
        }
    }
}
impl crate::convert::FaceMut for &mut OwnedFace {
    #[inline]
    fn set_variation(&mut self, axis: ttf_parser::Tag, value: f32) -> Option<()> {
        (*self).set_variation(axis, value)
    }
}

// Face data in a `Vec` with a self-referencing `Face`.
struct SelfRefVecFace {
    data: Vec<u8>,
    face: Option<ttf_parser::Face<'static>>,
    _pin: PhantomPinned,
}

impl SelfRefVecFace {
    /// Creates an underlying face object from owned data.
    fn try_from_vec(
        data: Vec<u8>,
        index: u32,
    ) -> Result<Pin<Box<Self>>, ttf_parser::FaceParsingError> {
        let face = Self {
            data,
            face: None,
            _pin: PhantomPinned,
        };
        let mut b = Box::pin(face);
        unsafe {
            // 'static lifetime is a lie, this data is owned, it has pseudo-self lifetime.
            let slice: &'static [u8] = slice::from_raw_parts(b.data.as_ptr(), b.data.len());
            let mut_ref: Pin<&mut Self> = Pin::as_mut(&mut b);
            let mut_inner = mut_ref.get_unchecked_mut();
            mut_inner.face = Some(ttf_parser::Face::parse(slice, index)?);
        }
        Ok(b)
    }

    // Must not leak the fake 'static lifetime that we lied about earlier to the
    // compiler. Since the lifetime 'a will not outlive our owned data it's
    // safe to provide Face<'a>
    #[inline]
    #[allow(clippy::needless_lifetimes)] // explicit is nice as it's important 'static isn't leaked
    fn inner_ref<'a>(self: &'a Pin<Box<Self>>) -> &'a ttf_parser::Face<'a> {
        // Safety: if you have a ref `face` is always Some
        unsafe { self.face.as_ref().unwrap_unchecked() }
    }

    fn into_vec(self: Pin<Box<Self>>) -> Vec<u8> {
        // Safety: safe as `face` is dropped.
        let mut me = unsafe { Pin::into_inner_unchecked(self) };
        me.face.take(); // ensure dropped before taking `data`
        mem::take(&mut me.data)
    }
}

impl Drop for SelfRefVecFace {
    fn drop(&mut self) {
        self.face.take(); // ensure dropped before `data`
    }
}