Make servo build again

This commit is contained in:
Brian Anderson 2012-12-04 12:23:32 -08:00
parent 557de81c87
commit 3cf9b0f2b0
52 changed files with 376 additions and 317 deletions

@ -1 +1 @@
Subproject commit f1670147011cee03a94c751d6d77a30c2330ee4d Subproject commit 461dcedfb36240f3c82f1d193f8cb42c9528fe34

View file

@ -1,7 +1,7 @@
use azure::azure_hl::{DrawTarget}; use azure::azure_hl::{DrawTarget};
use geom::rect::Rect; use geom::rect::Rect;
struct LayerBuffer { pub struct LayerBuffer {
draw_target: DrawTarget, draw_target: DrawTarget,
// The rect in the containing RenderLayer that this represents. // The rect in the containing RenderLayer that this represents.
@ -13,7 +13,7 @@ struct LayerBuffer {
/// A set of layer buffers. This is an atomic unit used to switch between the front and back /// A set of layer buffers. This is an atomic unit used to switch between the front and back
/// buffers. /// buffers.
struct LayerBufferSet { pub struct LayerBufferSet {
buffers: ~[LayerBuffer] buffers: ~[LayerBuffer]
} }
@ -21,7 +21,7 @@ struct LayerBufferSet {
The interface used to by the renderer to aquire draw targets for The interface used to by the renderer to aquire draw targets for
each rendered frame and submit them to be drawn to the display each rendered frame and submit them to be drawn to the display
*/ */
trait Compositor { pub trait Compositor {
fn begin_drawing(next_dt: pipes::Chan<LayerBufferSet>); fn begin_drawing(next_dt: pipes::Chan<LayerBufferSet>);
fn draw(next_dt: pipes::Chan<LayerBufferSet>, +draw_me: LayerBufferSet); fn draw(next_dt: pipes::Chan<LayerBufferSet>, +draw_me: LayerBufferSet);
} }

View file

@ -95,7 +95,7 @@ trait DisplayListMethods {
fn draw_into_context(ctx: &RenderContext); fn draw_into_context(ctx: &RenderContext);
} }
impl DisplayList { pub impl DisplayList {
static fn new() -> DisplayList { static fn new() -> DisplayList {
DisplayList { list: ~[] } DisplayList { list: ~[] }
} }

View file

@ -43,7 +43,7 @@ pub trait FontHandleMethods {
// //
// `new` should be part of trait FontHandleMethods. // `new` should be part of trait FontHandleMethods.
impl FontHandle { pub impl FontHandle {
#[cfg(target_os = "macos")] #[cfg(target_os = "macos")]
static pub fn new_from_buffer(fctx: &native::FontContextHandle, buf: ~[u8], style: &SpecifiedFontStyle) -> Result<FontHandle, ()> { static pub fn new_from_buffer(fctx: &native::FontContextHandle, buf: ~[u8], style: &SpecifiedFontStyle) -> Result<FontHandle, ()> {
quartz::font::QuartzFontHandle::new_from_buffer(fctx, move buf, style) quartz::font::QuartzFontHandle::new_from_buffer(fctx, move buf, style)
@ -56,7 +56,7 @@ impl FontHandle {
} }
// Used to abstract over the shaper's choice of fixed int representation. // Used to abstract over the shaper's choice of fixed int representation.
type FractionalPixel = float; pub type FractionalPixel = float;
pub type FontTableTag = u32; pub type FontTableTag = u32;
@ -80,11 +80,11 @@ pub type FontTable/& = quartz::font::QuartzFontTable;
#[cfg(target_os = "linux")] #[cfg(target_os = "linux")]
pub type FontTable/& = freetype::font::FreeTypeFontTable; pub type FontTable/& = freetype::font::FreeTypeFontTable;
trait FontTableMethods { pub trait FontTableMethods {
fn with_buffer(fn&(*u8, uint)); fn with_buffer(fn&(*u8, uint));
} }
struct FontMetrics { pub struct FontMetrics {
underline_size: Au, underline_size: Au,
underline_offset: Au, underline_offset: Au,
leading: Au, leading: Au,
@ -96,7 +96,7 @@ struct FontMetrics {
} }
// TODO(Issue #200): use enum from CSS bindings for 'font-weight' // TODO(Issue #200): use enum from CSS bindings for 'font-weight'
enum CSSFontWeight { pub enum CSSFontWeight {
FontWeight100, FontWeight100,
FontWeight200, FontWeight200,
FontWeight300, FontWeight300,
@ -239,7 +239,7 @@ pub impl FontGroup {
} }
} }
struct RunMetrics { pub struct RunMetrics {
// may be negative due to negative width (i.e., kerning of '.' in 'P.T.') // may be negative due to negative width (i.e., kerning of '.' in 'P.T.')
advance_width: Au, advance_width: Au,
ascent: Au, // nonzero ascent: Au, // nonzero
@ -262,7 +262,7 @@ pub struct Font {
backend: BackendType, backend: BackendType,
} }
impl Font { pub impl Font {
static fn new_from_buffer(ctx: &FontContext, buffer: ~[u8], static fn new_from_buffer(ctx: &FontContext, buffer: ~[u8],
style: &SpecifiedFontStyle, backend: BackendType) -> Result<@Font, ()> { style: &SpecifiedFontStyle, backend: BackendType) -> Result<@Font, ()> {
@ -395,7 +395,7 @@ pub impl Font : FontMethods {
use azure::{AzDrawOptions, use azure::{AzDrawOptions,
AzGlyph, AzGlyph,
AzGlyphBuffer}; AzGlyphBuffer};
use azure::bindgen::{AzCreateColorPattern, use azure::azure::bindgen::{AzCreateColorPattern,
AzDrawTargetFillGlyphs, AzDrawTargetFillGlyphs,
AzReleaseColorPattern}; AzReleaseColorPattern};

View file

@ -36,7 +36,7 @@ type FontContextHandle/& = quartz::font_context::QuartzFontContextHandle;
#[cfg(target_os = "linux")] #[cfg(target_os = "linux")]
type FontContextHandle/& = freetype::font_context::FreeTypeFontContextHandle; type FontContextHandle/& = freetype::font_context::FreeTypeFontContextHandle;
trait FontContextHandleMethods { pub trait FontContextHandleMethods {
pure fn clone(&const self) -> FontContextHandle; pure fn clone(&const self) -> FontContextHandle;
fn create_font_from_identifier(~str, UsedFontStyle) -> Result<FontHandle, ()>; fn create_font_from_identifier(~str, UsedFontStyle) -> Result<FontHandle, ()>;
} }

View file

@ -22,7 +22,7 @@ pub impl FontListHandle {
} }
} }
type FontFamilyMap = linear::LinearMap<~str, @FontFamily>; pub type FontFamilyMap = linear::LinearMap<~str, @FontFamily>;
trait FontListHandleMethods { trait FontListHandleMethods {
fn get_available_families(&const self, fctx: &native::FontContextHandle) -> FontFamilyMap; fn get_available_families(&const self, fctx: &native::FontContextHandle) -> FontFamilyMap;
@ -132,7 +132,7 @@ pub impl FontFamily {
// In the common case, each FontFamily will have a singleton FontEntry, or // In the common case, each FontFamily will have a singleton FontEntry, or
// it will have the standard four faces: Normal, Bold, Italic, BoldItalic. // it will have the standard four faces: Normal, Bold, Italic, BoldItalic.
struct FontEntry { pub struct FontEntry {
family: @FontFamily, family: @FontFamily,
face_name: ~str, face_name: ~str,
priv weight: CSSFontWeight, priv weight: CSSFontWeight,
@ -141,7 +141,7 @@ struct FontEntry {
// TODO: array of OpenType features, etc. // TODO: array of OpenType features, etc.
} }
impl FontEntry { pub impl FontEntry {
static fn new(family: @FontFamily, handle: FontHandle) -> FontEntry { static fn new(family: @FontFamily, handle: FontHandle) -> FontEntry {
FontEntry { FontEntry {
family: family, family: family,

View file

@ -5,7 +5,7 @@ use fc = fontconfig;
use ft = freetype; use ft = freetype;
use gfx_font::FontHandle; use gfx_font::FontHandle;
use gfx_font_list::{FontEntry, FontFamily}; use gfx_font_list::{FontEntry, FontFamily, FontFamilyMap};
use core::dvec::DVec; use core::dvec::DVec;
use core::send_map::{linear, SendMap}; use core::send_map::{linear, SendMap};
@ -19,9 +19,11 @@ pub impl FontconfigFontListHandle {
FontconfigFontListHandle { fctx: () } FontconfigFontListHandle { fctx: () }
} }
fn get_available_families(&const self, fn get_available_families() -> FontFamilyMap {
_fctx: &native::FontContextHandle)
-> linear::LinearMap<~str, @FontFamily> {
fail; fail;
} }
fn load_variations_for_family(family: @FontFamily) {
fail
}
} }

View file

@ -6,6 +6,8 @@ use gfx_font::{
FontHandle, FontHandle,
FontHandleMethods, FontHandleMethods,
FontMetrics, FontMetrics,
FontTable,
FontTableMethods,
FontTableTag, FontTableTag,
FractionalPixel, FractionalPixel,
SpecifiedFontStyle, SpecifiedFontStyle,
@ -15,7 +17,7 @@ use geometry::Au;
use text::glyph::GlyphIndex; use text::glyph::GlyphIndex;
use text::util::{float_to_fixed, fixed_to_float}; use text::util::{float_to_fixed, fixed_to_float};
use freetype::{ use freetype::freetype::{
FTErrorMethods, FTErrorMethods,
FT_Error, FT_Error,
FT_F26Dot6, FT_F26Dot6,
@ -30,7 +32,7 @@ use freetype::{
FT_UInt, FT_UInt,
FT_Size_Metrics, FT_Size_Metrics,
}; };
use freetype::bindgen::{ use freetype::freetype::bindgen::{
FT_Init_FreeType, FT_Init_FreeType,
FT_Done_FreeType, FT_Done_FreeType,
FT_New_Memory_Face, FT_New_Memory_Face,
@ -48,6 +50,16 @@ fn fixed_to_float_ft(f: i32) -> float {
fixed_to_float(6, f) fixed_to_float(6, f)
} }
pub struct FreeTypeFontTable {
bogus: ()
}
pub impl FreeTypeFontTable : FontTableMethods {
fn with_buffer(blk: fn&(*u8, uint)) {
fail
}
}
pub struct FreeTypeFontHandle { pub struct FreeTypeFontHandle {
// The font binary. This must stay valid for the lifetime of the font, // The font binary. This must stay valid for the lifetime of the font,
// if the font is created using FT_Memory_Face. // if the font is created using FT_Memory_Face.
@ -184,7 +196,7 @@ pub impl FreeTypeFontHandle : FontHandleMethods {
} }
} }
fn get_table_for_tag(_tag: FontTableTag) -> Option<~[u8]> { fn get_table_for_tag(_tag: FontTableTag) -> Option<FontTable> {
fail; fail;
} }
} }

View file

@ -1,11 +1,11 @@
extern mod freetype; extern mod freetype;
use freetype::{ use freetype::freetype::{
FTErrorMethods, FTErrorMethods,
FT_Error, FT_Error,
FT_Library, FT_Library,
}; };
use freetype::bindgen::{ use freetype::freetype::bindgen::{
FT_Init_FreeType, FT_Init_FreeType,
FT_Done_FreeType FT_Done_FreeType
}; };
@ -38,6 +38,10 @@ pub impl FreeTypeFontContextHandle {
} }
pub impl FreeTypeFontContextHandle : FontContextHandleMethods { pub impl FreeTypeFontContextHandle : FontContextHandleMethods {
pure fn clone(&const self) -> FreeTypeFontContextHandle {
fail
}
fn create_font_from_identifier(_identifier: ~str, _style: UsedFontStyle) fn create_font_from_identifier(_identifier: ~str, _style: UsedFontStyle)
-> Result<FontHandle, ()> { -> Result<FontHandle, ()> {

View file

@ -41,12 +41,12 @@ pub fn from_cmdline_args(args: &[~str]) -> Opts {
copy opt_match.free copy opt_match.free
}; };
let render_mode = match getopts::opt_maybe_str(copy opt_match, ~"o") { let render_mode = match getopts::opt_maybe_str(&opt_match, ~"o") {
Some(move output_file) => { Png(move output_file) } Some(move output_file) => { Png(move output_file) }
None => { Screen } None => { Screen }
}; };
let render_backend = match getopts::opt_maybe_str(copy opt_match, ~"r") { let render_backend = match getopts::opt_maybe_str(&opt_match, ~"r") {
Some(move backend_str) => { Some(move backend_str) => {
if backend_str == ~"direct2d" { if backend_str == ~"direct2d" {
Direct2DBackend Direct2DBackend
@ -65,12 +65,12 @@ pub fn from_cmdline_args(args: &[~str]) -> Opts {
None => CairoBackend None => CairoBackend
}; };
let tile_size: uint = match getopts::opt_maybe_str(copy opt_match, ~"s") { let tile_size: uint = match getopts::opt_maybe_str(&opt_match, ~"s") {
Some(move tile_size_str) => from_str::from_str(tile_size_str).get(), Some(move tile_size_str) => from_str::from_str(tile_size_str).get(),
None => 512, None => 512,
}; };
let n_render_threads: uint = match getopts::opt_maybe_str(move opt_match, ~"t") { let n_render_threads: uint = match getopts::opt_maybe_str(&opt_match, ~"t") {
Some(move n_render_threads_str) => from_str::from_str(n_render_threads_str).get(), Some(move n_render_threads_str) => from_str::from_str(n_render_threads_str).get(),
None => 1, // FIXME: Number of cores. None => 1, // FIXME: Number of cores.
}; };

View file

@ -16,7 +16,7 @@ use geom::rect::Rect;
use geom::size::Size2D; use geom::size::Size2D;
use std::arc::ARC; use std::arc::ARC;
struct RenderContext { pub struct RenderContext {
canvas: &LayerBuffer, canvas: &LayerBuffer,
font_ctx: @FontContext, font_ctx: @FontContext,
opts: &Opts opts: &Opts

View file

@ -106,7 +106,7 @@ impl<C: Compositor Send> Renderer<C> {
let layer_buffer_set_cell = Cell(move layer_buffer_set); let layer_buffer_set_cell = Cell(move layer_buffer_set);
let layer_buffer_set_channel_cell = Cell(move layer_buffer_set_channel); let layer_buffer_set_channel_cell = Cell(move layer_buffer_set_channel);
#debug("renderer: rendering"); debug!("renderer: rendering");
do util::time::time(~"rendering") { do util::time::time(~"rendering") {
let layer_buffer_set = layer_buffer_set_cell.take(); let layer_buffer_set = layer_buffer_set_cell.take();
@ -150,7 +150,7 @@ impl<C: Compositor Send> Renderer<C> {
} }
}; };
#debug("renderer: returning surface"); debug!("renderer: returning surface");
self.compositor.draw(move layer_buffer_set_channel, move layer_buffer_set); self.compositor.draw(move layer_buffer_set_channel, move layer_buffer_set);
} }
} }

View file

@ -10,7 +10,7 @@ pub fn factory(url: Url, progress_chan: Chan<ProgressMsg>) {
assert url.scheme == ~"http"; assert url.scheme == ~"http";
do spawn |move url| { do spawn |move url| {
#debug("http_loader: requesting via http: %?", copy url); debug!("http_loader: requesting via http: %?", copy url);
let request = uv_http_request(copy url); let request = uv_http_request(copy url);
let errored = @mut false; let errored = @mut false;
do request.begin |event, copy url| { do request.begin |event, copy url| {
@ -18,13 +18,13 @@ pub fn factory(url: Url, progress_chan: Chan<ProgressMsg>) {
match event { match event {
http_client::Status(*) => { } http_client::Status(*) => { }
http_client::Payload(data) => { http_client::Payload(data) => {
#debug("http_loader: got data from %?", url); debug!("http_loader: got data from %?", url);
let mut junk = None; let mut junk = None;
*data <-> junk; *data <-> junk;
progress_chan.send(Payload(option::unwrap(move junk))); progress_chan.send(Payload(option::unwrap(move junk)));
} }
http_client::Error(*) => { http_client::Error(*) => {
#debug("http_loader: error loading %?", url); debug!("http_loader: error loading %?", url);
*errored = true; *errored = true;
progress_chan.send(Done(Err(()))); progress_chan.send(Done(Err(())));
} }

View file

@ -178,7 +178,7 @@ impl ImageCache {
for msg_handlers.each |handler| { (*handler)(&msg) } for msg_handlers.each |handler| { (*handler)(&msg) }
#debug("image_cache_task: received: %?", msg); debug!("image_cache_task: received: %?", msg);
match move msg { match move msg {
Prefetch(move url) => self.prefetch(move url), Prefetch(move url) => self.prefetch(move url),
@ -249,7 +249,7 @@ impl ImageCache {
do spawn |move to_cache, move url_cell| { do spawn |move to_cache, move url_cell| {
let url = url_cell.take(); let url = url_cell.take();
#debug("image_cache_task: started fetch for %s", url.to_str()); debug!("image_cache_task: started fetch for %s", url.to_str());
let image = load_image_data(copy url, resource_task); let image = load_image_data(copy url, resource_task);
@ -259,7 +259,7 @@ impl ImageCache {
Err(()) Err(())
}; };
to_cache.send(StorePrefetchedImageData(copy url, move result)); to_cache.send(StorePrefetchedImageData(copy url, move result));
#debug("image_cache_task: ended fetch for %s", (copy url).to_str()); debug!("image_cache_task: ended fetch for %s", (copy url).to_str());
} }
self.set_state(move url, Prefetching(DoNotDecode)); self.set_state(move url, Prefetching(DoNotDecode));
@ -327,7 +327,7 @@ impl ImageCache {
do spawn |move url_cell, move decode, move data, move to_cache| { do spawn |move url_cell, move decode, move data, move to_cache| {
let url = url_cell.take(); let url = url_cell.take();
#debug("image_cache_task: started image decode for %s", url.to_str()); debug!("image_cache_task: started image decode for %s", url.to_str());
let image = decode(data); let image = decode(data);
let image = if image.is_some() { let image = if image.is_some() {
Some(ARC(~option::unwrap(move image))) Some(ARC(~option::unwrap(move image)))
@ -335,7 +335,7 @@ impl ImageCache {
None None
}; };
to_cache.send(StoreImage(copy url, move image)); to_cache.send(StoreImage(copy url, move image));
#debug("image_cache_task: ended image decode for %s", url.to_str()); debug!("image_cache_task: ended image decode for %s", url.to_str());
} }
self.set_state(move url, Decoding); self.set_state(move url, Decoding);

View file

@ -100,11 +100,11 @@ impl ResourceManager {
match self.get_loader_factory(&url) { match self.get_loader_factory(&url) {
Some(loader_factory) => { Some(loader_factory) => {
#debug("resource_task: loading url: %s", to_str(copy url)); debug!("resource_task: loading url: %s", to_str(copy url));
loader_factory(move url, progress_chan); loader_factory(move url, progress_chan);
} }
None => { None => {
#debug("resource_task: no loader for scheme %s", url.scheme); debug!("resource_task: no loader for scheme %s", url.scheme);
progress_chan.send(Done(Err(()))); progress_chan.send(Done(Err(())));
} }
} }

View file

@ -36,58 +36,68 @@ pub mod native;
#[cfg(target_os = "macos")] #[cfg(target_os = "macos")]
pub mod quartz { pub mod quartz {
#[path = "quartz/font.rs"]
pub mod font; pub mod font;
#[path = "quartz/font_context.rs"]
pub mod font_context; pub mod font_context;
#[path = "quartz/font_list.rs"]
pub mod font_list; pub mod font_list;
} }
#[cfg(target_os = "linux")] #[cfg(target_os = "linux")]
pub mod freetype { pub mod freetype {
#[path = "freetype/font.rs"]
pub mod font; pub mod font;
#[path = "freetype/font_context.rs"]
pub mod font_context; pub mod font_context;
} }
#[cfg(target_os = "linux")] #[cfg(target_os = "linux")]
pub mod fontconfig { pub mod fontconfig {
#[path = "fontconfig/font_list.rs"]
pub mod font_list; pub mod font_list;
} }
// Images // Images
pub mod image { pub mod image {
#[path = "image/base.rs"]
pub mod base; pub mod base;
pub mod encode { pub mod encode {
#[path = "image/encode/tga.rs"]
pub mod tga; pub mod tga;
} }
#[path = "image/holder.rs"]
pub mod holder; pub mod holder;
} }
// Text // Text
pub mod text { #[path = "text/mod.rs"]
pub mod glyph; pub mod text;
pub mod text_run;
pub mod util;
pub mod shaper;
// Below are the actual platform-specific parts.
pub mod harfbuzz {
pub mod shaper;
}
}
// FIXME: Blech. This does not belong in the GFX module. // FIXME: Blech. This does not belong in the GFX module.
pub mod resource { pub mod resource {
#[path = "resource/file_loader.rs"]
pub mod file_loader; pub mod file_loader;
#[path = "resource/http_loader.rs"]
pub mod http_loader; pub mod http_loader;
#[path = "resource/image_cache_task.rs"]
pub mod image_cache_task; pub mod image_cache_task;
#[path = "resource/local_image_cache.rs"]
pub mod local_image_cache; pub mod local_image_cache;
#[path = "resource/resource_task.rs"]
pub mod resource_task; pub mod resource_task;
} }
pub mod util { pub mod util {
#[path = "util/cache.rs"]
pub mod cache; pub mod cache;
#[path = "util/range.rs"]
pub mod range; pub mod range;
#[path = "util/time.rs"]
pub mod time; pub mod time;
#[path = "util/url.rs"]
pub mod url; pub mod url;
#[path = "util/vec.rs"]
pub mod vec; pub mod vec;
} }
@ -95,3 +105,7 @@ use servo_util = util;
use gfx_font = font; use gfx_font = font;
use gfx_font_context = font_context; use gfx_font_context = font_context;
use gfx_font_list = font_list; use gfx_font_list = font_list;
pub use servo_gfx_font = font;
pub use servo_gfx_font_list = font_list;
pub use servo_gfx_util = util;

View file

@ -1,5 +0,0 @@
// FIXME: Blech. We need crate-relative imports.
pub use servo_gfx_font = font;
pub use servo_gfx_font_list = font_list;
pub use servo_gfx_util = util;

View file

@ -29,10 +29,10 @@ struct GlyphEntry {
pure fn GlyphEntry(value: u32) -> GlyphEntry { GlyphEntry { value: value } } pure fn GlyphEntry(value: u32) -> GlyphEntry { GlyphEntry { value: value } }
/// The index of a particular glyph within a font /// The index of a particular glyph within a font
type GlyphIndex = u32; pub type GlyphIndex = u32;
// TODO: unify with bit flags? // TODO: unify with bit flags?
enum BreakType { pub enum BreakType {
BreakTypeNone, BreakTypeNone,
BreakTypeNormal, BreakTypeNormal,
BreakTypeHyphen BreakTypeHyphen
@ -426,7 +426,7 @@ impl DetailedGlyphStore {
// This struct is used by GlyphStore clients to provide new glyph data. // This struct is used by GlyphStore clients to provide new glyph data.
// It should be allocated on the stack and passed by reference to GlyphStore. // It should be allocated on the stack and passed by reference to GlyphStore.
struct GlyphData { pub struct GlyphData {
index: GlyphIndex, index: GlyphIndex,
advance: Au, advance: Au,
offset: Point2D<Au>, offset: Point2D<Au>,
@ -435,7 +435,7 @@ struct GlyphData {
ligature_start: bool, ligature_start: bool,
} }
pure fn GlyphData(index: GlyphIndex, pub pure fn GlyphData(index: GlyphIndex,
advance: Au, advance: Au,
offset: Option<Point2D<Au>>, offset: Option<Point2D<Au>>,
is_missing: bool, is_missing: bool,
@ -505,13 +505,13 @@ impl GlyphInfo {
} }
// Public data structure and API for storing and retrieving glyph data // Public data structure and API for storing and retrieving glyph data
struct GlyphStore { pub struct GlyphStore {
// we use a DVec here instead of a mut vec, since this is much safer. // we use a DVec here instead of a mut vec, since this is much safer.
entry_buffer: ~[GlyphEntry], entry_buffer: ~[GlyphEntry],
detail_store: DetailedGlyphStore, detail_store: DetailedGlyphStore,
} }
impl GlyphStore { pub impl GlyphStore {
// Initializes the glyph store, but doesn't actually shape anything. // Initializes the glyph store, but doesn't actually shape anything.
// Use the set_glyph, set_glyphs() methods to store glyph data. // Use the set_glyph, set_glyphs() methods to store glyph data.
static fn new(length: uint) -> GlyphStore { static fn new(length: uint) -> GlyphStore {

View file

@ -209,6 +209,9 @@ pub impl HarfbuzzShaper : ShaperMethods {
self.save_glyph_results(text, glyphs, hb_buffer); self.save_glyph_results(text, glyphs, hb_buffer);
hb_buffer_destroy(hb_buffer); hb_buffer_destroy(hb_buffer);
} }
}
pub impl HarfbuzzShaper {
priv fn save_glyph_results(text: &str, glyphs: &mut GlyphStore, buffer: *hb_buffer_t) { priv fn save_glyph_results(text: &str, glyphs: &mut GlyphStore, buffer: *hb_buffer_t) {
let glyph_data = ShapedGlyphData::new(buffer); let glyph_data = ShapedGlyphData::new(buffer);
@ -239,8 +242,9 @@ pub impl HarfbuzzShaper : ShaperMethods {
let mut i = 0u; let mut i = 0u;
while i < byte_max { while i < byte_max {
byteToGlyph[i] = NO_GLYPH; byteToGlyph[i] = NO_GLYPH;
let {ch, next} = str::char_range_at(text, i); ignore(ch); let range = str::char_range_at(text, i);
i = next; ignore(range.ch);
i = range.next;
} }
} }
@ -260,9 +264,9 @@ pub impl HarfbuzzShaper : ShaperMethods {
debug!("(char idx): char->(glyph index):"); debug!("(char idx): char->(glyph index):");
let mut i = 0u; let mut i = 0u;
while i < byte_max { while i < byte_max {
let {ch, next} = str::char_range_at(text, i); let range = str::char_range_at(text, i);
debug!("%u: %? --> %d", i, ch, byteToGlyph[i] as int); debug!("%u: %? --> %d", i, range.ch, byteToGlyph[i] as int);
i = next; i = range.next;
} }
// some helpers // some helpers
@ -285,16 +289,18 @@ pub impl HarfbuzzShaper : ShaperMethods {
// find a range of chars corresponding to this glyph, plus // find a range of chars corresponding to this glyph, plus
// any trailing chars that do not have associated glyphs. // any trailing chars that do not have associated glyphs.
while char_byte_span.end() < byte_max { while char_byte_span.end() < byte_max {
let {ch, next} = str::char_range_at(text, char_byte_span.end()); ignore(ch); let range = str::char_range_at(text, char_byte_span.end());
char_byte_span.extend_to(next); ignore(range.ch);
char_byte_span.extend_to(range.next);
debug!("Processing char byte span: off=%u, len=%u for glyph idx=%u", debug!("Processing char byte span: off=%u, len=%u for glyph idx=%u",
char_byte_span.begin(), char_byte_span.length(), glyph_span.begin()); char_byte_span.begin(), char_byte_span.length(), glyph_span.begin());
while char_byte_span.end() != byte_max && byteToGlyph[char_byte_span.end()] == NO_GLYPH { while char_byte_span.end() != byte_max && byteToGlyph[char_byte_span.end()] == NO_GLYPH {
debug!("Extending char byte span to include byte offset=%u with no associated glyph", char_byte_span.end()); debug!("Extending char byte span to include byte offset=%u with no associated glyph", char_byte_span.end());
let {ch, next} = str::char_range_at(text, char_byte_span.end()); ignore(ch); let range = str::char_range_at(text, char_byte_span.end());
char_byte_span.extend_to(next); ignore(range.ch);
char_byte_span.extend_to(range.next);
} }
// extend glyph range to max glyph index covered by char_span, // extend glyph range to max glyph index covered by char_span,
@ -356,8 +362,9 @@ pub impl HarfbuzzShaper : ShaperMethods {
// extend, clipping at end of text range. // extend, clipping at end of text range.
while covered_byte_span.end() < byte_max while covered_byte_span.end() < byte_max
&& byteToGlyph[covered_byte_span.end()] == NO_GLYPH { && byteToGlyph[covered_byte_span.end()] == NO_GLYPH {
let {ch, next} = str::char_range_at(text, covered_byte_span.end()); ignore(ch); let range = str::char_range_at(text, covered_byte_span.end());
covered_byte_span.extend_to(next); ignore(range.ch);
covered_byte_span.extend_to(range.next);
} }
if covered_byte_span.begin() >= byte_max { if covered_byte_span.begin() >= byte_max {
@ -400,8 +407,9 @@ pub impl HarfbuzzShaper : ShaperMethods {
// set the other chars, who have no glyphs // set the other chars, who have no glyphs
let mut i = covered_byte_span.begin(); let mut i = covered_byte_span.begin();
loop { loop {
let {ch, next} = str::char_range_at(text, i); ignore(ch); let range = str::char_range_at(text, i);
i = next; ignore(range.ch);
i = range.next;
if i >= covered_byte_span.end() { break; } if i >= covered_byte_span.end() { break; }
char_idx += 1; char_idx += 1;
glyphs.add_nonglyph_for_char_index(char_idx, false, false); glyphs.add_nonglyph_for_char_index(char_idx, false, false);

View file

@ -7,3 +7,14 @@ servo.rc. This is not ideal and may be changed in the future. */
pub use shaper::Shaper; pub use shaper::Shaper;
pub use text_run::TextRun; pub use text_run::TextRun;
pub use text_run::SendableTextRun; pub use text_run::SendableTextRun;
pub mod glyph;
pub mod text_run;
pub mod util;
pub mod shaper;
// Below are the actual platform-specific parts.
pub mod harfbuzz {
#[path = "harfbuzz/shaper.rs"]
pub mod shaper;
}

View file

@ -9,14 +9,14 @@ use text::glyph::GlyphStore;
pub type Shaper/& = harfbuzz::shaper::HarfbuzzShaper; pub type Shaper/& = harfbuzz::shaper::HarfbuzzShaper;
trait ShaperMethods { pub trait ShaperMethods {
fn shape_text(text: &str, glyphs: &mut GlyphStore); fn shape_text(text: &str, glyphs: &mut GlyphStore);
} }
// TODO(Issue #163): this is a workaround for static methods and // TODO(Issue #163): this is a workaround for static methods and
// typedefs not working well together. It should be removed. // typedefs not working well together. It should be removed.
impl Shaper { pub impl Shaper {
static pub fn new(font: @Font) -> Shaper { static pub fn new(font: @Font) -> Shaper {
harfbuzz::shaper::HarfbuzzShaper::new(font) harfbuzz::shaper::HarfbuzzShaper::new(font)
} }

View file

@ -42,7 +42,7 @@ impl SendableTextRun {
} }
} }
impl TextRun { pub impl TextRun {
static fn new(font: @Font, text: ~str) -> TextRun { static fn new(font: @Font, text: ~str) -> TextRun {
let mut glyph_store = GlyphStore::new(str::char_len(text)); let mut glyph_store = GlyphStore::new(str::char_len(text));
TextRun::compute_potential_breaks(text, &mut glyph_store); TextRun::compute_potential_breaks(text, &mut glyph_store);
@ -63,7 +63,9 @@ impl TextRun {
let mut char_j = 0u; let mut char_j = 0u;
let mut prev_is_whitespace = false; let mut prev_is_whitespace = false;
while byte_i < text.len() { while byte_i < text.len() {
let {ch, next} = str::char_range_at(text, byte_i); let range = str::char_range_at(text, byte_i);
let ch = range.ch;
let next = range.next;
// set char properties. // set char properties.
match ch { match ch {
' ' => { glyphs.set_char_is_space(char_j); }, ' ' => { glyphs.set_char_is_space(char_j); },

View file

@ -7,7 +7,7 @@ pub fn time<T>(msg: &str, callback: fn() -> T) -> T{
let end_time = precise_time_ns(); let end_time = precise_time_ns();
let ms = ((end_time - start_time) / 1000000u64) as uint; let ms = ((end_time - start_time) / 1000000u64) as uint;
if ms >= 5 { if ms >= 5 {
#debug("%s took %u ms", msg, ms); debug!("%s took %u ms", msg, ms);
} }
return move val; return move val;
} }

View file

@ -22,7 +22,7 @@ pub fn make_url(str_url: ~str, current_url: Option<Url>) -> Url {
~"file://" + os::getcwd().push(str_url).to_str() ~"file://" + os::getcwd().push(str_url).to_str()
} else { } else {
let current_url = current_url.get(); let current_url = current_url.get();
#debug("make_url: current_url: %?", current_url); debug!("make_url: current_url: %?", current_url);
if current_url.path.is_empty() || current_url.path.ends_with("/") { if current_url.path.is_empty() || current_url.path.ends_with("/") {
current_url.scheme + "://" + current_url.host + "/" + str_url current_url.scheme + "://" + current_url.host + "/" + str_url
} else { } else {
@ -47,7 +47,7 @@ mod make_url_tests {
fn should_create_absolute_file_url_if_current_url_is_none_and_str_url_looks_filey() { fn should_create_absolute_file_url_if_current_url_is_none_and_str_url_looks_filey() {
let file = ~"local.html"; let file = ~"local.html";
let url = make_url(move file, None); let url = make_url(move file, None);
#debug("url: %?", url); debug!("url: %?", url);
assert url.scheme == ~"file"; assert url.scheme == ~"file";
assert url.path.contains(os::getcwd().to_str()); assert url.path.contains(os::getcwd().to_str());
} }

View file

@ -48,7 +48,7 @@ pub enum PingMsg {
pub type ContentTask = pipes::SharedChan<ControlMsg>; pub type ContentTask = pipes::SharedChan<ControlMsg>;
fn ContentTask(layout_task: LayoutTask, pub fn ContentTask(layout_task: LayoutTask,
dom_event_port: pipes::Port<Event>, dom_event_port: pipes::Port<Event>,
dom_event_chan: pipes::SharedChan<Event>, dom_event_chan: pipes::SharedChan<Event>,
resource_task: ResourceTask, resource_task: ResourceTask,
@ -102,7 +102,7 @@ pub struct Content {
mut damage: Damage, mut damage: Damage,
} }
fn Content(layout_task: LayoutTask, pub fn Content(layout_task: LayoutTask,
control_port: pipes::Port<ControlMsg>, control_port: pipes::Port<ControlMsg>,
control_chan: pipes::SharedChan<ControlMsg>, control_chan: pipes::SharedChan<ControlMsg>,
resource_task: ResourceTask, resource_task: ResourceTask,

View file

@ -81,7 +81,7 @@ unsafe fn unwrap(obj: *JSObject) -> *rust_box<Document> {
} }
extern fn finalize(_fop: *JSFreeOp, obj: *JSObject) { extern fn finalize(_fop: *JSFreeOp, obj: *JSObject) {
#debug("document finalize!"); debug!("document finalize!");
unsafe { unsafe {
let val = JS_GetReservedSlot(obj, 0); let val = JS_GetReservedSlot(obj, 0);
let _doc: @Document = cast::reinterpret_cast(&RUST_JSVAL_TO_PRIVATE(val)); let _doc: @Document = cast::reinterpret_cast(&RUST_JSVAL_TO_PRIVATE(val));

View file

@ -23,7 +23,7 @@ use node::unwrap;
extern fn finalize(_fop: *JSFreeOp, obj: *JSObject) { extern fn finalize(_fop: *JSFreeOp, obj: *JSObject) {
#debug("element finalize!"); debug!("element finalize!");
unsafe { unsafe {
let val = JS_GetReservedSlot(obj, 0); let val = JS_GetReservedSlot(obj, 0);
let _node: ~NodeBundle = cast::reinterpret_cast(&RUST_JSVAL_TO_PRIVATE(val)); let _node: ~NodeBundle = cast::reinterpret_cast(&RUST_JSVAL_TO_PRIVATE(val));

View file

@ -61,19 +61,19 @@ pub fn create(cx: *JSContext, node: Node, scope: NodeScope) -> jsobj unsafe {
} }
} }
struct NodeBundle { pub struct NodeBundle {
node: Node, node: Node,
scope: NodeScope, scope: NodeScope,
} }
fn NodeBundle(n: Node, s: NodeScope) -> NodeBundle { pub fn NodeBundle(n: Node, s: NodeScope) -> NodeBundle {
NodeBundle { NodeBundle {
node : n, node : n,
scope : s scope : s
} }
} }
unsafe fn unwrap(obj: *JSObject) -> *rust_box<NodeBundle> { pub unsafe fn unwrap(obj: *JSObject) -> *rust_box<NodeBundle> {
let val = js::GetReservedSlot(obj, 0); let val = js::GetReservedSlot(obj, 0);
cast::reinterpret_cast(&JSVAL_TO_PRIVATE(val)) cast::reinterpret_cast(&JSVAL_TO_PRIVATE(val))
} }

View file

@ -12,27 +12,27 @@ use js::glue::bindgen::*;
use ptr::null; use ptr::null;
use content::content_task::{Content, task_from_context}; use content::content_task::{Content, task_from_context};
enum DOMString { pub enum DOMString {
str(~str), str(~str),
null_string null_string
} }
type rust_box<T> = {rc: uint, td: *sys::TypeDesc, next: *(), prev: *(), payload: T}; pub type rust_box<T> = {rc: uint, td: *sys::TypeDesc, next: *(), prev: *(), payload: T};
unsafe fn squirrel_away<T>(x: @T) -> *rust_box<T> { pub unsafe fn squirrel_away<T>(x: @T) -> *rust_box<T> {
let y: *rust_box<T> = cast::reinterpret_cast(&x); let y: *rust_box<T> = cast::reinterpret_cast(&x);
cast::forget(x); cast::forget(x);
y y
} }
unsafe fn squirrel_away_unique<T>(x: ~T) -> *rust_box<T> { pub unsafe fn squirrel_away_unique<T>(x: ~T) -> *rust_box<T> {
let y: *rust_box<T> = cast::reinterpret_cast(&x); let y: *rust_box<T> = cast::reinterpret_cast(&x);
cast::forget(move x); cast::forget(move x);
y y
} }
//XXX very incomplete //XXX very incomplete
fn jsval_to_str(cx: *JSContext, v: JSVal) -> Result<~str, ()> { pub fn jsval_to_str(cx: *JSContext, v: JSVal) -> Result<~str, ()> {
let jsstr; let jsstr;
if RUST_JSVAL_IS_STRING(v) == 1 { if RUST_JSVAL_IS_STRING(v) == 1 {
jsstr = RUST_JSVAL_TO_STRING(v) jsstr = RUST_JSVAL_TO_STRING(v)
@ -55,7 +55,7 @@ fn jsval_to_str(cx: *JSContext, v: JSVal) -> Result<~str, ()> {
} }
} }
unsafe fn domstring_to_jsval(cx: *JSContext, string: &DOMString) -> JSVal { pub unsafe fn domstring_to_jsval(cx: *JSContext, string: &DOMString) -> JSVal {
match *string { match *string {
null_string => { null_string => {
JSVAL_NULL JSVAL_NULL

View file

@ -57,7 +57,7 @@ unsafe fn unwrap(obj: *JSObject) -> *rust_box<Window> {
} }
extern fn finalize(_fop: *JSFreeOp, obj: *JSObject) { extern fn finalize(_fop: *JSFreeOp, obj: *JSObject) {
#debug("finalize!"); debug!("finalize!");
unsafe { unsafe {
let val = JS_GetReservedSlot(obj, 0); let val = JS_GetReservedSlot(obj, 0);
let _: @Window = cast::reinterpret_cast(&RUST_JSVAL_TO_PRIVATE(val)); let _: @Window = cast::reinterpret_cast(&RUST_JSVAL_TO_PRIVATE(val));

View file

@ -224,7 +224,7 @@ impl<T:Copy Send,A> Scope<T,A> {
let const_read_ptr = ptr::const_offset(h.read_ptr(), 0); let const_read_ptr = ptr::const_offset(h.read_ptr(), 0);
let const_write_ptr = ptr::const_offset(h.write_ptr(), 0); let const_write_ptr = ptr::const_offset(h.write_ptr(), 0);
if self.d.layout_active && const_read_ptr == const_write_ptr { if self.d.layout_active && const_read_ptr == const_write_ptr {
#debug["marking handle %? as dirty", h]; debug!("marking handle %? as dirty", h);
h.set_write_ptr(cast::reinterpret_cast(&self.clone(h.read_ptr()))); h.set_write_ptr(cast::reinterpret_cast(&self.clone(h.read_ptr())));
h.set_next_dirty(self.d.first_dirty); h.set_next_dirty(self.d.first_dirty);
self.d.first_dirty = *h; self.d.first_dirty = *h;

View file

@ -2,12 +2,12 @@ use newcss::stylesheet::Stylesheet;
use dom::node::{NodeScope, Node}; use dom::node::{NodeScope, Node};
use std::arc::ARC; use std::arc::ARC;
struct Document { pub struct Document {
root: Node, root: Node,
scope: NodeScope, scope: NodeScope,
} }
fn Document(root: Node, scope: NodeScope) -> Document { pub fn Document(root: Node, scope: NodeScope) -> Document {
Document { Document {
root : root, root : root,
scope : scope, scope : scope,

View file

@ -4,7 +4,7 @@ use dvec::DVec;
use geom::size::Size2D; use geom::size::Size2D;
use std::net::url::Url; use std::net::url::Url;
struct ElementData { pub struct ElementData {
tag_name: ~str, tag_name: ~str,
kind: ~ElementKind, kind: ~ElementKind,
attrs: DVec<~Attr>, attrs: DVec<~Attr>,
@ -43,7 +43,7 @@ impl ElementData {
} }
} }
fn ElementData(tag_name: ~str, kind: ~ElementKind) -> ElementData { pub fn ElementData(tag_name: ~str, kind: ~ElementKind) -> ElementData {
ElementData { ElementData {
tag_name : move tag_name, tag_name : move tag_name,
kind : move kind, kind : move kind,
@ -51,29 +51,29 @@ fn ElementData(tag_name: ~str, kind: ~ElementKind) -> ElementData {
} }
} }
struct Attr { pub struct Attr {
name: ~str, name: ~str,
value: ~str, value: ~str,
} }
fn Attr(name: ~str, value: ~str) -> Attr { pub fn Attr(name: ~str, value: ~str) -> Attr {
Attr { Attr {
name : move name, name : move name,
value : move value, value : move value,
} }
} }
fn HTMLImageData() -> HTMLImageData { pub fn HTMLImageData() -> HTMLImageData {
HTMLImageData { HTMLImageData {
image: None image: None
} }
} }
struct HTMLImageData { pub struct HTMLImageData {
mut image: Option<Url> mut image: Option<Url>
} }
enum HeadingLevel { pub enum HeadingLevel {
Heading1, Heading1,
Heading2, Heading2,
Heading3, Heading3,
@ -82,7 +82,7 @@ enum HeadingLevel {
Heading6, Heading6,
} }
enum ElementKind { pub enum ElementKind {
HTMLAnchorElement, HTMLAnchorElement,
HTMLAsideElement, HTMLAsideElement,
HTMLBRElement, HTMLBRElement,

View file

@ -1,4 +1,4 @@
enum Event { pub enum Event {
ResizeEvent(uint, uint, pipes::Chan<()>), ResizeEvent(uint, uint, pipes::Chan<()>),
ReflowEvent ReflowEvent
} }

View file

@ -16,15 +16,15 @@ use ptr::null;
use std::arc::ARC; use std::arc::ARC;
use util::tree; use util::tree;
enum NodeData = { pub enum NodeData = {
tree: tree::Tree<Node>, tree: tree::Tree<Node>,
kind: ~NodeKind, kind: ~NodeKind,
}; };
/* The tree holding Nodes (read-only) */ /* The tree holding Nodes (read-only) */
enum NodeTree { NodeTree } pub enum NodeTree { NodeTree }
impl NodeTree : tree::ReadMethods<Node> { impl NodeTree {
fn each_child(node: &Node, f: fn(&Node) -> bool) { fn each_child(node: &Node, f: fn(&Node) -> bool) {
tree::each_child(&self, node, f) tree::each_child(&self, node, f)
} }
@ -32,7 +32,9 @@ impl NodeTree : tree::ReadMethods<Node> {
fn get_parent(node: &Node) -> Option<Node> { fn get_parent(node: &Node) -> Option<Node> {
tree::get_parent(&self, node) tree::get_parent(&self, node)
} }
}
impl NodeTree : tree::ReadMethods<Node> {
fn with_tree_fields<R>(n: &Node, f: fn(&tree::Tree<Node>) -> R) -> R { fn with_tree_fields<R>(n: &Node, f: fn(&tree::Tree<Node>) -> R) -> R {
n.read(|n| f(&n.tree)) n.read(|n| f(&n.tree))
} }
@ -91,14 +93,14 @@ pub enum NodeKind {
Text(~str) Text(~str)
} }
struct DoctypeData { pub struct DoctypeData {
name: ~str, name: ~str,
public_id: Option<~str>, public_id: Option<~str>,
system_id: Option<~str>, system_id: Option<~str>,
force_quirks: bool force_quirks: bool
} }
fn DoctypeData(name: ~str, public_id: Option<~str>, pub fn DoctypeData(name: ~str, public_id: Option<~str>,
system_id: Option<~str>, force_quirks: bool) -> DoctypeData { system_id: Option<~str>, force_quirks: bool) -> DoctypeData {
DoctypeData { DoctypeData {
name : move name, name : move name,
@ -110,7 +112,7 @@ fn DoctypeData(name: ~str, public_id: Option<~str>,
fn define_bindings(compartment: &bare_compartment, doc: @Document, pub fn define_bindings(compartment: &bare_compartment, doc: @Document,
win: @Window) { win: @Window) {
bindings::window::init(compartment, win); bindings::window::init(compartment, win);
bindings::document::init(compartment, doc); bindings::document::init(compartment, doc);
@ -129,11 +131,11 @@ enum LayoutData = {
mut flow: Option<@FlowContext> mut flow: Option<@FlowContext>
}; };
type Node = cow::Handle<NodeData, LayoutData>; pub type Node = cow::Handle<NodeData, LayoutData>;
type NodeScope = cow::Scope<NodeData, LayoutData>; pub type NodeScope = cow::Scope<NodeData, LayoutData>;
fn NodeScope() -> NodeScope { pub fn NodeScope() -> NodeScope {
cow::Scope() cow::Scope()
} }
@ -148,8 +150,7 @@ impl NodeScope : NodeScopeExtensions {
} }
} }
#[allow(non_implicitly_copyable_typarams)] impl NodeScope {
impl NodeScope : tree::ReadMethods<Node> {
fn each_child(node: &Node, f: fn(&Node) -> bool) { fn each_child(node: &Node, f: fn(&Node) -> bool) {
tree::each_child(&self, node, f) tree::each_child(&self, node, f)
} }
@ -157,18 +158,23 @@ impl NodeScope : tree::ReadMethods<Node> {
fn get_parent(node: &Node) -> Option<Node> { fn get_parent(node: &Node) -> Option<Node> {
tree::get_parent(&self, node) tree::get_parent(&self, node)
} }
}
#[allow(non_implicitly_copyable_typarams)]
impl NodeScope : tree::ReadMethods<Node> {
fn with_tree_fields<R>(node: &Node, f: fn(&tree::Tree<Node>) -> R) -> R { fn with_tree_fields<R>(node: &Node, f: fn(&tree::Tree<Node>) -> R) -> R {
self.read(node, |n| f(&n.tree)) self.read(node, |n| f(&n.tree))
} }
} }
#[allow(non_implicitly_copyable_typarams)] impl NodeScope {
impl NodeScope : tree::WriteMethods<Node> {
fn add_child(node: Node, child: Node) { fn add_child(node: Node, child: Node) {
tree::add_child(&self, node, child) tree::add_child(&self, node, child)
} }
}
#[allow(non_implicitly_copyable_typarams)]
impl NodeScope : tree::WriteMethods<Node> {
pure fn eq(a: &Node, b: &Node) -> bool { a == b } pure fn eq(a: &Node, b: &Node) -> bool { a == b }
fn with_tree_fields<R>(node: &Node, f: fn(&tree::Tree<Node>) -> R) -> R { fn with_tree_fields<R>(node: &Node, f: fn(&tree::Tree<Node>) -> R) -> R {

View file

@ -3,13 +3,13 @@ use content::content_task::{ControlMsg, Timer, ExitMsg};
use js::jsapi::JSVal; use js::jsapi::JSVal;
use dvec::DVec; use dvec::DVec;
enum TimerControlMsg { pub enum TimerControlMsg {
TimerMessage_Fire(~TimerData), TimerMessage_Fire(~TimerData),
TimerMessage_Close, TimerMessage_Close,
TimerMessage_TriggerExit //XXXjdm this is just a quick hack to talk to the content task TimerMessage_TriggerExit //XXXjdm this is just a quick hack to talk to the content task
} }
struct Window { pub struct Window {
timer_chan: Chan<TimerControlMsg>, timer_chan: Chan<TimerControlMsg>,
drop { drop {
@ -63,7 +63,7 @@ impl Window {
} }
} }
fn Window(content_chan: pipes::SharedChan<ControlMsg>) -> Window { pub fn Window(content_chan: pipes::SharedChan<ControlMsg>) -> Window {
Window { Window {
timer_chan: do task::spawn_listener |timer_port: Port<TimerControlMsg>, timer_chan: do task::spawn_listener |timer_port: Port<TimerControlMsg>,

View file

@ -23,7 +23,7 @@ pub enum Msg {
ExitMsg(Chan<()>) ExitMsg(Chan<()>)
} }
struct Engine<C:Compositor Send Copy> { pub struct Engine<C:Compositor Send Copy> {
request_port: comm::Port<Msg>, request_port: comm::Port<Msg>,
compositor: C, compositor: C,
render_task: RenderTask, render_task: RenderTask,
@ -33,7 +33,7 @@ struct Engine<C:Compositor Send Copy> {
content_task: ContentTask content_task: ContentTask
} }
fn Engine<C:Compositor Send Copy>(compositor: C, pub fn Engine<C:Compositor Send Copy>(compositor: C,
opts: &Opts, opts: &Opts,
dom_event_port: pipes::Port<Event>, dom_event_port: pipes::Port<Event>,
dom_event_chan: pipes::SharedChan<Event>, dom_event_chan: pipes::SharedChan<Event>,

View file

@ -12,7 +12,7 @@ use std::net::url::Url;
use std::net::url; use std::net::url;
/// Where a style sheet comes from. /// Where a style sheet comes from.
enum StylesheetProvenance { pub enum StylesheetProvenance {
UrlProvenance(Url), UrlProvenance(Url),
InlineProvenance(Url, ~str), InlineProvenance(Url, ~str),
} }

View file

@ -10,6 +10,7 @@ use resource::resource_task::{Done, Load, Payload, ResourceTask};
use core::comm::{Chan, Port}; use core::comm::{Chan, Port};
use cssparse::{InlineProvenance, StylesheetProvenance, UrlProvenance, spawn_css_parser}; use cssparse::{InlineProvenance, StylesheetProvenance, UrlProvenance, spawn_css_parser};
use hubbub::hubbub;
use hubbub::Attribute; use hubbub::Attribute;
use newcss::stylesheet::Stylesheet; use newcss::stylesheet::Stylesheet;
use std::net::url::Url; use std::net::url::Url;
@ -97,7 +98,7 @@ fn js_script_listener(to_parent : comm::Chan<~[~[u8]]>, from_parent : comm::Port
break; break;
} }
Done(Err(*)) => { Done(Err(*)) => {
#error("error loading script %s", url.to_str()); error!("error loading script %s", url.to_str());
} }
} }
} }

View file

@ -11,11 +11,11 @@ use layout::display_list_builder::DisplayListBuilder;
use layout::flow::{FlowContext, FlowTree, InlineBlockFlow, BlockFlow, RootFlow}; use layout::flow::{FlowContext, FlowTree, InlineBlockFlow, BlockFlow, RootFlow};
use util::tree; use util::tree;
struct BlockFlowData { pub struct BlockFlowData {
mut box: Option<@RenderBox> mut box: Option<@RenderBox>
} }
fn BlockFlowData() -> BlockFlowData { pub fn BlockFlowData() -> BlockFlowData {
BlockFlowData { BlockFlowData {
box: None box: None
} }

View file

@ -71,7 +71,7 @@ padding, backgrounds. It is analogous to a CSS nonreplaced content box.
It also holds data specific to different box types, such as text. It also holds data specific to different box types, such as text.
*/ */
struct RenderBoxData { pub struct RenderBoxData {
/* originating DOM node */ /* originating DOM node */
node : Node, node : Node,
/* reference to containing flow context, which this box /* reference to containing flow context, which this box
@ -105,32 +105,7 @@ pub enum SplitBoxResult {
SplitDidNotFit(Option<@RenderBox>, Option<@RenderBox>) SplitDidNotFit(Option<@RenderBox>, Option<@RenderBox>)
} }
trait RenderBoxMethods { pub fn RenderBoxData(node: Node, ctx: @FlowContext, id: int) -> RenderBoxData {
pure fn d(&self) -> &self/RenderBoxData;
pure fn is_replaced() -> bool;
pure fn can_split() -> bool;
pure fn is_whitespace_only() -> bool;
// TODO(Issue #220): this should be a pure/const method
fn can_merge_with_box(@self, other: @RenderBox) -> bool;
pure fn content_box() -> Rect<Au>;
pure fn border_box() -> Rect<Au>;
pure fn margin_box() -> Rect<Au>;
fn split_to_width(@self, &LayoutContext, Au, starts_line: bool) -> SplitBoxResult;
fn get_min_width(&LayoutContext) -> Au;
fn get_pref_width(&LayoutContext) -> Au;
fn get_used_width() -> (Au, Au);
fn get_used_height() -> (Au, Au);
fn build_display_list(@self,
builder: &DisplayListBuilder,
dirty: &Rect<Au>,
offset: &Point2D<Au>,
dl: &mut DisplayList);
}
fn RenderBoxData(node: Node, ctx: @FlowContext, id: int) -> RenderBoxData {
RenderBoxData { RenderBoxData {
node : node, node : node,
mut ctx : ctx, mut ctx : ctx,
@ -140,7 +115,7 @@ fn RenderBoxData(node: Node, ctx: @FlowContext, id: int) -> RenderBoxData {
} }
} }
impl RenderBox : RenderBoxMethods { impl RenderBox {
pure fn d(&self) -> &self/RenderBoxData { pure fn d(&self) -> &self/RenderBoxData {
match *self { match *self {
GenericBox(ref d) => d, GenericBox(ref d) => d,

View file

@ -22,7 +22,7 @@ pub struct LayoutTreeBuilder {
mut next_cid: int mut next_cid: int
} }
impl LayoutTreeBuilder { pub impl LayoutTreeBuilder {
static pure fn new() -> LayoutTreeBuilder { static pure fn new() -> LayoutTreeBuilder {
LayoutTreeBuilder { LayoutTreeBuilder {
root_flow: None, root_flow: None,

View file

@ -6,7 +6,7 @@ use std::net::url::Url;
/* Represents layout task context. */ /* Represents layout task context. */
struct LayoutContext { pub struct LayoutContext {
font_ctx: @FontContext, font_ctx: @FontContext,
image_cache: @LocalImageCache, image_cache: @LocalImageCache,
doc_url: Url, doc_url: Url,

View file

@ -1,10 +1,10 @@
trait BoxedDebugMethods { pub trait BoxedDebugMethods {
pure fn dump(@self); pure fn dump(@self);
pure fn dump_indent(@self, ident: uint); pure fn dump_indent(@self, ident: uint);
pure fn debug_str(@self) -> ~str; pure fn debug_str(@self) -> ~str;
} }
trait DebugMethods { pub trait DebugMethods {
pure fn dump(&self); pure fn dump(&self);
pure fn dump_indent(&self, ident: uint); pure fn dump_indent(&self, ident: uint);
pure fn debug_str(&self) -> ~str; pure fn debug_str(&self) -> ~str;

View file

@ -43,7 +43,7 @@ Currently, the important types of flows are:
/* The type of the formatting context, and data specific to each /* The type of the formatting context, and data specific to each
context, such as linebox structures or float lists */ context, such as linebox structures or float lists */
enum FlowContext { pub enum FlowContext {
AbsoluteFlow(FlowData), AbsoluteFlow(FlowData),
BlockFlow(FlowData, BlockFlowData), BlockFlow(FlowData, BlockFlowData),
FloatFlow(FlowData), FloatFlow(FlowData),
@ -63,20 +63,6 @@ enum FlowContextType {
Flow_Table Flow_Table
} }
trait FlowContextMethods {
pure fn d(&self) -> &self/FlowData;
pure fn inline(&self) -> &self/InlineFlowData;
pure fn block(&self) -> &self/BlockFlowData;
pure fn root(&self) -> &self/RootFlowData;
fn bubble_widths(@self, &LayoutContext);
fn assign_widths(@self, &LayoutContext);
fn assign_height(@self, &LayoutContext);
fn build_display_list_recurse(@self, &DisplayListBuilder, dirty: &Rect<Au>,
offset: &Point2D<Au>, &mut DisplayList);
pure fn foldl_boxes_for_node<B: Copy>(Node, +seed: B, cb: pure fn&(+a: B,@RenderBox) -> B) -> B;
pure fn iter_boxes_for_node<T>(Node, cb: pure fn&(@RenderBox) -> T);
}
/* A particular kind of layout context. It manages the positioning of /* A particular kind of layout context. It manages the positioning of
render boxes within the context. */ render boxes within the context. */
struct FlowData { struct FlowData {
@ -106,7 +92,7 @@ fn FlowData(id: int) -> FlowData {
} }
} }
impl FlowContext : FlowContextMethods { impl FlowContext {
pure fn d(&self) -> &self/FlowData { pure fn d(&self) -> &self/FlowData {
match *self { match *self {
AbsoluteFlow(ref d) => d, AbsoluteFlow(ref d) => d,
@ -216,22 +202,27 @@ impl FlowContext : FlowContextMethods {
} }
/* The tree holding FlowContexts */ /* The tree holding FlowContexts */
enum FlowTree { FlowTree } pub enum FlowTree { FlowTree }
impl FlowTree : tree::ReadMethods<@FlowContext> { impl FlowTree {
fn each_child(ctx: @FlowContext, f: fn(box: @FlowContext) -> bool) { fn each_child(ctx: @FlowContext, f: fn(box: @FlowContext) -> bool) {
tree::each_child(&self, &ctx, |box| f(*box) ) tree::each_child(&self, &ctx, |box| f(*box) )
} }
}
impl FlowTree : tree::ReadMethods<@FlowContext> {
fn with_tree_fields<R>(box: &@FlowContext, f: fn(&tree::Tree<@FlowContext>) -> R) -> R { fn with_tree_fields<R>(box: &@FlowContext, f: fn(&tree::Tree<@FlowContext>) -> R) -> R {
f(&box.d().tree) f(&box.d().tree)
} }
} }
impl FlowTree : tree::WriteMethods<@FlowContext> { impl FlowTree {
fn add_child(parent: @FlowContext, child: @FlowContext) { fn add_child(parent: @FlowContext, child: @FlowContext) {
tree::add_child(&self, parent, child) tree::add_child(&self, parent, child)
} }
}
impl FlowTree : tree::WriteMethods<@FlowContext> {
pure fn eq(a: &@FlowContext, b: &@FlowContext) -> bool { core::box::ptr_eq(*a, *b) } pure fn eq(a: &@FlowContext, b: &@FlowContext) -> bool { core::box::ptr_eq(*a, *b) }

View file

@ -39,12 +39,12 @@ serve as the starting point, but the current design doesn't make it
hard to try out that alternative. hard to try out that alternative.
*/ */
struct NodeRange { pub struct NodeRange {
node: Node, node: Node,
range: Range, range: Range,
} }
impl NodeRange { pub impl NodeRange {
static pure fn new(node: Node, range: &const Range) -> NodeRange { static pure fn new(node: Node, range: &const Range) -> NodeRange {
NodeRange { node: node, range: copy *range } NodeRange { node: node, range: copy *range }
} }
@ -557,7 +557,7 @@ impl LineboxScanner {
} }
} }
struct InlineFlowData { pub struct InlineFlowData {
// A vec of all inline render boxes. Several boxes may // A vec of all inline render boxes. Several boxes may
// correspond to one Node/Element. // correspond to one Node/Element.
boxes: DVec<@RenderBox>, boxes: DVec<@RenderBox>,
@ -570,7 +570,7 @@ struct InlineFlowData {
elems: ElementMapping elems: ElementMapping
} }
fn InlineFlowData() -> InlineFlowData { pub fn InlineFlowData() -> InlineFlowData {
InlineFlowData { InlineFlowData {
boxes: DVec(), boxes: DVec(),
lines: DVec(), lines: DVec(),

View file

@ -75,7 +75,7 @@ impl Damage {
} }
} }
struct BuildData { pub struct BuildData {
node: Node, node: Node,
url: Url, url: Url,
dom_event_chan: pipes::SharedChan<Event>, dom_event_chan: pipes::SharedChan<Event>,
@ -84,7 +84,7 @@ struct BuildData {
damage: Damage, damage: Damage,
} }
fn LayoutTask(render_task: RenderTask, pub fn LayoutTask(render_task: RenderTask,
img_cache_task: ImageCacheTask, img_cache_task: ImageCacheTask,
opts: Opts) -> LayoutTask { opts: Opts) -> LayoutTask {
do spawn_listener::<Msg> |from_content, move img_cache_task, move opts| { do spawn_listener::<Msg> |from_content, move img_cache_task, move opts| {

View file

@ -10,11 +10,11 @@ use layout::flow::{FlowContext, FlowTree, InlineBlockFlow, BlockFlow, RootFlow};
use layout::display_list_builder::DisplayListBuilder; use layout::display_list_builder::DisplayListBuilder;
use util::tree; use util::tree;
struct RootFlowData { pub struct RootFlowData {
mut box: Option<@RenderBox> mut box: Option<@RenderBox>
} }
fn RootFlowData() -> RootFlowData { pub fn RootFlowData() -> RootFlowData {
RootFlowData { RootFlowData {
box: None box: None
} }

View file

@ -14,9 +14,10 @@ use geom::size::Size2D;
use gfx::compositor::{Compositor, LayerBuffer, LayerBufferSet}; use gfx::compositor::{Compositor, LayerBuffer, LayerBufferSet};
use gfx::opts::Opts; use gfx::opts::Opts;
use gfx::util::time; use gfx::util::time;
use layers::ImageLayer; use layers::layers::ImageLayer;
use std::cell::Cell; use std::cell::Cell;
use std::cmp::FuzzyEq; use std::cmp::FuzzyEq;
use glut::glut;
pub struct OSMain { pub struct OSMain {
chan: comm::Chan<Msg> chan: comm::Chan<Msg>
@ -40,12 +41,12 @@ pub enum Msg {
Exit Exit
} }
fn OSMain(dom_event_chan: pipes::SharedChan<Event>, opts: Opts) -> OSMain { pub fn OSMain(dom_event_chan: pipes::SharedChan<Event>, opts: Opts) -> OSMain {
let dom_event_chan = Cell(move dom_event_chan); let dom_event_chan = Cell(move dom_event_chan);
OSMain { OSMain {
chan: do on_osmain::<Msg> |po, move dom_event_chan, move opts| { chan: do on_osmain::<Msg> |po, move dom_event_chan, move opts| {
do platform::runmain { do platform::runmain {
#debug("preparing to enter main loop"); debug!("preparing to enter main loop");
// FIXME: Use the servo options. // FIXME: Use the servo options.
let mode; let mode;
@ -139,7 +140,7 @@ fn mainloop(mode: Mode,
AddKeyHandler(move key_ch) => key_handlers.push(move key_ch), AddKeyHandler(move key_ch) => key_handlers.push(move key_ch),
BeginDrawing(move sender) => lend_surface(surfaces, move sender), BeginDrawing(move sender) => lend_surface(surfaces, move sender),
Draw(move sender, move draw_target) => { Draw(move sender, move draw_target) => {
#debug("osmain: received new frame"); debug!("osmain: received new frame");
return_surface(surfaces, move draw_target); return_surface(surfaces, move draw_target);
lend_surface(surfaces, move sender); lend_surface(surfaces, move sender);
@ -226,7 +227,7 @@ fn mainloop(mode: Mode,
match window { match window {
GlutWindow(window) => { GlutWindow(window) => {
do glut::reshape_func(window) |width, height| { do glut::reshape_func(window) |width, height| {
#debug("osmain: window resized to %d,%d", width as int, height as int); debug!("osmain: window resized to %d,%d", width as int, height as int);
check_for_messages(); check_for_messages();
resize_rate_limiter.window_resized(width as uint, height as uint); resize_rate_limiter.window_resized(width as uint, height as uint);
//composite(); //composite();
@ -286,7 +287,7 @@ fn lend_surface(surfaces: &SurfaceSet, receiver: pipes::Chan<LayerBufferSet>) {
rect: copy layer_buffer.rect, rect: copy layer_buffer.rect,
stride: layer_buffer.stride stride: layer_buffer.stride
}; };
#debug("osmain: lending surface %?", layer_buffer); debug!("osmain: lending surface %?", layer_buffer);
move layer_buffer move layer_buffer
}; };
surfaces.front.layer_buffer_set.buffers = move old_layer_buffers; surfaces.front.layer_buffer_set.buffers = move old_layer_buffers;

View file

@ -23,67 +23,215 @@ extern mod stb_image;
extern mod std; extern mod std;
pub mod content { pub mod content {
#[path = "content/content_task.rs"]
pub mod content_task; pub mod content_task;
} }
pub mod css { pub mod css {
#[path = "css/select_handler.rs"]
priv mod select_handler; priv mod select_handler;
#[path = "css/node_util.rs"]
priv mod node_util; priv mod node_util;
#[path = "css/node_void_ptr.rs"]
priv mod node_void_ptr; priv mod node_void_ptr;
#[path = "css/select.rs"]
pub mod select; pub mod select;
#[path = "css/matching.rs"]
pub mod matching; pub mod matching;
#[path = "css/node_style.rs"]
pub mod node_style; pub mod node_style;
} }
pub mod dom { pub mod dom {
pub mod bindings { pub mod bindings {
#[path = "dom/bindings/document.rs"]
pub mod document; pub mod document;
#[path = "dom/bindings/element.rs"]
pub mod element; pub mod element;
#[path = "dom/bindings/node.rs"]
pub mod node; pub mod node;
#[path = "dom/bindings/utils.rs"]
pub mod utils; pub mod utils;
#[path = "dom/bindings/window.rs"]
pub mod window; pub mod window;
} }
#[path = "dom/cow.rs"]
pub mod cow; pub mod cow;
#[path = "dom/document.rs"]
pub mod document; pub mod document;
#[path = "dom/element.rs"]
pub mod element; pub mod element;
#[path = "dom/event.rs"]
pub mod event; pub mod event;
#[path = "dom/node.rs"]
pub mod node; pub mod node;
#[path = "dom/window.rs"]
pub mod window; pub mod window;
} }
pub mod engine; pub mod engine;
pub mod layout { pub mod layout {
#[path = "layout/block.rs"]
pub mod block; pub mod block;
#[path = "layout/box.rs"]
pub mod box; pub mod box;
#[path = "layout/box_builder.rs"]
pub mod box_builder; pub mod box_builder;
#[path = "layout/context.rs"]
pub mod context; pub mod context;
#[path = "layout/debug.rs"]
pub mod debug; pub mod debug;
#[path = "layout/display_list_builder.rs"]
pub mod display_list_builder; pub mod display_list_builder;
#[path = "layout/flow.rs"]
pub mod flow; pub mod flow;
#[path = "layout/layout_task.rs"]
pub mod layout_task; pub mod layout_task;
#[path = "layout/inline.rs"]
pub mod inline; pub mod inline;
#[path = "layout/root.rs"]
pub mod root; pub mod root;
#[path = "layout/text.rs"]
pub mod text; pub mod text;
#[path = "layout/traverse.rs"]
pub mod traverse; pub mod traverse;
#[path = "layout/aux.rs"]
mod aux; mod aux;
} }
pub mod html { pub mod html {
#[path = "html/cssparse.rs"]
pub mod cssparse; pub mod cssparse;
#[path = "html/hubbub_html_parser.rs"]
pub mod hubbub_html_parser; pub mod hubbub_html_parser;
} }
pub mod platform { pub mod platform {
#[path = "platform/base.rs"]
pub mod base; pub mod base;
#[path = "platform/osmain.rs"]
pub mod osmain; pub mod osmain;
#[path = "platform/resize_rate_limiter.rs"]
priv mod resize_rate_limiter; priv mod resize_rate_limiter;
} }
pub mod util { #[path = "util/mod.rs"]
pub mod actor; pub mod util;
pub mod tree;
}
use servo_util = util; use servo_util = util;
#[cfg(target_os="macos")]
extern mod core_graphics;
#[cfg(target_os="macos")]
extern mod core_text;
use engine::{Engine, ExitMsg, LoadURLMsg}; // FIXME: "ExitMsg" is pollution.
use platform::osmain::{AddKeyHandler, OSMain};
use core::comm::*; // FIXME: Bad!
use core::option::swap_unwrap;
use core::pipes::{Port, Chan};
pub use gfx::opts::{Opts, Png, Screen}; // FIXME: Do we really want "Screen" and "Png" visible?
pub use gfx::resource;
pub use gfx::resource::image_cache_task::ImageCacheTask;
pub use gfx::resource::resource_task::ResourceTask;
pub use gfx::text;
pub use gfx::util::url::make_url;
fn main() {
let args = os::args();
run(&gfx::opts::from_cmdline_args(args))
}
#[allow(non_implicitly_copyable_typarams)]
fn run(opts: &Opts) {
match opts.render_mode {
Screen => run_pipeline_screen(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, outfile)
}
}
}
fn run_pipeline_screen(opts: &Opts) {
let (dom_event_chan, dom_event_port) = pipes::stream();
let dom_event_chan = pipes::SharedChan(move dom_event_chan);
// The platform event handler thread
let osmain = OSMain(dom_event_chan.clone(), copy *opts);
// Send each file to render then wait for keypress
let (keypress_to_engine, keypress_from_osmain) = pipes::stream();
osmain.chan.send(AddKeyHandler(move keypress_to_engine));
// Create a servo instance
let resource_task = ResourceTask();
let image_cache_task = ImageCacheTask(copy resource_task);
let engine_task = Engine(osmain, opts, move dom_event_port, move dom_event_chan,
move resource_task, move image_cache_task);
for opts.urls.each |filename| {
let url = make_url(copy *filename, None);
debug!("master: Sending url `%s`", url.to_str());
engine_task.send(LoadURLMsg(move url));
debug!("master: Waiting for keypress");
match keypress_from_osmain.try_recv() {
Some(*) => { }
None => { error!("keypress stream closed unexpectedly") }
};
}
// Shut everything down
debug!("master: Shut down");
let (exit_chan, exit_response_from_engine) = pipes::stream();
engine_task.send(engine::ExitMsg(move exit_chan));
exit_response_from_engine.recv();
osmain.chan.send(platform::osmain::Exit);
}
fn run_pipeline_png(_opts: &Opts, _outfile: &str) {
fail ~"PNG compositor is broken";
}
#[cfg(broken)]
fn run_pipeline_png(url: ~str, outfile: &str) {
// Use a PNG encoder as the graphics compositor
use gfx::png_compositor;
use png_compositor::PngCompositor;
use io::{Writer, buffered_file_writer};
use resource::resource_task::ResourceTask;
use resource::image_cache_task::SyncImageCacheTask;
listen(|pngdata_from_compositor| {
let (dom_event_chan, dom_event_port) = pipes::stream();
let dom_event_chan = pipes::SharedChan(move dom_event_chan);
let compositor = PngCompositor(pngdata_from_compositor);
let resource_task = ResourceTask();
// For the PNG pipeline we are using a synchronous image task so that all images will be
// fulfilled before the first paint.
let image_cache_task = SyncImageCacheTask(resource_task);
let engine_task = Engine(copy compositor, move dom_event_port, move dom_event_chan,
move resource_task, move image_cache_task);
engine_task.send(LoadURLMsg(make_url(copy url, None)));
match buffered_file_writer(&Path(outfile)) {
Ok(writer) => writer.write(pngdata_from_compositor.recv()),
Err(e) => fail e
}
let (exit_chan, exit_response_from_engine) = pipes::stream();
engine_task.send(engine::ExitMsg(move exit_chan));
exit_response_from_engine.recv();
compositor.send(png_compositor::Exit);
})
}

View file

@ -1,113 +0,0 @@
#[cfg(target_os="macos")]
extern mod core_graphics;
#[cfg(target_os="macos")]
extern mod core_text;
use engine::{Engine, ExitMsg, LoadURLMsg}; // FIXME: "ExitMsg" is pollution.
use platform::osmain::{AddKeyHandler, OSMain};
use core::comm::*; // FIXME: Bad!
use core::option::swap_unwrap;
use core::pipes::{Port, Chan};
pub use gfx::opts::{Opts, Png, Screen}; // FIXME: Do we really want "Screen" and "Png" visible?
pub use gfx::resource;
pub use gfx::resource::image_cache_task::ImageCacheTask;
pub use gfx::resource::resource_task::ResourceTask;
pub use gfx::text;
pub use gfx::util::url::make_url;
fn main() {
let args = os::args();
run(&gfx::opts::from_cmdline_args(args))
}
#[allow(non_implicitly_copyable_typarams)]
fn run(opts: &Opts) {
match opts.render_mode {
Screen => run_pipeline_screen(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, outfile)
}
}
}
fn run_pipeline_screen(opts: &Opts) {
let (dom_event_chan, dom_event_port) = pipes::stream();
let dom_event_chan = pipes::SharedChan(move dom_event_chan);
// The platform event handler thread
let osmain = OSMain(dom_event_chan.clone(), copy *opts);
// Send each file to render then wait for keypress
let (keypress_to_engine, keypress_from_osmain) = pipes::stream();
osmain.chan.send(AddKeyHandler(move keypress_to_engine));
// Create a servo instance
let resource_task = ResourceTask();
let image_cache_task = ImageCacheTask(copy resource_task);
let engine_task = Engine(osmain, opts, move dom_event_port, move dom_event_chan,
move resource_task, move image_cache_task);
for opts.urls.each |filename| {
let url = make_url(copy *filename, None);
#debug["master: Sending url `%s`", url.to_str()];
engine_task.send(LoadURLMsg(move url));
#debug["master: Waiting for keypress"];
match keypress_from_osmain.try_recv() {
Some(*) => { }
None => { #error("keypress stream closed unexpectedly") }
};
}
// Shut everything down
#debug["master: Shut down"];
let (exit_chan, exit_response_from_engine) = pipes::stream();
engine_task.send(engine::ExitMsg(move exit_chan));
exit_response_from_engine.recv();
osmain.chan.send(platform::osmain::Exit);
}
fn run_pipeline_png(_opts: &Opts, _outfile: &str) {
fail ~"PNG compositor is broken";
}
#[cfg(broken)]
fn run_pipeline_png(url: ~str, outfile: &str) {
// Use a PNG encoder as the graphics compositor
use gfx::png_compositor;
use png_compositor::PngCompositor;
use io::{Writer, buffered_file_writer};
use resource::resource_task::ResourceTask;
use resource::image_cache_task::SyncImageCacheTask;
listen(|pngdata_from_compositor| {
let (dom_event_chan, dom_event_port) = pipes::stream();
let dom_event_chan = pipes::SharedChan(move dom_event_chan);
let compositor = PngCompositor(pngdata_from_compositor);
let resource_task = ResourceTask();
// For the PNG pipeline we are using a synchronous image task so that all images will be
// fulfilled before the first paint.
let image_cache_task = SyncImageCacheTask(resource_task);
let engine_task = Engine(copy compositor, move dom_event_port, move dom_event_chan,
move resource_task, move image_cache_task);
engine_task.send(LoadURLMsg(make_url(copy url, None)));
match buffered_file_writer(&Path(outfile)) {
Ok(writer) => writer.write(pngdata_from_compositor.recv()),
Err(e) => fail e
}
let (exit_chan, exit_response_from_engine) = pipes::stream();
engine_task.send(engine::ExitMsg(move exit_chan));
exit_response_from_engine.recv();
compositor.send(png_compositor::Exit);
})
}

View file

@ -1,3 +1,5 @@
pub use gfx::util::cache; pub use gfx::util::cache;
pub use gfx::util::time; pub use gfx::util::time;
pub mod actor;
pub mod tree;