servo: Render to PNG file when using -o flag

Source-Repo: https://github.com/servo/servo
Source-Revision: 7a8305dc163b1934df948aa252cbc99e69315f2f
This commit is contained in:
Brian Anderson 2012-05-05 16:32:11 -07:00
Родитель abe5f6e82a
Коммит 22fa953010
5 изменённых файлов: 98 добавлений и 27 удалений

36
servo/src/servo/engine.rs Normal file
Просмотреть файл

@ -0,0 +1,36 @@
import gfx::renderer;
enum msg {
load_url(str),
exit(comm::chan<()>)
}
fn engine<S: renderer::sink send>(sink: S) -> comm::chan<msg> {
task::spawn_listener::<msg> {|self_ch|
// The renderer
let renderer = renderer::renderer(sink);
// The layout task
let layout = layout::layout::layout(renderer);
// The content task
let content = content::content(layout);
loop {
alt self_ch.recv() {
load_url(url) { content.send(content::parse(url)) }
exit(sender) {
content.send(content::exit);
layout.send(layout::layout::exit);
listen {|resp_ch|
renderer.send(renderer::exit(resp_ch));
resp_ch.recv();
}
sender.send(());
break;
}
}
}
}
}

Просмотреть файл

@ -41,9 +41,11 @@ fn pngsink(output: chan<[u8]>) -> chan<msg> {
loop {
alt po.recv() {
begin_drawing(sender) {
#debug("pngsink: begin_drawing");
sender.send(draw_target);
}
draw(sender, dt) {
#debug("pngsink: draw");
do_draw(sender, dt, output, cairo_surf);
}
exit { break }

Просмотреть файл

@ -12,7 +12,7 @@ type opts = {
enum render_mode {
screen,
file(str)
png(str)
}
fn from_cmdline_args(args: [str]) -> opts {
@ -36,7 +36,7 @@ fn from_cmdline_args(args: [str]) -> opts {
};
let render_mode = alt getopts::opt_maybe_str(match, "o") {
some(output_file) { file(output_file) }
some(output_file) { png(output_file) }
none { screen }
};

Просмотреть файл

@ -50,3 +50,4 @@ mod util {
mod content;
mod opts;
mod engine;

Просмотреть файл

@ -11,41 +11,73 @@ fn main(args: [str]) {
fn run(opts: opts::opts) {
alt opts.render_mode {
opts::screen {
run_pipeline_screen(opts.urls)
}
opts::png(outfile) {
assert opts.urls.is_not_empty();
if opts.urls.len() > 1u {
fail "servo asks that you stick to a single URL in PNG output mode"
}
run_pipeline_png(opts.urls.head(), outfile)
}
}
}
fn run_pipeline_screen(urls: [str]) {
// Use the platform thread as the renderer sink
import osmain::gfxsink;
// The platform event handler thread
let osmain = osmain::osmain();
// The renderer
let renderer = {
// Use the platform thread as the renderer sink
import osmain::gfxsink;
renderer::renderer(osmain)
};
// The layout task
let layout = layout::layout::layout(renderer);
// The content task
let content = content::content(layout);
// Create a serve instance
let engine = engine::engine(osmain);
// Send each file to render then wait for keypress
for opts.urls.each { |filename|
#debug["master: Sending filename `%s`", filename];
content.send(content::parse(filename));
#debug["master: Waiting for keypress"];
listen {|key_ch|
osmain.send(platform::osmain::add_key_handler(key_ch));
for urls.each { |filename|
#debug["master: Sending filename `%s`", filename];
engine.send(engine::load_url(filename));
#debug["master: Waiting for keypress"];
key_ch.recv();
}
}
// Shut everything down
#debug["master: Shut down"];
content.send(content::exit);
layout.send(layout::layout::exit);
listen {|wait_ch|
renderer.send(gfx::renderer::exit(wait_ch));
wait_ch.recv();
listen {|resp_ch|
engine.send(engine::exit(resp_ch));
resp_ch.recv();
}
osmain.send(platform::osmain::exit);
}
fn run_pipeline_png(url: str, outfile: str) {
// Use a PNG encoder as the graphics sink
import gfx::pngsink;
import pngsink::pngsink;
listen {|pngdata|
let sink = pngsink::pngsink(pngdata);
let engine = engine::engine(sink);
engine.send(engine::load_url(url));
alt io::buffered_file_writer(outfile) {
result::ok(writer) {
import io::writer;
writer.write(pngdata.recv())
}
result::err(e) { fail e }
}
listen {|resp_ch|
engine.send(engine::exit(resp_ch));
resp_ch.recv();
}
sink.send(pngsink::exit);
}
}