mirror of
https://github.com/servo/servo.git
synced 2025-07-22 23:03:42 +01:00
Add a PNG graphics sink
This commit is contained in:
parent
e57e2bc801
commit
572d505037
2 changed files with 123 additions and 0 deletions
122
src/servo/gfx/pngsink.rs
Normal file
122
src/servo/gfx/pngsink.rs
Normal file
|
@ -0,0 +1,122 @@
|
||||||
|
#[doc = "
|
||||||
|
A graphics sink that renders to PNG format buffers
|
||||||
|
|
||||||
|
Each time the renderer renders a frame the bufsink will output a
|
||||||
|
`[u8]` containing the frame in PNG format.
|
||||||
|
"];
|
||||||
|
|
||||||
|
export msg, pngsink;
|
||||||
|
|
||||||
|
import azure::cairo;
|
||||||
|
import azure_bg = azure::bindgen;
|
||||||
|
import azure::AzDrawTargetRef;
|
||||||
|
import cairo_bg = cairo::bindgen;
|
||||||
|
|
||||||
|
enum msg {
|
||||||
|
begin_drawing(chan<AzDrawTargetRef>),
|
||||||
|
draw(chan<AzDrawTargetRef>, AzDrawTargetRef),
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
|
||||||
|
impl pngsink of renderer::sink for chan<msg> {
|
||||||
|
fn begin_drawing(next_dt: chan<AzDrawTargetRef>) {
|
||||||
|
self.send(begin_drawing(next_dt))
|
||||||
|
}
|
||||||
|
fn draw(next_dt: chan<AzDrawTargetRef>, draw_me: AzDrawTargetRef) {
|
||||||
|
self.send(draw(next_dt, draw_me))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn pngsink(output: chan<[u8]>) -> chan<msg> {
|
||||||
|
task::spawn_listener::<msg> { |po|
|
||||||
|
|
||||||
|
let cairo_surf = cairo_bg::cairo_image_surface_create(
|
||||||
|
cairo::CAIRO_FORMAT_ARGB32, 800 as libc::c_int, 600 as libc::c_int
|
||||||
|
);
|
||||||
|
assert cairo_surf.is_not_null();
|
||||||
|
|
||||||
|
let draw_target = azure_bg::AzCreateDrawTargetForCairoSurface(cairo_surf);
|
||||||
|
assert draw_target.is_not_null();
|
||||||
|
|
||||||
|
loop {
|
||||||
|
alt po.recv() {
|
||||||
|
begin_drawing(sender) {
|
||||||
|
sender.send(draw_target);
|
||||||
|
}
|
||||||
|
draw(sender, dt) {
|
||||||
|
do_draw(sender, dt, output, cairo_surf);
|
||||||
|
}
|
||||||
|
exit { break }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
azure_bg::AzReleaseDrawTarget(draw_target);
|
||||||
|
cairo_bg::cairo_surface_destroy(cairo_surf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn do_draw(sender: chan<AzDrawTargetRef>,
|
||||||
|
dt: AzDrawTargetRef,
|
||||||
|
output: comm::chan<[u8]>,
|
||||||
|
cairo_surf: *cairo::cairo_surface_t) {
|
||||||
|
|
||||||
|
import libc::*;
|
||||||
|
|
||||||
|
listen {|data_ch|
|
||||||
|
|
||||||
|
crust fn write_fn(closure: *c_void,
|
||||||
|
data: *c_uchar,
|
||||||
|
len: c_uint)
|
||||||
|
|
||||||
|
-> cairo::cairo_status_t unsafe {
|
||||||
|
|
||||||
|
let p: *chan<[u8]> = unsafe::reinterpret_cast(closure);
|
||||||
|
let data_ch = *p;
|
||||||
|
|
||||||
|
// Convert from *c_uchar to *u8
|
||||||
|
let data = unsafe::reinterpret_cast(data);
|
||||||
|
let len = len as uint;
|
||||||
|
// Copy to a vector
|
||||||
|
let data = vec::unsafe::from_buf(data, len);
|
||||||
|
data_ch.send(data);
|
||||||
|
|
||||||
|
ret cairo::CAIRO_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
let closure = ptr::addr_of(data_ch);
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
cairo_bg::cairo_surface_write_to_png_stream(
|
||||||
|
cairo_surf, write_fn, unsafe::reinterpret_cast(closure));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Collect the entire image into a single vector
|
||||||
|
let mut result = [];
|
||||||
|
while data_ch.peek() {
|
||||||
|
result += data_ch.recv();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send the PNG image away
|
||||||
|
output.send(result);
|
||||||
|
}
|
||||||
|
// Send the next draw target to the renderer
|
||||||
|
sender.send(dt);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn sanity_check() {
|
||||||
|
|
||||||
|
listen {|ch|
|
||||||
|
|
||||||
|
let sink = pngsink(ch);
|
||||||
|
let renderer = renderer::renderer(sink);
|
||||||
|
|
||||||
|
let dlist = [];
|
||||||
|
renderer.send(renderer::render(dlist));
|
||||||
|
listen {|resp|
|
||||||
|
renderer.send(renderer::exit(resp));
|
||||||
|
resp.recv();
|
||||||
|
}
|
||||||
|
sink.send(exit)
|
||||||
|
}
|
||||||
|
}
|
|
@ -19,6 +19,7 @@ mod gfx {
|
||||||
mod geom;
|
mod geom;
|
||||||
mod surface;
|
mod surface;
|
||||||
mod renderer;
|
mod renderer;
|
||||||
|
mod pngsink;
|
||||||
}
|
}
|
||||||
|
|
||||||
mod image {
|
mod image {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue