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
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
use std::ptr::null_mut;
use {
    ffi,
    Bitmap,
    FtResult,
    Glyph,
    GlyphMetrics,
    Outline,
    RenderMode,
    Vector
};

/// A description of a given subglyph returned by `GlyphSlot::get_subglyph_info`
/// function.
#[derive(Copy, Clone)]
pub struct SubGlyphInfo {
    /// The glyph index of the subglyph.
    pub index: i32,
    /// The subglyph flags, see FT_SUBGLYPH_FLAG_XXX.
    pub flags: u32,
    /// The subglyph's first argument (if any).
    pub arg1: i32,
    /// The subglyph's second argument (if any).
    pub arg2: i32,
    /// The subglyph transformation (if any).
    pub transform: ffi::FT_Matrix
}

impl Default for SubGlyphInfo {
    fn default() -> Self {
        SubGlyphInfo {
            index: 0,
            flags: 0,
            arg1: 0,
            arg2: 0,
            transform: ffi::FT_Matrix { xx: 0, xy: 0, yx: 0, yy: 0 }
        }
    }
}

/// A struct encapsulating the space for a glyph within a `Library`
#[derive(Copy, Clone, Eq, PartialEq, Hash)]
pub struct GlyphSlot {
    library_raw: ffi::FT_Library,
    raw: ffi::FT_GlyphSlot
}

impl GlyphSlot {
    /// Create a `GlyphSlot` from its constituent C parts
    pub unsafe fn from_raw(library_raw: ffi::FT_Library, raw: ffi::FT_GlyphSlot) -> Self {
        GlyphSlot { library_raw, raw }
    }

    /// Convert a given glyph image to a bitmap. It does so by inspecting the glyph image format,
    /// finding the relevant renderer, and invoking it.
    pub fn render_glyph(&self, render_mode: RenderMode) -> FtResult<()> {
        let err = unsafe {
            ffi::FT_Render_Glyph(self.raw, render_mode as u32)
        };
        if err == ffi::FT_Err_Ok {
            Ok(())
        } else {
            Err(err.into())
        }
    }

    /// Retrieve a description of a given subglyph. Only use it if the glyph's format is
    /// FT_GLYPH_FORMAT_COMPOSITE; an error is returned otherwise.
    pub fn get_subglyph_info(&self, sub_index: u32) -> FtResult<SubGlyphInfo> {
        let mut info = SubGlyphInfo::default();
        let err = unsafe {
            ffi::FT_Get_SubGlyph_Info(self.raw, sub_index, &mut info.index, &mut info.flags,
                                      &mut info.arg1, &mut info.arg2, &mut info.transform)
        };
        if err == ffi::FT_Err_Ok {
            Ok(info)
        } else {
            Err(err.into())
        }
    }

    /// Returns a glyph object, that is similar to a `GlyphSlot` but managed outside of the library
    pub fn get_glyph(&self) -> FtResult<Glyph> {
        let mut aglyph = null_mut();

        let err = unsafe {
            ffi::FT_Get_Glyph(self.raw, &mut aglyph)
        };
        if err == ffi::FT_Err_Ok {
            Ok(unsafe { Glyph::from_raw(self.library_raw, aglyph) })
        } else {
            Err(err.into())
        }
    }

    /// In freetype, the `Outline` object is a scalable glyph. This method unpacks a glyph into
    /// this object, or returns `None` if the glyph has no `outline`
    pub fn outline(&self) -> Option<Outline> {
        let outline = unsafe { &(*self.raw).outline };
        let format = unsafe { (*self.raw).format };

        if format == ffi::FT_GLYPH_FORMAT_OUTLINE {
            let outline = unsafe {
                Outline::from_raw(outline)
            };
            Some(outline)
        } else {
            None
        }
    }


    /// This field is used as a bitmap descriptor when the slot format is FT_GLYPH_FORMAT_BITMAP.
    /// Note that the address and content of the bitmap buffer can change between calls of
    /// FT_Load_Glyph and a few other functions.
    #[inline(always)]
    pub fn bitmap(&self) -> Bitmap {
        unsafe { Bitmap::from_raw(&(*self.raw).bitmap) }
    }

    /// The bitmap's left bearing expressed in integer pixels. Only valid if the format is
    /// FT_GLYPH_FORMAT_BITMAP, this is, if the glyph slot contains a bitmap.
    #[inline(always)]
    pub fn bitmap_left(&self) -> i32 {
        unsafe {
            (*self.raw).bitmap_left
        }
    }

    /// The bitmap's top bearing expressed in integer pixels. Remember that this is the distance
    /// from the baseline to the top-most glyph scanline, upwards y coordinates being positive.
    #[inline(always)]
    pub fn bitmap_top(&self) -> i32 {
        unsafe {
            (*self.raw).bitmap_top
        }
    }

    /// This shorthand is, depending on FT_LOAD_IGNORE_TRANSFORM, the transformed (hinted) advance
    /// width for the glyph, in 26.6 fractional pixel format. As specified with
    /// FT_LOAD_VERTICAL_LAYOUT, it uses either the ‘horiAdvance’ or the ‘vertAdvance’ value of
    /// ‘metrics’ field.
    #[inline(always)]
    pub fn advance(&self) -> Vector {
        unsafe {
            (*self.raw).advance
        }
    }

    /// The advance width of the unhinted glyph. Its value is expressed in 16.16 fractional pixels,
    /// unless FT_LOAD_LINEAR_DESIGN is set when loading the glyph. This field can be important to
    /// perform correct WYSIWYG layout. Only relevant for outline glyphs.
    #[inline(always)]
    pub fn linear_hori_advance(&self) -> ffi::FT_Fixed {
        unsafe {
            (*self.raw).linearHoriAdvance
        }
    }

    /// The advance height of the unhinted glyph. Its value is expressed in 16.16 fractional
    /// pixels, unless FT_LOAD_LINEAR_DESIGN is set when loading the glyph. This field can be
    /// important to perform correct WYSIWYG layout. Only relevant for outline glyphs.
    #[inline(always)]
    pub fn linear_vert_advance(&self) -> ffi::FT_Fixed {
        unsafe {
            (*self.raw).linearVertAdvance
        }
    }

    /// The metrics of the last loaded glyph in the slot. The returned values depend on the last
    /// load flags (see the FT_Load_Glyph API function) and can be expressed either in 26.6
    /// fractional pixels or font units.
    #[inline(always)]
    pub fn metrics(&self) -> GlyphMetrics {
        unsafe {
            (*self.raw).metrics
        }
    }

    /// Get a pointer to the underlying c struct
    #[inline(always)]
    pub fn raw(&self) -> &ffi::FT_GlyphSlotRec {
        unsafe {
            &*self.raw
        }
    }
}