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
use std::marker::PhantomData;
use cairo::{Context, Format, ImageSurface};
use piet::{ErrorKind, ImageFormat};
#[doc(hidden)]
pub use piet_cairo::*;
pub type Piet<'a> = CairoRenderContext<'a>;
pub type Brush = piet_cairo::Brush;
pub type PietText<'a> = CairoText;
pub type PietFont = CairoFont;
pub type PietFontBuilder<'a> = CairoFontBuilder;
pub type PietTextLayout = CairoTextLayout;
pub type PietTextLayoutBuilder<'a> = CairoTextLayoutBuilder;
pub type Image = ImageSurface;
pub struct Device;
pub struct BitmapTarget<'a> {
surface: ImageSurface,
cr: Context,
phantom: PhantomData<&'a ()>,
}
impl Device {
pub fn new() -> Result<Device, piet::Error> {
Ok(Device)
}
pub fn bitmap_target(
&self,
width: usize,
height: usize,
pix_scale: f64,
) -> Result<BitmapTarget, piet::Error> {
let surface = ImageSurface::create(Format::ARgb32, width as i32, height as i32).unwrap();
let cr = Context::new(&surface);
cr.scale(pix_scale, pix_scale);
let phantom = Default::default();
Ok(BitmapTarget {
surface,
cr,
phantom,
})
}
}
impl<'a> BitmapTarget<'a> {
pub fn render_context<'b>(&'b mut self) -> CairoRenderContext<'b> {
CairoRenderContext::new(&mut self.cr)
}
pub fn into_raw_pixels(mut self, fmt: ImageFormat) -> Result<Vec<u8>, piet::Error> {
if fmt != ImageFormat::RgbaPremul {
return Err(piet::new_error(ErrorKind::NotSupported));
}
std::mem::drop(self.cr);
self.surface.flush();
let stride = self.surface.get_stride() as usize;
let width = self.surface.get_width() as usize;
let height = self.surface.get_height() as usize;
let mut raw_data = vec![0; width * height * 4];
let buf = self
.surface
.get_data()
.map_err(|e| Into::<Box<dyn std::error::Error>>::into(e))?;
for y in 0..height {
let src_off = y * stride;
let dst_off = y * width * 4;
for x in 0..width {
raw_data[dst_off + x * 4 + 0] = buf[src_off + x * 4 + 2];
raw_data[dst_off + x * 4 + 1] = buf[src_off + x * 4 + 1];
raw_data[dst_off + x * 4 + 2] = buf[src_off + x * 4 + 0];
raw_data[dst_off + x * 4 + 3] = buf[src_off + x * 4 + 3];
}
}
Ok(raw_data)
}
}