-
Notifications
You must be signed in to change notification settings - Fork 65
/
Copy pathbitmap.rs
120 lines (103 loc) · 4.72 KB
/
bitmap.rs
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
use crate::{ffi, Error, FtResult};
use std::slice;
/// An enumeration type used to describe the format of pixels in a given bitmap. Note that
/// additional formats may be added in the future.
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum PixelMode {
/// This value is reserved.
None,
/// A monochrome bitmap, using 1 bit per pixel. Note that pixels are
/// stored in most-significant order (MSB), which means that the left-most
/// pixel in a byte has value 128.
Mono,
/// An 8-bit bitmap, generally used to represent anti-aliased glyph images.
/// Each pixel is stored in one byte. Note that the number of `gray`
/// levels is stored in the `num_grays` field of the FT_Bitmap structure
/// (it generally is 256).
Gray,
/// A 2-bit per pixel bitmap, used to represent embedded anti-aliased
/// bitmaps in font files according to the OpenType specification. We
/// haven't found a single font using this format, however.
Gray2,
/// A 4-bit per pixel bitmap, representing embedded anti-aliased bitmaps in
/// font files according to the OpenType specification. We haven't found a
/// single font using this format, however.
Gray4,
/// An 8-bit bitmap, representing RGB or BGR decimated glyph images used
/// for display on LCD displays; the bitmap is three times wider than the
/// original glyph image. See also FT_RENDER_MODE_LCD.
Lcd,
/// An 8-bit bitmap, representing RGB or BGR decimated glyph images used for
/// display on rotated LCD displays; the bitmap is three times taller than
/// the original glyph image. See also FT_RENDER_MODE_LCD_V.
LcdV,
/// An image with four 8-bit channels per pixel, representing a color image
/// (such as emoticons) with alpha channel. For each pixel, the format is
/// BGRA, which means, the blue channel comes first in memory. The color
/// channels are pre-multiplied and in the sRGB colorspace. For example,
/// full red at half-translucent opacity will be represented as
/// `00,00,80,80`, not `00,00,FF,80`. See also FT_LOAD_COLOR.
Bgra,
}
#[allow(missing_copy_implementations)]
pub struct Bitmap {
raw: *const ffi::FT_Bitmap,
}
impl Bitmap {
pub unsafe fn from_raw(raw: *const ffi::FT_Bitmap) -> Self {
Bitmap { raw }
}
/// A typeless pointer to the bitmap buffer. This value should be aligned
/// on 32-bit boundaries in most cases.
pub fn buffer(&self) -> &[u8] {
let buffer_size = (self.pitch().abs() * self.rows()) as usize;
if buffer_size > 0 {
unsafe { slice::from_raw_parts((*self.raw).buffer, buffer_size) }
} else {
// When buffer_size is 0, the buffer pointer will be null.
&[]
}
}
/// The number of pixels in bitmap row.
pub fn width(&self) -> i32 {
unsafe { (*self.raw).width }
}
/// The number of bitmap rows.
pub fn rows(&self) -> i32 {
unsafe { (*self.raw).rows }
}
pub fn raw(&self) -> &ffi::FT_Bitmap {
unsafe { &*self.raw }
}
/// The pixel mode, i.e., how pixel bits are stored. See `PixelMode` for
/// possible values.
pub fn pixel_mode(&self) -> FtResult<PixelMode> {
let pixel_mode = unsafe { (*self.raw).pixel_mode } as u32;
Ok(match pixel_mode {
ffi::FT_PIXEL_MODE_NONE => PixelMode::None,
ffi::FT_PIXEL_MODE_MONO => PixelMode::Mono,
ffi::FT_PIXEL_MODE_GRAY => PixelMode::Gray,
ffi::FT_PIXEL_MODE_GRAY2 => PixelMode::Gray2,
ffi::FT_PIXEL_MODE_GRAY4 => PixelMode::Gray4,
ffi::FT_PIXEL_MODE_LCD => PixelMode::Lcd,
ffi::FT_PIXEL_MODE_LCD_V => PixelMode::LcdV,
ffi::FT_PIXEL_MODE_BGRA => PixelMode::Bgra,
_ => return Err(Error::UnexpectedPixelMode),
})
}
/// The pitch's absolute value is the number of bytes taken by one bitmap row, including
/// padding. However, the pitch is positive when the bitmap has a ‘down’ flow, and negative
/// when it has an ‘up’ flow. In all cases, the pitch is an offset to add to a bitmap pointer
/// in order to go down one row.
///
/// Note that ‘padding’ means the alignment of a bitmap to a byte border, and FreeType
/// functions normally align to the smallest possible integer value.
/// For the B/W rasterizer, ‘pitch’ is always an even number.
///
/// To change the pitch of a bitmap (say, to make it a multiple of 4), use FT_Bitmap_Convert.
/// Alternatively, you might use callback functions to directly render to the application's
/// surface; see the file ‘example2.cpp’ in the tutorial for a demonstration.
pub fn pitch(&self) -> i32 {
unsafe { (*self.raw).pitch }
}
}