servo: Upgrade for language changes

Source-Repo: https://github.com/servo/servo
Source-Revision: 0458783bc798737d6772784b5805b6deb1b6ba9f
This commit is contained in:
Patrick Walton 2013-02-08 21:50:37 -08:00
parent 4af01fc238
commit 733059dd4c
53 changed files with 735 additions and 660 deletions

4
servo/configure vendored
View File

@ -391,7 +391,7 @@ if [ $CFG_OSTYPE = "apple-darwin" ]
then
# pkg-config is installed in a different place on mac (via homebrew? not sure)
# and the way to set this seems to be calling aclocal by hand (instead of via autoreconf)
OSX_PKG_CONFIG_M4_MACROS="-I/usr/local/share/aclocal"
OSX_PKG_CONFIG_M4_MACROS="-I/usr/share/aclocal -I/usr/local/share/aclocal"
LIBTOOLIZE=glibtoolize
else
OSX_PKG_CONFIG_M4_MACROS=""
@ -400,7 +400,7 @@ fi
PIXMAN_ACLOCALCMD="aclocal ${OSX_PKG_CONFIG_M4_MACROS}"
CAIRO_ACLOCALCMD="aclocal ${OSX_PKG_CONFIG_M4_MACROS} -Ibuild"
AUTOCMD="${LIBTOOLIZE} && autoconf && autoheader && automake --add-missing --copy --no-force"
AUTOCMD="${LIBTOOLIZE} && autoconf && autoheader && automake --add-missing --copy --force"
# Copied from cairo's autogen.sh. Build fails without
CAIRO_BOILERPLATE="touch boilerplate/Makefile.am.features && touch src/Makefile.am.features"
PIXMAN_AUTOCMD="${PIXMAN_ACLOCALCMD} && ${AUTOCMD}"

View File

@ -90,18 +90,11 @@ pub struct DisplayList {
list: ~[~DisplayItem]
}
trait DisplayListMethods {
fn append_item(&mut self, item: ~DisplayItem);
fn draw_into_context(ctx: &RenderContext);
}
pub impl DisplayList {
static fn new() -> DisplayList {
DisplayList { list: ~[] }
}
}
impl DisplayList : DisplayListMethods {
fn append_item(&mut self, item: ~DisplayItem) {
// FIXME(Issue #150): crashes
//debug!("Adding display item %u: %?", self.len(), item);

View File

@ -4,9 +4,11 @@ use geometry::Au;
use render_context::RenderContext;
use util::range::Range;
use text::glyph::{GlyphStore, GlyphIndex};
use text::shaper::ShaperMethods;
use text::{Shaper, TextRun};
use azure::{AzFloat, AzScaledFontRef};
use azure::{AzFloat, AzScaledFontRef, struct__AzDrawOptions, struct__AzGlyph};
use azure::{struct__AzGlyphBuffer, struct__AzPoint};
use azure::scaled_font::ScaledFont;
use azure::azure_hl::{BackendType, ColorPattern};
use core::dvec::DVec;
@ -374,26 +376,8 @@ pub impl Font {
}
}
// Public API
pub trait FontMethods {
fn draw_text_into_context(rctx: &RenderContext,
run: &TextRun,
range: &Range,
baseline_origin: Point2D<Au>,
color: Color);
// This calculates run metrics for the specified character range
// within the provided textrun.
fn measure_text(&TextRun, &const Range) -> RunMetrics;
fn shape_text(@self, &str, &mut GlyphStore);
fn get_descriptor() -> FontDescriptor;
// these are used to get glyphs and advances in the case that the
// shaper can't figure it out.
fn glyph_index(char) -> Option<GlyphIndex>;
fn glyph_h_advance(GlyphIndex) -> FractionalPixel;
}
pub impl Font : FontMethods {
pub impl Font {
fn draw_text_into_context(rctx: &RenderContext,
run: &TextRun,
range: &const Range,
@ -413,7 +397,7 @@ pub impl Font : FontMethods {
let azure_pattern = pattern.azure_color_pattern;
assert azure_pattern.is_not_null();
let options: AzDrawOptions = {
let options = struct__AzDrawOptions {
mAlpha: 1f as AzFloat,
fields: 0x0200 as uint16_t
};
@ -426,9 +410,9 @@ pub impl Font : FontMethods {
let glyph_advance = glyph.advance();
let glyph_offset = glyph.offset().get_or_default(Au::zero_point());
let azglyph: AzGlyph = {
let azglyph = struct__AzGlyph {
mIndex: glyph.index() as uint32_t,
mPosition: {
mPosition: struct__AzPoint {
x: (origin.x + glyph_offset.x).to_px() as AzFloat,
y: (origin.y + glyph_offset.y).to_px() as AzFloat
}
@ -441,10 +425,12 @@ pub impl Font : FontMethods {
if azglyph_buf_len == 0 { return; } // Otherwise the Quartz backend will assert.
let azglyph_buf = dvec::unwrap(move azglyphs);
let glyphbuf: AzGlyphBuffer = unsafe {{
mGlyphs: vec::raw::to_ptr(azglyph_buf),
mNumGlyphs: azglyph_buf_len as uint32_t
}};
let glyphbuf = unsafe {
struct__AzGlyphBuffer {
mGlyphs: vec::raw::to_ptr(azglyph_buf),
mNumGlyphs: azglyph_buf_len as uint32_t
}
};
// TODO(Issue #64): this call needs to move into azure_hl.rs
AzDrawTargetFillGlyphs(target.azure_draw_target,

View File

@ -1,4 +1,5 @@
use font::{CSSFontWeight, SpecifiedFontStyle, UsedFontStyle};
use gfx_font::FontHandleMethods;
use native::FontHandle;
use dvec::DVec;
@ -82,13 +83,13 @@ pub impl FontList {
priv fn find_family(family_name: &str) -> Option<@FontFamily> {
// look up canonical name
let family = self.family_map.find_copy(&str::from_slice(family_name));
let family = self.family_map.find(&str::from_slice(family_name));
let decision = if family.is_some() { "Found" } else { "Couldn't find" };
debug!("FontList: %s font family with name=%s", decision, family_name);
// TODO(Issue #188): look up localized font family names if canonical name not found
return family;
return family.map(|f| **f);
}
}

View File

@ -92,7 +92,7 @@ pub struct FreeTypeFontHandle {
drop {
assert self.face.is_not_null();
if !FT_Done_Face(self.face).succeeded() {
fail ~"FT_Done_Face failed";
fail!(~"FT_Done_Face failed");
}
}
}
@ -186,7 +186,6 @@ pub impl FreeTypeFontHandle {
}
pub impl FreeTypeFontHandle : FontHandleMethods {
// an identifier usable by FontContextHandle to recreate this FontHandle.
pure fn face_identifier() -> ~str {
/* FT_Get_Postscript_Name seems like a better choice here, but it

View File

@ -1,33 +1,43 @@
use geom::point::Point2D;
use geom::rect::Rect;
use geom::size::Size2D;
use num::Num;
pub enum Au = i32;
use core::num::NumCast;
impl Au : Num {
pure fn add(&self, other: &Au) -> Au { Au(**self + **other) }
pure fn sub(&self, other: &Au) -> Au { Au(**self - **other) }
pure fn mul(&self, other: &Au) -> Au { Au(**self * **other) }
pure fn div(&self, other: &Au) -> Au { Au(**self / **other) }
pure fn modulo(&self, other: &Au) -> Au { Au(**self % **other) }
pure fn neg(&self) -> Au { Au(-**self) }
pub struct Au(i32);
pure fn to_int(&self) -> int { **self as int }
static pure fn from_int(n: int) -> Au {
Au((n & (i32::max_value as int)) as i32)
}
pub impl Add<Au,Au> for Au {
pure fn add(&self, other: &Au) -> Au { Au(**self + **other) }
}
impl Au : cmp::Ord {
pub impl Sub<Au,Au> for Au {
pure fn sub(&self, other: &Au) -> Au { Au(**self - **other) }
}
pub impl Mul<Au,Au> for Au {
pure fn mul(&self, other: &Au) -> Au { Au(**self * **other) }
}
pub impl Div<Au,Au> for Au {
pure fn div(&self, other: &Au) -> Au { Au(**self / **other) }
}
pub impl Modulo<Au,Au> for Au {
pure fn modulo(&self, other: &Au) -> Au { Au(**self % **other) }
}
pub impl Neg<Au> for Au {
pure fn neg(&self) -> Au { Au(-**self) }
}
pub impl cmp::Ord for Au {
pure fn lt(&self, other: &Au) -> bool { **self < **other }
pure fn le(&self, other: &Au) -> bool { **self <= **other }
pure fn ge(&self, other: &Au) -> bool { **self >= **other }
pure fn gt(&self, other: &Au) -> bool { **self > **other }
}
impl Au : cmp::Eq {
pub impl cmp::Eq for Au {
pure fn eq(&self, other: &Au) -> bool { **self == **other }
pure fn ne(&self, other: &Au) -> bool { **self != **other }
}
@ -35,17 +45,37 @@ impl Au : cmp::Eq {
pub pure fn min(x: Au, y: Au) -> Au { if x < y { x } else { y } }
pub pure fn max(x: Au, y: Au) -> Au { if x > y { x } else { y } }
pub fn box<A:Copy Num>(x: A, y: A, w: A, h: A) -> Rect<A> {
impl NumCast for Au {
static pure fn from<T:NumCast>(n: T) -> Au { Au(n.to_i32()) }
pure fn to_u8(&self) -> u8 { (**self).to_u8() }
pure fn to_u16(&self) -> u16 { (**self).to_u16() }
pure fn to_u32(&self) -> u32 { (**self).to_u32() }
pure fn to_u64(&self) -> u64 { (**self).to_u64() }
pure fn to_uint(&self) -> uint { (**self).to_uint() }
pure fn to_i8(&self) -> i8 { (**self).to_i8() }
pure fn to_i16(&self) -> i16 { (**self).to_i16() }
pure fn to_i32(&self) -> i32 { (**self).to_i32() }
pure fn to_i64(&self) -> i64 { (**self).to_i64() }
pure fn to_int(&self) -> int { (**self).to_int() }
pure fn to_f32(&self) -> f32 { (**self).to_f32() }
pure fn to_f64(&self) -> f64 { (**self).to_f64() }
pure fn to_float(&self) -> float { (**self).to_float() }
}
pub fn box<T:Copy + Ord + Add<T,T> + Sub<T,T>>(x: T, y: T, w: T, h: T) -> Rect<T> {
Rect(Point2D(x, y), Size2D(w, h))
}
impl Au {
pub impl Au {
pub pure fn scale_by(factor: float) -> Au {
Au(((*self as float) * factor) as i32)
}
static pub pure fn from_px(i: int) -> Au {
Num::from_int(i * 60)
NumCast::from(i * 60)
}
pub pure fn to_px(&const self) -> int {
@ -98,7 +128,7 @@ pub pure fn from_frac_px(f: float) -> Au {
}
pub pure fn from_px(i: int) -> Au {
Num::from_int(i * 60)
NumCast::from(i * 60)
}
pub pure fn to_px(au: Au) -> int {

View File

@ -32,7 +32,7 @@ pub fn load_from_memory(buffer: &[u8]) -> Option<Image> {
1 => image.data[pixel * 4 + 1],
2 => image.data[pixel * 4 + 0],
3 => 0xffu8,
_ => fail
_ => fail!()
}
};
@ -40,7 +40,7 @@ pub fn load_from_memory(buffer: &[u8]) -> Option<Image> {
Some(Image(image.width, image.height, image.depth, move data))
}
stb_image::ImageF32(_image) => fail ~"HDR images not implemented",
stb_image::ImageF32(_image) => fail!(~"HDR images not implemented"),
stb_image::Error => None
}
}

View File

@ -1,7 +1,7 @@
use io::WriterUtil;
use surface;
fn encode(writer: io::Writer, surface: &surface::image_surface) {
fn encode(writer: io::Writer, surface: &surface::ImageSurface) {
assert surface.format == surface::fo_rgba_8888;
writer.write_u8(0u8); // identsize

View File

@ -32,11 +32,11 @@ pub fn from_cmdline_args(args: &[~str]) -> Opts {
let opt_match = match getopts::getopts(args, opts) {
result::Ok(m) => { copy m }
result::Err(f) => { fail getopts::fail_str(copy f) }
result::Err(f) => { fail!(getopts::fail_str(copy f)) }
};
let urls = if opt_match.free.is_empty() {
fail ~"servo asks that you provide 1 or more URLs"
fail!(~"servo asks that you provide 1 or more URLs")
} else {
copy opt_match.free
};
@ -59,7 +59,7 @@ pub fn from_cmdline_args(args: &[~str]) -> Opts {
} else if backend_str == ~"skia" {
SkiaBackend
} else {
fail ~"unknown backend type"
fail!(~"unknown backend type")
}
}
None => CairoBackend

View File

@ -14,7 +14,8 @@ use quartz::font_list::core_text::font_descriptor::{debug_descriptor};
use quartz::font::QuartzFontHandle;
use quartz::font_context::QuartzFontContextHandle;
use gfx_font::FontHandle;
use gfx_font::{FontHandle, FontHandleMethods};
use gfx_font_context::FontContextHandleMethods;
use gfx_font_list::{FontEntry, FontFamily, FontFamilyMap};
use core::dvec::DVec;

View File

@ -1,17 +1,19 @@
// The task that handles all rendering/painting.
use azure::AzFloat;
use compositor::{Compositor, LayerBufferSet};
use font_context::FontContext;
use geom::matrix2d::Matrix2D;
use opts::Opts;
use render_context::RenderContext;
use render_layers::{RenderLayer, render_layers};
use resource::util::spawn_listener;
use util::time::time;
use azure::AzFloat;
use core::oldcomm::*;
use core::libc::size_t;
use core::libc::types::common::c99::uint16_t;
use core::pipes::{Port, Chan};
use core::pipes::{Chan, Port, SharedChan};
use core::task::SingleThreaded;
use geom::matrix2d::Matrix2D;
use std::arc::ARC;
use std::arc;
use std::cell::Cell;
@ -22,12 +24,12 @@ pub enum Msg {
ExitMsg(pipes::Chan<()>)
}
pub type RenderTask = oldcomm::Chan<Msg>;
pub type RenderTask = SharedChan<Msg>;
pub fn RenderTask<C: Compositor Owned>(compositor: C, opts: Opts) -> RenderTask {
pub fn RenderTask<C:Compositor + Owned>(compositor: C, opts: Opts) -> RenderTask {
let compositor_cell = Cell(move compositor);
let opts_cell = Cell(move opts);
do spawn_listener |po: oldcomm::Port<Msg>, move compositor_cell, move opts_cell| {
let render_task = do spawn_listener |po: Port<Msg>| {
let (layer_buffer_set_port, layer_buffer_channel) = pipes::stream();
let compositor = compositor_cell.take();
@ -58,7 +60,8 @@ pub fn RenderTask<C: Compositor Owned>(compositor: C, opts: Opts) -> RenderTask
thread_pool: move thread_pool,
opts: opts_cell.take()
}.start();
}
};
SharedChan(render_task)
}
/// Data that needs to be kept around for each render thread.
@ -68,8 +71,8 @@ priv struct ThreadRenderContext {
opts: Opts,
}
priv struct Renderer<C: Compositor Owned> {
port: oldcomm::Port<Msg>,
priv struct Renderer<C> {
port: Port<Msg>,
compositor: C,
layer_buffer_set_port: Cell<pipes::Port<LayerBufferSet>>,
thread_pool: TaskPool<ThreadRenderContext>,

View File

@ -1,29 +1,29 @@
export factory;
use oldcomm::Chan;
use pipes::Chan;
use task::spawn;
use resource::resource_task::{ProgressMsg, Payload, Done};
use resource::resource_task::{ProgressMsg, Payload, Done, LoaderTask};
use std::net::url::Url;
use io::{file_reader, ReaderUtil};
const READ_SIZE: uint = 1024;
pub fn factory(url: Url, progress_chan: Chan<ProgressMsg>) {
assert url.scheme == ~"file";
do spawn |move url| {
// FIXME: Resolve bug prevents us from moving the path out of the URL.
match file_reader(&Path(url.path)) {
Ok(reader) => {
while !reader.eof() {
let data = reader.read_bytes(READ_SIZE);
progress_chan.send(Payload(move data));
}
progress_chan.send(Done(Ok(())));
}
Err(*) => {
progress_chan.send(Done(Err(())));
}
};
}
pub fn factory() -> LoaderTask {
let f: LoaderTask = |url, progress_chan| {
assert url.scheme == ~"file";
do spawn {
// FIXME: Resolve bug prevents us from moving the path out of the URL.
match file_reader(&Path(url.path)) {
Ok(reader) => {
while !reader.eof() {
let data = reader.read_bytes(READ_SIZE);
progress_chan.send(Payload(move data));
}
progress_chan.send(Done(Ok(())));
}
Err(*) => {
progress_chan.send(Done(Err(())));
}
};
}
};
f
}

View File

@ -1,39 +1,46 @@
export factory;
use oldcomm::Chan;
use pipes::{Chan, SharedChan};
use task::spawn;
use resource::resource_task::{ProgressMsg, Payload, Done};
use resource::resource_task::{ProgressMsg, Payload, Done, LoaderTask};
use std::cell::Cell;
use std::net::url::Url;
use http_client;
use http_client::{uv_http_request};
pub fn factory(url: Url, progress_chan: Chan<ProgressMsg>) {
assert url.scheme == ~"http";
pub fn factory() -> LoaderTask {
let f: LoaderTask = |url, progress_chan| {
assert url.scheme == ~"http";
do spawn |move url| {
debug!("http_loader: requesting via http: %?", copy url);
let request = uv_http_request(copy url);
let errored = @mut false;
do request.begin |event, copy url| {
let url = copy url;
match event {
http_client::Status(*) => { }
http_client::Payload(data) => {
debug!("http_loader: got data from %?", url);
let mut junk = None;
*data <-> junk;
progress_chan.send(Payload(option::unwrap(move junk)));
}
http_client::Error(*) => {
debug!("http_loader: error loading %?", url);
*errored = true;
progress_chan.send(Done(Err(())));
}
}
}
let progress_chan = SharedChan(progress_chan);
do spawn {
debug!("http_loader: requesting via http: %?", copy url);
let request = uv_http_request(copy url);
let errored = @mut false;
let url = copy url;
{
let progress_chan = progress_chan.clone();
do request.begin |event| {
let url = copy url;
match event {
http_client::Status(*) => { }
http_client::Payload(data) => {
debug!("http_loader: got data from %?", url);
let mut junk = None;
*data <-> junk;
progress_chan.send(Payload(option::unwrap(move junk)));
}
http_client::Error(*) => {
debug!("http_loader: error loading %?", url);
*errored = true;
progress_chan.send(Done(Err(())));
}
}
}
}
if !*errored {
progress_chan.send(Done(Ok(())));
}
}
if !*errored {
progress_chan.send(Done(Ok(())));
}
}
};
f
}

View File

@ -62,7 +62,7 @@ impl ImageResponseMsg: cmp::Eq {
pure fn eq(&self, other: &ImageResponseMsg) -> bool {
// FIXME: Bad copies
match (self.clone(), other.clone()) {
(ImageReady(*), ImageReady(*)) => fail ~"unimplemented comparison",
(ImageReady(*), ImageReady(*)) => fail!(~"unimplemented comparison"),
(ImageNotReady, ImageNotReady) => true,
(ImageFailed, ImageFailed) => true,
@ -84,7 +84,9 @@ pub fn ImageCacheTask(resource_task: ResourceTask) -> ImageCacheTask {
ImageCacheTask_(resource_task, default_decoder_factory)
}
pub fn ImageCacheTask_(resource_task: ResourceTask, decoder_factory: DecoderFactory) -> ImageCacheTask {
pub fn ImageCacheTask_(resource_task: ResourceTask,
decoder_factory: DecoderFactory)
-> ImageCacheTask {
// FIXME: Doing some dancing to avoid copying decoder_factory, our test
// version of which contains an uncopyable type which rust will currently
// copy unsoundly
@ -95,9 +97,9 @@ pub fn ImageCacheTask_(resource_task: ResourceTask, decoder_factory: DecoderFact
let port_cell = Cell(move port);
let chan_cell = Cell(chan.clone());
do spawn |move port_cell, move chan_cell, move decoder_factory_cell| {
do spawn {
ImageCache {
resource_task: resource_task,
resource_task: resource_task.clone(),
decoder_factory: decoder_factory_cell.take(),
port: port_cell.take(),
chan: chan_cell.take(),
@ -114,9 +116,9 @@ fn SyncImageCacheTask(resource_task: ResourceTask) -> ImageCacheTask {
let (port, chan) = stream();
let port_cell = Cell(move port);
do spawn |move port_cell, move resource_task| {
do spawn {
let port = port_cell.take();
let inner_cache = ImageCacheTask(resource_task);
let inner_cache = ImageCacheTask(resource_task.clone());
loop {
let msg: Msg = port.recv();
@ -177,7 +179,9 @@ impl ImageCache {
loop {
let msg = self.port.recv();
for msg_handlers.each |handler| { (*handler)(&msg) }
for msg_handlers.each |handler| {
(*handler)(&msg)
}
debug!("image_cache_task: received: %?", msg);
@ -192,7 +196,7 @@ impl ImageCache {
WaitForImage(move url, move response) => {
self.wait_for_image(move url, move response)
}
OnMsg(move handler) => msg_handlers += [move handler],
OnMsg(move handler) => msg_handlers.push(handler),
Exit(move response) => {
assert self.need_exit.is_none();
self.need_exit = Some(move response);
@ -207,14 +211,11 @@ impl ImageCache {
// before exiting
let mut can_exit = true;
for self.state_map.each_value |state| {
match state {
Prefetching(*) => can_exit = false,
Decoding => can_exit = false,
match *state {
Prefetching(*) => can_exit = false,
Decoding => can_exit = false,
Init
| Prefetched(*)
| Decoded(*)
| Failed => ()
Init | Prefetched(*) | Decoded(*) | Failed => ()
}
}
@ -231,7 +232,7 @@ impl ImageCache {
}
priv fn get_state(url: Url) -> ImageState {
match move self.state_map.find(move url) {
match move self.state_map.find(&url) {
Some(move state) => move state,
None => Init
}
@ -243,36 +244,32 @@ impl ImageCache {
priv fn prefetch(url: Url) {
match self.get_state(copy url) {
Init => {
let to_cache = self.chan.clone();
let resource_task = self.resource_task;
let url_cell = Cell(copy url);
Init => {
let to_cache = self.chan.clone();
let resource_task = self.resource_task.clone();
let url_cell = Cell(copy url);
do spawn |move to_cache, move url_cell| {
let url = url_cell.take();
debug!("image_cache_task: started fetch for %s", url.to_str());
do spawn {
let url = url_cell.take();
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.clone());
let result = if image.is_ok() {
Ok(Cell(result::unwrap(move image)))
} else {
Err(())
};
to_cache.send(StorePrefetchedImageData(copy url, move result));
debug!("image_cache_task: ended fetch for %s", (copy url).to_str());
let result = if image.is_ok() {
Ok(Cell(result::unwrap(move image)))
} else {
Err(())
};
to_cache.send(StorePrefetchedImageData(copy url, move result));
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));
}
Prefetching(*)
| Prefetched(*)
| Decoding
| Decoded(*)
| Failed => {
// We've already begun working on this image
}
Prefetching(*) | Prefetched(*) | Decoding | Decoded(*) | Failed => {
// We've already begun working on this image
}
}
}
@ -300,14 +297,14 @@ impl ImageCache {
| Decoding
| Decoded(*)
| Failed => {
fail ~"wrong state for storing prefetched image"
fail!(~"wrong state for storing prefetched image")
}
}
}
priv fn decode(url: Url) {
match self.get_state(copy url) {
Init => fail ~"decoding image before prefetch",
Init => fail!(~"decoding image before prefetch"),
Prefetching(DoNotDecode) => {
// We don't have the data yet, queue up the decode
@ -369,14 +366,13 @@ impl ImageCache {
| Prefetched(*)
| Decoded(*)
| Failed => {
fail ~"incorrect state in store_image"
fail!(~"incorrect state in store_image")
}
}
}
priv fn purge_waiters(url: Url, f: fn() -> ImageResponseMsg) {
match self.wait_map.find(copy url) {
Some(waiters) => {
let waiters = &mut *waiters;
let mut new_waiters = ~[];
@ -387,7 +383,7 @@ impl ImageCache {
}
*waiters <-> new_waiters;
self.wait_map.remove(move url);
self.wait_map.remove(&url);
}
None => ()
}
@ -395,16 +391,15 @@ impl ImageCache {
priv fn get_image(url: Url, response: Chan<ImageResponseMsg>) {
match self.get_state(copy url) {
Init => fail ~"request for image before prefetch",
Init => fail!(~"request for image before prefetch"),
Prefetching(DoDecode) => {
response.send(ImageNotReady);
}
Prefetching(DoNotDecode)
| Prefetched(*) => fail ~"request for image before decode",
| Prefetched(*) => fail!(~"request for image before decode"),
Decoding => {
response.send(ImageNotReady)
@ -422,13 +417,13 @@ impl ImageCache {
priv fn wait_for_image(url: Url, response: Chan<ImageResponseMsg>) {
match self.get_state(copy url) {
Init => fail ~"request for image before prefetch",
Init => fail!(~"request for image before prefetch"),
Prefetching(DoNotDecode) | Prefetched(*) => fail ~"request for image before decode",
Prefetching(DoNotDecode) | Prefetched(*) => fail!(~"request for image before decode"),
Prefetching(DoDecode) | Decoding => {
// We don't have this image yet
match self.wait_map.find(copy url) {
match self.wait_map.find(&url) {
Some(waiters) => {
vec::push(&mut *waiters, move response);
}
@ -466,8 +461,8 @@ impl ImageCacheTask: ImageCacheTaskClient {
}
fn load_image_data(url: Url, resource_task: ResourceTask) -> Result<~[u8], ()> {
let response_port = oldcomm::Port();
resource_task.send(resource_task::Load(move url, response_port.chan()));
let (response_port, response_chan) = stream();
resource_task.send(resource_task::Load(move url, response_chan));
let mut image_data = ~[];
@ -491,8 +486,8 @@ fn default_decoder_factory() -> ~fn(&[u8]) -> Option<Image> {
}
#[cfg(test)]
fn mock_resource_task(on_load: ~fn(resource: oldcomm::Chan<resource_task::ProgressMsg>)) -> ResourceTask {
do spawn_listener |port: oldcomm::Port<resource_task::ControlMsg>, move on_load| {
fn mock_resource_task(on_load: ~fn(resource: Chan<resource_task::ProgressMsg>)) -> ResourceTask {
do spawn_listener |port: Port<resource_task::ControlMsg>, move on_load| {
loop {
match port.recv() {
resource_task::Load(_, response) => {
@ -532,7 +527,7 @@ fn should_fail_if_unprefetched_image_is_requested() {
#[test]
fn should_request_url_from_resource_task_on_prefetch() {
let url_requested = oldcomm::Port();
let url_requested = Port();
let url_requested_chan = url_requested.chan();
let mock_resource_task = do mock_resource_task |response| {

View File

@ -133,7 +133,7 @@ pub impl LocalImageCache {
}
priv fn get_state(url: &Url) -> @ImageState {
match self.state_map.find(copy *url) {
match self.state_map.find(url) {
Some(state) => state,
None => {
let new_state = @ImageState {

View File

@ -4,8 +4,9 @@ A task that takes a URL and streams back the binary data
*/
use oldcomm::{Chan, Port};
use pipes::{Chan, Port, SharedChan};
use resource::util::spawn_listener;
use std::cell::Cell;
use std::net::url;
use std::net::url::{Url, to_str};
use super::{file_loader, http_loader};
@ -17,6 +18,7 @@ pub enum ControlMsg {
}
/// Messages sent in response to a `Load` message
#[deriving_eq]
pub enum ProgressMsg {
/// Binary data - there may be multiple of these
Payload(~[u8]),
@ -24,24 +26,8 @@ pub enum ProgressMsg {
Done(Result<(), ()>)
}
impl ProgressMsg: cmp::Eq {
pure fn eq(&self, other: &ProgressMsg) -> bool {
// FIXME: Bad copies
match (copy *self, copy *other) {
(Payload(a), Payload(b)) => a == b,
(Done(a), Done(b)) => a == b,
(Payload(*), _)
| (Done(*), _) => false
}
}
pure fn ne(&self, other: &ProgressMsg) -> bool {
return !(*self).eq(other);
}
}
/// Handle to a resource task
pub type ResourceTask = Chan<ControlMsg>;
pub type ResourceTask = SharedChan<ControlMsg>;
/**
Creates a task to load a specific resource
@ -49,7 +35,9 @@ Creates a task to load a specific resource
The ResourceManager delegates loading to a different type of loader task for
each URL scheme
*/
type LoaderTaskFactory = fn~(url: Url, Chan<ProgressMsg>);
type LoaderTaskFactory = ~fn() -> ~fn(url: Url, Chan<ProgressMsg>);
pub type LoaderTask = ~fn(url: Url, Chan<ProgressMsg>);
/// Create a ResourceTask with the default loaders
pub fn ResourceTask() -> ResourceTask {
@ -63,10 +51,12 @@ pub fn ResourceTask() -> ResourceTask {
}
fn create_resource_task_with_loaders(loaders: ~[(~str, LoaderTaskFactory)]) -> ResourceTask {
do spawn_listener |from_client, move loaders| {
let loaders_cell = Cell(loaders);
let chan = do spawn_listener |from_client| {
// TODO: change copy to move once we can move out of closures
ResourceManager(from_client, copy loaders).start()
}
ResourceManager(from_client, loaders_cell.take()).start()
};
SharedChan(chan)
}
pub struct ResourceManager {
@ -113,12 +103,15 @@ impl ResourceManager {
}
}
fn get_loader_factory(url: &Url) -> Option<LoaderTaskFactory> {
fn get_loader_factory(url: &Url) -> Option<LoaderTask> {
for self.loaders.each |scheme_loader| {
let (scheme, loader_factory) = copy *scheme_loader;
if scheme == url.scheme {
return Some(move loader_factory);
}
match *scheme_loader {
(ref scheme, ref loader_factory) => {
if (*scheme) == url.scheme {
return Some((*loader_factory)());
}
}
}
}
return None;
}

View File

@ -1,12 +1,12 @@
pub fn spawn_listener<A: Owned>(
f: fn~(oldcomm::Port<A>)) -> oldcomm::Chan<A> {
let setup_po = oldcomm::Port();
let setup_ch = oldcomm::Chan(&setup_po);
use core::pipes::{Chan, Port};
use core::pipes;
pub fn spawn_listener<A: Owned>(f: ~fn(Port<A>)) -> Chan<A> {
let (setup_po, setup_ch) = pipes::stream();
do task::spawn |move f| {
let po = oldcomm::Port();
let ch = oldcomm::Chan(&po);
oldcomm::send(setup_ch, ch);
let (po, ch) = pipes::stream();
setup_ch.send(ch);
f(move po);
}
oldcomm::recv(setup_po)
setup_po.recv()
}

View File

@ -1,27 +1,11 @@
use geom::size::Size2D;
#[deriving_eq]
pub enum format {
fo_rgba_8888
// TODO: RGB 565, others?
}
impl format: cmp::Eq {
pure fn eq(&self, other: &format) -> bool {
match (*self, *other) {
(fo_rgba_8888, fo_rgba_8888) => true,
}
}
pure fn ne(&self, other: &format) -> bool {
return !self.eq(other);
}
}
pub type image_surface = {
size: Size2D<int>,
format: format,
buffer: ~[u8]
};
impl format {
fn bpp() -> uint {
match self {
@ -30,11 +14,19 @@ impl format {
}
}
pub fn image_surface(size: Size2D<int>, format: format) -> image_surface {
{
size: copy size,
format: format,
buffer: vec::from_elem((size.area() as uint) * format.bpp(), 0u8)
}
pub struct ImageSurface {
size: Size2D<int>,
format: format,
buffer: ~[u8]
}
impl ImageSurface {
static pub fn new(size: Size2D<int>, format: format) -> ImageSurface {
ImageSurface {
size: copy size,
format: format,
buffer: vec::from_elem((size.area() as uint) * format.bpp(), 0u8)
}
}
}

View File

@ -6,10 +6,10 @@ use geometry;
use core;
use core::cmp::{Ord, Eq};
use core::dvec::DVec;
use core::num::NumCast;
use core::u16;
use geom::point::Point2D;
use std::sort;
use num::Num;
// GlyphEntry is a port of Gecko's CompressedGlyph scheme for storing
@ -174,7 +174,7 @@ impl GlyphEntry {
#[inline(always)]
pure fn advance() -> Au {
//assert self.is_simple();
Num::from_int(((self.value & GLYPH_ADVANCE_MASK) >> GLYPH_ADVANCE_SHIFT) as int)
NumCast::from((self.value & GLYPH_ADVANCE_MASK) >> GLYPH_ADVANCE_SHIFT)
}
pure fn index() -> GlyphIndex {
@ -375,7 +375,7 @@ impl DetailedGlyphStore {
// FIXME: This is a workaround for borrow of self.detail_lookup not getting inferred.
let records : &[DetailedGlyphRecord] = self.detail_lookup;
match records.binary_search_index(&key) {
None => fail ~"Invalid index not found in detailed glyph lookup table!",
None => fail!(~"Invalid index not found in detailed glyph lookup table!"),
Some(i) => {
assert i + (count as uint) <= self.detail_buffer.len();
// return a view into the buffer
@ -384,7 +384,10 @@ impl DetailedGlyphStore {
}
}
pure fn get_detailed_glyph_with_index(&self, entry_offset: uint, detail_offset: u16) -> &self/DetailedGlyph {
pure fn get_detailed_glyph_with_index(&self,
entry_offset: uint,
detail_offset: u16)
-> &self/DetailedGlyph {
assert (detail_offset as uint) <= self.detail_buffer.len();
assert self.lookup_is_sorted;
@ -396,7 +399,7 @@ impl DetailedGlyphStore {
// FIXME: This is a workaround for borrow of self.detail_lookup not getting inferred.
let records : &[DetailedGlyphRecord] = self.detail_lookup;
match records.binary_search_index(&key) {
None => fail ~"Invalid index not found in detailed glyph lookup table!",
None => fail!(~"Invalid index not found in detailed glyph lookup table!"),
Some(i) => {
assert i + (detail_offset as uint) < self.detail_buffer.len();
&self.detail_buffer[i+(detail_offset as uint)]

View File

@ -4,7 +4,7 @@ use geom::Point2D;
use geometry::Au;
use font::{Font, FontTable, FontTableTag};
use font::{Font, FontTable, FontTableMethods, FontTableTag};
use text::glyph::{GlyphStore, GlyphIndex, GlyphData};
use text::shaper::ShaperMethods;
@ -202,7 +202,7 @@ pub impl HarfbuzzShaper {
}
}
pub impl HarfbuzzShaper : ShaperMethods {
impl ShaperMethods for HarfbuzzShaper {
/**
Calculate the layout metrics associated with a some given text
when rendered in a specific font.

View File

@ -12,7 +12,6 @@ pub type Shaper/& = harfbuzz::shaper::HarfbuzzShaper;
pub trait ShaperMethods {
fn shape_text(text: &str, glyphs: &mut GlyphStore);
}
// TODO(Issue #163): this is a workaround for static methods and

View File

@ -28,7 +28,7 @@ impl SendableTextRun {
pub fn deserialize(&self, fctx: @FontContext) -> TextRun {
let font = match fctx.get_font_by_descriptor(&self.font) {
Ok(f) => f,
Err(_) => fail fmt!("Font descriptor deserialization failed! desc=%?", self.font)
Err(_) => fail!(fmt!("Font descriptor deserialization failed! desc=%?", self.font))
};
TextRun {

View File

@ -1,14 +1,14 @@
use core::cmp::*;
pub trait Cache<K: Copy Eq, V: Copy> {
static fn new(size: uint) -> self;
static fn new(size: uint) -> Self;
fn insert(key: &K, value: V);
fn find(key: &K) -> Option<V>;
fn find_or_create(key: &K, blk: pure fn&(&K) -> V) -> V;
fn evict_all();
}
pub struct MonoCache<K: Copy Eq, V: Copy> {
pub struct MonoCache<K, V> {
mut entry: Option<(K,V)>,
}
@ -56,4 +56,4 @@ fn test_monocache() {
cache.find_or_create(&2, |_v| { two });
assert cache.find(&2).is_some();
assert cache.find(&1).is_none();
}
}

View File

@ -88,8 +88,8 @@ pub impl Range {
let overlap = other.end() - self.begin();
return OverlapsEnd(overlap);
}
fail fmt!("relation_to_range(): didn't classify self=%?, other=%?",
self, other);
fail!(fmt!("relation_to_range(): didn't classify self=%?, other=%?",
self, other));
}
fn repair_after_coalesced_range(&mut self, other: &const Range) {
@ -103,8 +103,10 @@ pub impl Range {
Coincides | ContainedBy => { self.reset(other.begin(), 1); },
Contains => { self.extend_by(-(other.length() as int)); },
OverlapsBegin(overlap) => { self.extend_by(1 - (overlap as int)); },
OverlapsEnd(overlap) =>
{ self.reset(other.begin(), self.length() - overlap + 1); }
OverlapsEnd(overlap) => {
let len = self.length() - overlap + 1;
self.reset(other.begin(), len);
}
};
debug!("repair_after_coalesced_range: new range: ---- %?", self);
}

View File

@ -1,7 +1,7 @@
use core::path::Path;
use std::map::HashMap;
use std::net::url;
use std::net::url::Url;
use std::oldmap::HashMap;
/**
Create a URL object from a string. Does various helpful browsery things like
@ -98,7 +98,7 @@ mod make_url_tests {
}
pub type UrlMap<T: Copy> = HashMap<Url, T>;
pub type UrlMap<T> = HashMap<Url, T>;
pub fn url_map<T: Copy>() -> UrlMap<T> {
use core::to_str::ToStr;

View File

@ -13,7 +13,7 @@ use layout::layout_task::{AddStylesheet, BuildData, BuildMsg, Damage, LayoutTask
use layout::layout_task::{MatchSelectorsDamage, NoDamage, ReflowDamage};
use util::task::spawn_listener;
use core::oldcomm::{Port, Chan, listen, select2};
use core::pipes::{Port, Chan, SharedChan, select2};
use core::either;
use core::task::{SingleThreaded, spawn, task};
use core::io::{println, read_whole_file};
@ -28,7 +28,7 @@ use js::global::{global_class, debug_fns};
use js::glue::bindgen::RUST_JSVAL_TO_OBJECT;
use js::jsapi::{JSContext, JSVal};
use js::jsapi::bindgen::{JS_CallFunctionValue, JS_GetContextPrivate};
use js::rust::{compartment, cx, methods};
use js::rust::{Compartment, Cx};
use jsrt = js::rust::rt;
use newcss::stylesheet::Stylesheet;
use std::arc::{ARC, clone};
@ -49,29 +49,30 @@ pub enum PingMsg {
PongMsg
}
pub type ContentTask = pipes::SharedChan<ControlMsg>;
pub type ContentTask = SharedChan<ControlMsg>;
pub fn ContentTask(layout_task: LayoutTask,
dom_event_port: pipes::Port<Event>,
dom_event_chan: pipes::SharedChan<Event>,
resource_task: ResourceTask,
img_cache_task: ImageCacheTask) -> ContentTask {
dom_event_port: Port<Event>,
dom_event_chan: SharedChan<Event>,
resource_task: ResourceTask,
img_cache_task: ImageCacheTask)
-> ContentTask {
let (control_port, control_chan) = pipes::stream();
let control_chan = pipes::SharedChan(move control_chan);
let control_chan = SharedChan(control_chan);
let control_chan_copy = control_chan.clone();
let control_port = Cell(move control_port);
let dom_event_port = Cell(move dom_event_port);
let dom_event_chan = Cell(move dom_event_chan);
let control_port = Cell(control_port);
let dom_event_port = Cell(dom_event_port);
let dom_event_chan = Cell(dom_event_chan);
do task().sched_mode(SingleThreaded).spawn |move layout_task, move control_port,
move control_chan_copy, move resource_task,
move img_cache_task, move dom_event_port,
move dom_event_chan| {
let content = Content(layout_task, control_port.take(), control_chan_copy.clone(),
resource_task, img_cache_task.clone(),
dom_event_port.take(), dom_event_chan.take());
do task().sched_mode(SingleThreaded).spawn {
let content = Content(layout_task.clone(),
control_port.take(),
control_chan_copy.clone(),
resource_task.clone(),
img_cache_task.clone(),
dom_event_port.take(),
dom_event_chan.take());
content.start();
}
@ -90,7 +91,7 @@ pub struct Content {
scope: NodeScope,
jsrt: jsrt,
cx: cx,
cx: @Cx,
mut document: Option<@Document>,
mut window: Option<@Window>,
@ -99,20 +100,20 @@ pub struct Content {
resource_task: ResourceTask,
compartment: Option<compartment>,
compartment: Option<@mut Compartment>,
// What parts of layout are dirty.
mut damage: Damage,
}
pub fn Content(layout_task: LayoutTask,
control_port: pipes::Port<ControlMsg>,
control_chan: pipes::SharedChan<ControlMsg>,
resource_task: ResourceTask,
img_cache_task: ImageCacheTask,
event_port: pipes::Port<Event>,
event_chan: pipes::SharedChan<Event>) -> @Content {
control_port: pipes::Port<ControlMsg>,
control_chan: pipes::SharedChan<ControlMsg>,
resource_task: ResourceTask,
img_cache_task: ImageCacheTask,
event_port: pipes::Port<Event>,
event_chan: pipes::SharedChan<Event>)
-> @Content {
let jsrt = jsrt();
let cx = jsrt.cx();
@ -161,7 +162,6 @@ pub fn task_from_context(cx: *JSContext) -> *Content {
#[allow(non_implicitly_copyable_typarams)]
impl Content {
fn start() {
while self.handle_msg() {
// Go on ...
@ -185,7 +185,7 @@ impl Content {
let result = html::hubbub_html_parser::parse_html(self.scope,
copy url,
self.resource_task,
self.resource_task.clone(),
self.image_cache_task.clone());
let root = result.root;
@ -286,7 +286,7 @@ impl Content {
join_port.recv();
debug!("content: layout joined");
}
None => fail ~"reader forked but no join port?"
None => fail!(~"reader forked but no join port?")
}
self.scope.reader_joined();
@ -332,9 +332,9 @@ impl Content {
fn query_layout(query: layout_task::LayoutQuery) -> layout_task::LayoutQueryResponse {
self.relayout(self.document.get(), &(copy self.doc_url).get());
self.join_layout();
let response_port = Port();
self.layout_task.send(layout_task::QueryMsg(query, response_port.chan()));
let (response_port, response_chan) = pipes::stream();
self.layout_task.send(layout_task::QueryMsg(query, response_chan));
return response_port.recv()
}

View File

@ -1,14 +1,15 @@
/**
* High-level interface to CSS selector matching.
*/
use std::arc::{ARC, get, clone};
use dom::node::{Node, NodeTree};
use newcss::select::{SelectCtx, SelectResults};
use newcss::complete::CompleteSelectResults;
use layout::context::LayoutContext;
use css::select_handler::NodeSelectHandler;
// High-level interface to CSS selector matching.
trait MatchMethods {
use css::node_util::NodeUtil;
use css::select_handler::NodeSelectHandler;
use dom::node::{Node, NodeTree};
use layout::context::LayoutContext;
use newcss::complete::CompleteSelectResults;
use newcss::select::{SelectCtx, SelectResults};
use std::arc::{ARC, get, clone};
pub trait MatchMethods {
fn restyle_subtree(select_ctx: &SelectCtx);
}

View File

@ -1,8 +1,11 @@
// Style retrieval from DOM elements.
use css::node_util::NodeUtil;
use dom::node::Node;
use newcss::complete::CompleteStyle;
/// Node mixin providing `style` method that returns a `NodeStyle`
trait StyledNode {
pub trait StyledNode {
fn style(&self) -> CompleteStyle/&self;
}

View File

@ -2,12 +2,12 @@ use dom::node::Node;
use newcss::complete::CompleteSelectResults;
use std::cell::Cell;
trait NodeUtil {
pub trait NodeUtil {
fn get_css_select_results() -> &self/CompleteSelectResults;
fn set_css_select_results(decl : CompleteSelectResults);
}
impl Node: NodeUtil {
impl NodeUtil for Node {
/**
* Provides the computed style for the given node. If CSS selector
* Returns the style results for the given node. If CSS selector
@ -17,12 +17,12 @@ impl Node: NodeUtil {
*/
fn get_css_select_results() -> &self/CompleteSelectResults {
if !self.has_aux() {
fail ~"style() called on a node without aux data!";
fail!(~"style() called on a node without aux data!");
}
unsafe { &*self.aux( |x| {
match x.style {
Some(ref style) => ptr::to_unsafe_ptr(style),
None => fail ~"style() called on node without a style!"
None => fail!(~"style() called on node without a style!")
}
})}
}

View File

@ -9,7 +9,7 @@ pub struct NodeSelectHandler {
fn with_node_name<R>(data: &NodeData, f: &fn(&str) -> R) -> R {
match *data.kind {
Element(ref data) => f(data.tag_name),
_ => fail ~"attempting to style non-element node"
_ => fail!(~"attempting to style non-element node")
}
}
@ -75,7 +75,7 @@ impl NodeSelectHandler: SelectHandler<Node> {
do node.read |data| {
match *data.kind {
Element(ref data) => data.with_attr("id", f),
_ => fail ~"attempting to style non-element node"
_ => fail!(~"attempting to style non-element node")
}
}
}
@ -91,7 +91,7 @@ impl NodeSelectHandler: SelectHandler<Node> {
}
}
}
_ => fail ~"attempting to style non-element node"
_ => fail!(~"attempting to style non-element node")
}
}
}

View File

@ -1,4 +1,4 @@
use js::rust::{compartment, bare_compartment, methods, jsobj};
use js::rust::{Compartment, jsobj};
use js::{JS_ARGV, JSCLASS_HAS_RESERVED_SLOTS, JSPROP_ENUMERATE, JSPROP_SHARED,
JSVAL_NULL, JS_THIS_OBJECT, JS_SET_RVAL, JSPROP_NATIVE_ACCESSORS};
use js::jsapi::{JSContext, JSVal, JSObject, JSBool, jsid, JSClass, JSFreeOp};
@ -62,8 +62,7 @@ enum Element = int;
return 1;
}*/
extern fn getDocumentElement(cx: *JSContext, _argc: c_uint, vp: *mut JSVal)
-> JSBool {
extern fn getDocumentElement(cx: *JSContext, _argc: c_uint, vp: *mut JSVal) -> JSBool {
unsafe {
let obj = JS_THIS_OBJECT(cx, cast::reinterpret_cast(&vp));
if obj.is_null() {
@ -92,7 +91,7 @@ extern fn finalize(_fop: *JSFreeOp, obj: *JSObject) {
}
}
pub fn init(compartment: &bare_compartment, doc: @Document) {
pub fn init(compartment: @mut Compartment, doc: @Document) {
let obj = utils::define_empty_prototype(~"Document", None, compartment);
let attrs = @~[

View File

@ -1,4 +1,4 @@
use js::rust::{bare_compartment, methods, jsobj};
use js::rust::{Compartment, jsobj};
use js::{JS_ARGV, JSCLASS_HAS_RESERVED_SLOTS, JSPROP_ENUMERATE, JSPROP_SHARED, JSVAL_NULL,
JS_THIS_OBJECT, JS_SET_RVAL, JSPROP_NATIVE_ACCESSORS};
use js::jsapi::{JSContext, JSVal, JSObject, JSBool, jsid, JSClass, JSFreeOp, JSPropertySpec};
@ -29,7 +29,7 @@ extern fn finalize(_fop: *JSFreeOp, obj: *JSObject) {
}
}
pub fn init(compartment: &bare_compartment) {
pub fn init(compartment: @mut Compartment) {
let obj = utils::define_empty_prototype(~"Element", Some(~"Node"), compartment);
let attrs = @~[
{name: compartment.add_name(~"tagName"),
@ -87,10 +87,10 @@ extern fn HTMLImageElement_getWidth(cx: *JSContext, _argc: c_uint, vp: *mut JSVa
}
// TODO: if nothing is being rendered(?), return zero dimensions
}
_ => fail ~"why is this not an image element?"
_ => fail!(~"why is this not an image element?")
}
}
_ => fail ~"why is this not an element?"
_ => fail!(~"why is this not an element?")
}
});
*vp = RUST_INT_TO_JSVAL(
@ -117,10 +117,10 @@ extern fn HTMLImageElement_setWidth(cx: *JSContext, _argc: c_uint, vp: *mut JSVa
let arg = ptr::offset(JS_ARGV(cx, cast::reinterpret_cast(&vp)), 0);
ed.set_attr(~"width", int::str(RUST_JSVAL_TO_INT(*arg) as int))
}
_ => fail ~"why is this not an image element?"
_ => fail!(~"why is this not an image element?")
}
}
_ => fail ~"why is this not an element?"
_ => fail!(~"why is this not an element?")
}
};
return 1;
@ -166,7 +166,7 @@ pub fn create(cx: *JSContext, node: Node, scope: NodeScope) -> jsobj {
_ => ~"HTMLElement"
}
}
_ => fail ~"element::create only handles elements"
_ => fail!(~"element::create only handles elements")
}
});

View File

@ -1,4 +1,4 @@
use js::rust::{bare_compartment, methods, jsobj};
use js::rust::{Compartment, jsobj};
use js::{JS_ARGV, JSCLASS_HAS_RESERVED_SLOTS, JSPROP_ENUMERATE, JSPROP_SHARED, JSVAL_NULL,
JS_THIS_OBJECT, JS_SET_RVAL, JSPROP_NATIVE_ACCESSORS};
use js::jsapi::{JSContext, JSVal, JSObject, JSBool, jsid, JSClass, JSFreeOp, JSPropertySpec};
@ -18,7 +18,7 @@ use super::utils;
use super::element;
use js;
pub fn init(compartment: &bare_compartment) {
pub fn init(compartment: @mut Compartment) {
let obj = utils::define_empty_prototype(~"Node", None, compartment);
let attrs = @~[
@ -49,18 +49,10 @@ pub fn init(compartment: &bare_compartment) {
pub fn create(cx: *JSContext, node: Node, scope: NodeScope) -> jsobj {
do scope.write(&node) |nd| {
match nd.kind {
~Element(*) => {
element::create(cx, node, scope)
}
~Text(*) => {
fail ~"no text node bindings yet";
}
~Comment(*) => {
fail ~"no comment node bindings yet";
}
~Doctype(*) => {
fail ~"no doctype node bindings yet";
}
~Element(*) => element::create(cx, node, scope),
~Text(*) => fail!(~"no text node bindings yet"),
~Comment(*) => fail!(~"no comment node bindings yet"),
~Doctype(*) => fail!(~"no doctype node bindings yet")
}
}
}

View File

@ -1,5 +1,5 @@
use js;
use js::rust::{compartment, bare_compartment, methods};
use js::rust::Compartment;
use js::{JS_ARGV, JSCLASS_HAS_RESERVED_SLOTS, JSPROP_ENUMERATE, JSPROP_SHARED, JSVAL_NULL,
JS_THIS_OBJECT, JS_SET_RVAL};
use js::jsapi::{JSContext, JSVal, JSObject, JSBool, jsid, JSClass, JSFreeOp};
@ -70,7 +70,7 @@ pub unsafe fn domstring_to_jsval(cx: *JSContext, string: &DOMString) -> JSVal {
}
}
pub fn get_compartment(cx: *JSContext) -> compartment {
pub fn get_compartment(cx: *JSContext) -> @mut Compartment {
unsafe {
let content = task_from_context(cx);
let compartment = option::expect((*content).compartment,
@ -96,68 +96,71 @@ extern fn has_instance(_cx: *JSContext, obj: **JSObject, v: *JSVal, bp: *mut JSB
return 1;
}
pub fn prototype_jsclass(name: ~str) -> @fn(compartment: &bare_compartment) -> JSClass {
let f: @fn(&bare_compartment) -> JSClass = |compartment: &bare_compartment, move name| {
{name: compartment.add_name(copy name),
flags: 0,
addProperty: GetJSClassHookStubPointer(PROPERTY_STUB) as *u8,
delProperty: GetJSClassHookStubPointer(PROPERTY_STUB) as *u8,
getProperty: GetJSClassHookStubPointer(PROPERTY_STUB) as *u8,
setProperty: GetJSClassHookStubPointer(STRICT_PROPERTY_STUB) as *u8,
enumerate: GetJSClassHookStubPointer(ENUMERATE_STUB) as *u8,
resolve: GetJSClassHookStubPointer(RESOLVE_STUB) as *u8,
convert: GetJSClassHookStubPointer(CONVERT_STUB) as *u8,
finalize: null(),
checkAccess: null(),
call: null(),
hasInstance: has_instance,
construct: null(),
trace: null(),
reserved: (null(), null(), null(), null(), null(), // 05
null(), null(), null(), null(), null(), // 10
null(), null(), null(), null(), null(), // 15
null(), null(), null(), null(), null(), // 20
null(), null(), null(), null(), null(), // 25
null(), null(), null(), null(), null(), // 30
null(), null(), null(), null(), null(), // 35
null(), null(), null(), null(), null())} // 40
pub fn prototype_jsclass(name: ~str) -> @fn(compartment: @mut Compartment) -> JSClass {
let f: @fn(@mut Compartment) -> JSClass = |compartment: @mut Compartment, move name| {
JSClass {
name: compartment.add_name(copy name),
flags: 0,
addProperty: GetJSClassHookStubPointer(PROPERTY_STUB) as *u8,
delProperty: GetJSClassHookStubPointer(PROPERTY_STUB) as *u8,
getProperty: GetJSClassHookStubPointer(PROPERTY_STUB) as *u8,
setProperty: GetJSClassHookStubPointer(STRICT_PROPERTY_STUB) as *u8,
enumerate: GetJSClassHookStubPointer(ENUMERATE_STUB) as *u8,
resolve: GetJSClassHookStubPointer(RESOLVE_STUB) as *u8,
convert: GetJSClassHookStubPointer(CONVERT_STUB) as *u8,
finalize: null(),
checkAccess: null(),
call: null(),
hasInstance: has_instance,
construct: null(),
trace: null(),
reserved: (null(), null(), null(), null(), null(), // 05
null(), null(), null(), null(), null(), // 10
null(), null(), null(), null(), null(), // 15
null(), null(), null(), null(), null(), // 20
null(), null(), null(), null(), null(), // 25
null(), null(), null(), null(), null(), // 30
null(), null(), null(), null(), null(), // 35
null(), null(), null(), null(), null()) // 40
}
};
return f;
}
pub fn instance_jsclass(name: ~str, finalize: *u8)
-> @fn(compartment: &bare_compartment) -> JSClass {
let f: @fn(&bare_compartment) -> JSClass =
|compartment: &bare_compartment, move name| {
{name: compartment.add_name(copy name),
flags: JSCLASS_HAS_RESERVED_SLOTS(1),
addProperty: GetJSClassHookStubPointer(PROPERTY_STUB) as *u8,
delProperty: GetJSClassHookStubPointer(PROPERTY_STUB) as *u8,
getProperty: GetJSClassHookStubPointer(PROPERTY_STUB) as *u8,
setProperty: GetJSClassHookStubPointer(STRICT_PROPERTY_STUB) as *u8,
enumerate: GetJSClassHookStubPointer(ENUMERATE_STUB) as *u8,
resolve: GetJSClassHookStubPointer(RESOLVE_STUB) as *u8,
convert: GetJSClassHookStubPointer(CONVERT_STUB) as *u8,
finalize: finalize,
checkAccess: null(),
call: null(),
hasInstance: has_instance,
construct: null(),
trace: null(),
reserved: (null(), null(), null(), null(), null(), // 05
null(), null(), null(), null(), null(), // 10
null(), null(), null(), null(), null(), // 15
null(), null(), null(), null(), null(), // 20
null(), null(), null(), null(), null(), // 25
null(), null(), null(), null(), null(), // 30
null(), null(), null(), null(), null(), // 35
null(), null(), null(), null(), null())} // 40
-> @fn(compartment: @mut Compartment) -> JSClass {
let f: @fn(@mut Compartment) -> JSClass = |compartment: @mut Compartment, move name| {
JSClass {
name: compartment.add_name(copy name),
flags: JSCLASS_HAS_RESERVED_SLOTS(1),
addProperty: GetJSClassHookStubPointer(PROPERTY_STUB) as *u8,
delProperty: GetJSClassHookStubPointer(PROPERTY_STUB) as *u8,
getProperty: GetJSClassHookStubPointer(PROPERTY_STUB) as *u8,
setProperty: GetJSClassHookStubPointer(STRICT_PROPERTY_STUB) as *u8,
enumerate: GetJSClassHookStubPointer(ENUMERATE_STUB) as *u8,
resolve: GetJSClassHookStubPointer(RESOLVE_STUB) as *u8,
convert: GetJSClassHookStubPointer(CONVERT_STUB) as *u8,
finalize: finalize,
checkAccess: null(),
call: null(),
hasInstance: has_instance,
construct: null(),
trace: null(),
reserved: (null(), null(), null(), null(), null(), // 05
null(), null(), null(), null(), null(), // 10
null(), null(), null(), null(), null(), // 15
null(), null(), null(), null(), null(), // 20
null(), null(), null(), null(), null(), // 25
null(), null(), null(), null(), null(), // 30
null(), null(), null(), null(), null(), // 35
null(), null(), null(), null(), null()) // 40
}
};
return f;
}
// FIXME: A lot of string copies here
pub fn define_empty_prototype(name: ~str, proto: Option<~str>, compartment: &bare_compartment)
pub fn define_empty_prototype(name: ~str, proto: Option<~str>, compartment: @mut Compartment)
-> js::rust::jsobj {
compartment.register_class(prototype_jsclass(copy name));

View File

@ -1,23 +1,29 @@
use js::rust::{bare_compartment, methods};
use js::{JS_ARGV, JSCLASS_HAS_RESERVED_SLOTS, JSPROP_ENUMERATE, JSPROP_SHARED, JSVAL_NULL,
JS_THIS_OBJECT, JS_SET_RVAL};
use js::jsapi::{JSContext, JSVal, JSObject, JSBool, jsid, JSClass, JSFreeOp};
use js::jsapi::bindgen::{JS_ValueToString, JS_GetStringCharsZAndLength, JS_ReportError,
JS_GetReservedSlot, JS_SetReservedSlot, JS_NewStringCopyN,
JS_DefineFunctions, JS_DefineProperty, JS_DefineProperties, JS_EncodeString, JS_free};
use js::glue::bindgen::*;
use js::global::jsval_to_rust_str;
use js::crust::{JS_PropertyStub, JS_StrictPropertyStub, JS_EnumerateStub, JS_ConvertStub, JS_ResolveStub};
use js::glue::bindgen::RUST_JSVAL_TO_INT;
use ptr::null;
use libc::c_uint;
use dom::bindings::utils::{rust_box, squirrel_away, jsval_to_str};
// DOM bindings for the Window object.
use dom::bindings::node::create;
use dom::window::{Window, TimerMessage_Fire};
use dom::bindings::utils::{rust_box, squirrel_away, jsval_to_str};
use dom::node::Node;
use core::dvec::DVec;
use dom::window::{Window, TimerMessage_Fire};
use super::utils;
use core::dvec::DVec;
use core::libc::c_uint;
use core::ptr::null;
use js::crust::{JS_PropertyStub, JS_StrictPropertyStub, JS_EnumerateStub, JS_ConvertStub};
use js::crust::{JS_ResolveStub};
use js::global::jsval_to_rust_str;
use js::glue::bindgen::*;
use js::glue::bindgen::RUST_JSVAL_TO_INT;
use js::jsapi::bindgen::{JS_DefineFunctions, JS_DefineProperty, JS_DefineProperties};
use js::jsapi::bindgen::{JS_EncodeString, JS_free};
use js::jsapi::bindgen::{JS_GetReservedSlot, JS_SetReservedSlot, JS_NewStringCopyN};
use js::jsapi::bindgen::{JS_ValueToString, JS_GetStringCharsZAndLength, JS_ReportError};
use js::jsapi::{JSContext, JSVal, JSObject, JSBool, jsid, JSClass, JSFreeOp, JSFunctionSpec};
use js::jsapi::{JSNativeWrapper};
use js::rust::Compartment;
use js::{JS_ARGV, JSCLASS_HAS_RESERVED_SLOTS, JSPROP_ENUMERATE, JSPROP_SHARED, JSVAL_NULL};
use js::{JS_THIS_OBJECT, JS_SET_RVAL};
extern fn alert(cx: *JSContext, argc: c_uint, vp: *JSVal) -> JSBool {
unsafe {
let argv = JS_ARGV(cx, vp);
@ -69,7 +75,7 @@ extern fn finalize(_fop: *JSFreeOp, obj: *JSObject) {
}
}
pub fn init(compartment: &bare_compartment, win: @Window) {
pub fn init(compartment: @mut Compartment, win: @Window) {
let proto = utils::define_empty_prototype(~"Window", None, compartment);
compartment.register_class(utils::instance_jsclass(~"WindowInstance", finalize));
@ -78,27 +84,40 @@ pub fn init(compartment: &bare_compartment, win: @Window) {
~"Window", null()));
/* Define methods on a window */
let methods = ~[{name: compartment.add_name(~"alert"),
call: {op: alert, info: null()},
nargs: 1,
flags: 0,
selfHostedName: null()},
{name: compartment.add_name(~"setTimeout"),
call: {op: setTimeout, info: null()},
nargs: 2,
flags: 0,
selfHostedName: null()},
{name: compartment.add_name(~"close"),
call: {op: close, info: null()},
nargs: 2,
flags: 0,
selfHostedName: null()}];
vec::as_imm_buf(methods, |fns, _len| {
JS_DefineFunctions(compartment.cx.ptr, proto.ptr, fns);
});
let methods = [
JSFunctionSpec {
name: compartment.add_name(~"alert"),
call: JSNativeWrapper { op: alert, info: null() },
nargs: 1,
flags: 0,
selfHostedName: null()
},
JSFunctionSpec {
name: compartment.add_name(~"setTimeout"),
call: JSNativeWrapper { op: setTimeout, info: null() },
nargs: 2,
flags: 0,
selfHostedName: null()
},
JSFunctionSpec {
name: compartment.add_name(~"close"),
call: JSNativeWrapper { op: close, info: null() },
nargs: 2,
flags: 0,
selfHostedName: null()
},
JSFunctionSpec {
name: null(),
call: JSNativeWrapper { op: null(), info: null() },
nargs: 0,
flags: 0,
selfHostedName: null()
}
];
unsafe {
JS_DefineFunctions(compartment.cx.ptr, proto.ptr, &methods[0]);
let raw_ptr: *libc::c_void = cast::reinterpret_cast(&squirrel_away(win));
JS_SetReservedSlot(obj.ptr, 0, RUST_PRIVATE_TO_JSVAL(raw_ptr));
}

View File

@ -8,7 +8,7 @@ use geom::size::Size2D;
use js::crust::*;
use js::glue::bindgen::RUST_OBJECT_TO_JSVAL;
use js::jsapi::{JSClass, JSObject, JSPropertySpec, JSContext, jsid, JSVal, JSBool};
use js::rust::{bare_compartment, compartment, methods};
use js::rust::Compartment;
use js::{JSPROP_ENUMERATE, JSPROP_SHARED};
use layout::debug::DebugMethods;
use layout::flow::FlowContext;
@ -115,8 +115,7 @@ pub fn DoctypeData(name: ~str, public_id: Option<~str>,
pub fn define_bindings(compartment: &bare_compartment, doc: @Document,
win: @Window) {
pub fn define_bindings(compartment: @mut Compartment, doc: @Document, win: @Window) {
bindings::window::init(compartment, win);
bindings::document::init(compartment, doc);
bindings::node::init(compartment);
@ -142,7 +141,7 @@ pub fn NodeScope() -> NodeScope {
cow::Scope()
}
trait NodeScopeExtensions {
pub trait NodeScopeExtensions {
fn new_node(+k: NodeKind) -> Node;
}

View File

@ -1,4 +1,4 @@
use oldcomm::{Port, Chan};
use core::pipes::{Port, Chan};
use content::content_task::{ControlMsg, Timer, ExitMsg};
use js::jsapi::JSVal;
use dvec::DVec;
@ -62,8 +62,9 @@ impl Window {
// Post a delayed message to the per-window timer task; it will dispatch it
// to the relevant content handler that will deal with it.
timer::delayed_send(uv_global_loop::get(),
timeout, self.timer_chan,
timer::delayed_send(&uv_global_loop::get(),
timeout,
&self.timer_chan,
TimerMessage_Fire(~TimerData(argc, argv)));
}
}

View File

@ -16,15 +16,15 @@ use gfx::render_task;
use std::cell::Cell;
use std::net::url::Url;
pub type EngineTask = oldcomm::Chan<Msg>;
pub type EngineTask = Chan<Msg>;
pub enum Msg {
LoadURLMsg(Url),
ExitMsg(Chan<()>)
}
pub struct Engine<C:Compositor Owned Copy> {
request_port: oldcomm::Port<Msg>,
pub struct Engine<C> {
request_port: Port<Msg>,
compositor: C,
render_task: RenderTask,
resource_task: ResourceTask,
@ -33,30 +33,31 @@ pub struct Engine<C:Compositor Owned Copy> {
content_task: ContentTask
}
pub fn Engine<C:Compositor Owned Copy>(compositor: C,
opts: &Opts,
dom_event_port: pipes::Port<Event>,
dom_event_chan: pipes::SharedChan<Event>,
resource_task: ResourceTask,
image_cache_task: ImageCacheTask) -> EngineTask {
let dom_event_port = Cell(move dom_event_port);
let dom_event_chan = Cell(move dom_event_chan);
pub fn Engine<C:Compositor + Owned + Clone>(compositor: C,
opts: &Opts,
dom_event_port: pipes::Port<Event>,
dom_event_chan: pipes::SharedChan<Event>,
resource_task: ResourceTask,
image_cache_task: ImageCacheTask)
-> EngineTask {
let dom_event_port = Cell(dom_event_port);
let dom_event_chan = Cell(dom_event_chan);
let opts = Cell(copy *opts);
do spawn_listener::<Msg> |request, move dom_event_port, move dom_event_chan,
move image_cache_task, move opts| {
let render_task = RenderTask(compositor, opts.with_ref(|o| copy *o));
let layout_task = LayoutTask(render_task, image_cache_task.clone(), opts.take());
let content_task = ContentTask(layout_task,
dom_event_port.take(), dom_event_chan.take(),
resource_task, image_cache_task.clone());
do spawn_listener::<Msg> |request| {
let render_task = RenderTask(compositor.clone(), opts.with_ref(|o| copy *o));
let layout_task = LayoutTask(render_task.clone(), image_cache_task.clone(), opts.take());
let content_task = ContentTask(layout_task.clone(),
dom_event_port.take(),
dom_event_chan.take(),
resource_task.clone(),
image_cache_task.clone());
Engine {
request_port: request,
compositor: compositor,
compositor: compositor.clone(),
render_task: render_task,
resource_task: resource_task,
resource_task: resource_task.clone(),
image_cache_task: image_cache_task.clone(),
layout_task: move layout_task,
content_task: move content_task
@ -64,7 +65,7 @@ pub fn Engine<C:Compositor Owned Copy>(compositor: C,
}
}
impl<C: Compositor Copy Owned> Engine<C> {
impl<C:Compositor + Owned + Clone> Engine<C> {
fn run() {
while self.handle_request(self.request_port.recv()) {
// Go on...

View File

@ -4,13 +4,14 @@ Some little helpers for hooking up the HTML parser with the CSS parser
use resource::resource_task::{ResourceTask, ProgressMsg, Load, Payload, Done};
use core::pipes::{Port, Chan};
use core::pipes;
use core::str;
use newcss::stylesheet::Stylesheet;
use newcss::util::DataStream;
use std::cell::Cell;
use std::net::url::Url;
use std::net::url;
use core::oldcomm::{Port, Chan};
/// Where a style sheet comes from.
pub enum StylesheetProvenance {
@ -19,9 +20,9 @@ pub enum StylesheetProvenance {
}
pub fn spawn_css_parser(provenance: StylesheetProvenance,
resource_task: ResourceTask) -> oldcomm::Port<Stylesheet> {
let result_port = oldcomm::Port();
let result_chan = oldcomm::Chan(&result_port);
resource_task: ResourceTask)
-> Port<Stylesheet> {
let (result_port, result_chan) = pipes::stream();
let provenance_cell = Cell(move provenance);
do task::spawn |move provenance_cell, copy resource_task| {
@ -32,8 +33,9 @@ pub fn spawn_css_parser(provenance: StylesheetProvenance,
}
};
let sheet = Stylesheet::new(move url, data_stream(provenance_cell.take(), resource_task));
result_chan.send(move sheet);
let sheet = Stylesheet::new(url, data_stream(provenance_cell.take(),
resource_task.clone()));
result_chan.send(sheet);
}
return result_port;
@ -42,8 +44,8 @@ pub fn spawn_css_parser(provenance: StylesheetProvenance,
fn data_stream(provenance: StylesheetProvenance, resource_task: ResourceTask) -> DataStream {
match move provenance {
UrlProvenance(move url) => {
let input_port = Port();
resource_task.send(Load(move url, input_port.chan()));
let (input_port, input_chan) = pipes::stream();
resource_task.send(Load(move url, input_chan));
resource_port_to_data_stream(input_port)
}
InlineProvenance(_, move data) => {
@ -52,7 +54,7 @@ fn data_stream(provenance: StylesheetProvenance, resource_task: ResourceTask) ->
}
}
fn resource_port_to_data_stream(input_port: oldcomm::Port<ProgressMsg>) -> DataStream {
fn resource_port_to_data_stream(input_port: Port<ProgressMsg>) -> DataStream {
return || {
match input_port.recv() {
Payload(move data) => Some(move data),

View File

@ -4,13 +4,14 @@ use content::content_task::ContentTask;
use dom::cow;
use dom::element::*;
use dom::event::{Event, ReflowEvent};
use dom::node::{Comment, Doctype, DoctypeData, Element, Node, NodeScope, Text};
use dom::node::{Comment, Doctype, DoctypeData, Element, Node, NodeScope, NodeScopeExtensions};
use dom::node::{Text};
use resource::image_cache_task::ImageCacheTask;
use resource::image_cache_task;
use resource::resource_task::{Done, Load, Payload, ResourceTask};
use util::task::{spawn_listener, spawn_conversation};
use core::oldcomm::{Chan, Port};
use core::pipes::{Chan, Port, SharedChan};
use html::cssparse::{InlineProvenance, StylesheetProvenance, UrlProvenance, spawn_css_parser};
use hubbub::hubbub::Attribute;
use hubbub::hubbub;
@ -32,8 +33,8 @@ enum JSMessage {
struct HtmlParserResult {
root: Node,
style_port: oldcomm::Port<Option<Stylesheet>>,
js_port: oldcomm::Port<JSResult>,
style_port: Port<Option<Stylesheet>>,
js_port: Port<JSResult>,
}
/**
@ -51,15 +52,15 @@ spawned, collates them, and sends them to the given result channel.
* `from_parent` - A port on which to receive new links.
*/
fn css_link_listener(to_parent : oldcomm::Chan<Option<Stylesheet>>,
from_parent : oldcomm::Port<CSSMessage>,
fn css_link_listener(to_parent: Chan<Option<Stylesheet>>,
from_parent: Port<CSSMessage>,
resource_task: ResourceTask) {
let mut result_vec = ~[];
loop {
match from_parent.recv() {
CSSTaskNewFile(move provenance) => {
result_vec.push(spawn_css_parser(move provenance, copy resource_task));
CSSTaskNewFile(provenance) => {
result_vec.push(spawn_css_parser(provenance, resource_task.clone()));
}
CSSTaskExit => {
break;
@ -75,19 +76,20 @@ fn css_link_listener(to_parent : oldcomm::Chan<Option<Stylesheet>>,
to_parent.send(None);
}
fn js_script_listener(to_parent : oldcomm::Chan<~[~[u8]]>, from_parent : oldcomm::Port<JSMessage>,
fn js_script_listener(to_parent: Chan<~[~[u8]]>,
from_parent: Port<JSMessage>,
resource_task: ResourceTask) {
let mut result_vec = ~[];
loop {
match from_parent.recv() {
JSTaskNewFile(move url) => {
let result_port = oldcomm::Port();
let result_chan = oldcomm::Chan(&result_port);
do task::spawn |move url| {
let input_port = Port();
let (result_port, result_chan) = pipes::stream();
let resource_task = resource_task.clone();
do task::spawn {
let (input_port, input_chan) = pipes::stream();
// TODO: change copy to move once we can move into closures
resource_task.send(Load(copy url, input_port.chan()));
resource_task.send(Load(copy url, input_chan));
let mut buf = ~[];
loop {
@ -166,18 +168,22 @@ pub fn parse_html(scope: NodeScope,
resource_task: ResourceTask,
image_cache_task: ImageCacheTask) -> HtmlParserResult {
// Spawn a CSS parser to receive links to CSS style sheets.
let (css_port, css_chan): (oldcomm::Port<Option<Stylesheet>>, oldcomm::Chan<CSSMessage>) =
do spawn_conversation |css_port: oldcomm::Port<CSSMessage>,
css_chan: oldcomm::Chan<Option<Stylesheet>>| {
css_link_listener(css_chan, css_port, resource_task);
let resource_task2 = resource_task.clone();
let (css_port, css_chan): (Port<Option<Stylesheet>>, Chan<CSSMessage>) =
do spawn_conversation |css_port: Port<CSSMessage>,
css_chan: Chan<Option<Stylesheet>>| {
css_link_listener(css_chan, css_port, resource_task2.clone());
};
let css_chan = SharedChan(css_chan);
// Spawn a JS parser to receive JavaScript.
let (js_port, js_chan): (oldcomm::Port<JSResult>, oldcomm::Chan<JSMessage>) =
do spawn_conversation |js_port: oldcomm::Port<JSMessage>,
js_chan: oldcomm::Chan<JSResult>| {
js_script_listener(js_chan, js_port, resource_task);
let resource_task2 = resource_task.clone();
let (js_port, js_chan): (Port<JSResult>, Chan<JSMessage>) =
do spawn_conversation |js_port: Port<JSMessage>,
js_chan: Chan<JSResult>| {
js_script_listener(js_chan, js_port, resource_task2.clone());
};
let js_chan = SharedChan(js_chan);
let (scope, url) = (@copy scope, @move url);
@ -192,6 +198,7 @@ pub fn parse_html(scope: NodeScope,
// Performs various actions necessary after appending has taken place. Currently, this consists
// of processing inline stylesheets, but in the future it might perform prefetching, etc.
let css_chan2 = css_chan.clone();
let append_hook: @fn(Node, Node) = |parent_node, child_node| {
do scope.read(&parent_node) |parent_node_contents| {
do scope.read(&child_node) |child_node_contents| {
@ -203,7 +210,7 @@ pub fn parse_html(scope: NodeScope,
let url = url::from_str("http://example.com/"); // FIXME
let provenance = InlineProvenance(result::unwrap(move url),
copy *data);
css_chan.send(CSSTaskNewFile(move provenance));
css_chan2.send(CSSTaskNewFile(move provenance));
}
_ => {} // Nothing to do.
}
@ -214,6 +221,7 @@ pub fn parse_html(scope: NodeScope,
}
};
let (css_chan2, js_chan2) = (css_chan.clone(), js_chan.clone());
parser.set_tree_handler(@hubbub::TreeHandler {
create_comment: |data: ~str| {
debug!("create comment");
@ -257,8 +265,8 @@ pub fn parse_html(scope: NodeScope,
(Some(move rel), Some(move href)) => {
if rel == ~"stylesheet" {
debug!("found CSS stylesheet: %s", href);
css_chan.send(CSSTaskNewFile(UrlProvenance(make_url(move href,
Some(copy *url)))));
css_chan2.send(CSSTaskNewFile(UrlProvenance(make_url(
href, Some(copy *url)))));
}
}
_ => {}
@ -341,7 +349,10 @@ pub fn parse_html(scope: NodeScope,
complete_script: |script| {
// A little function for holding this lint attr
#[allow(non_implicitly_copyable_typarams)]
fn complete_script(scope: &NodeScope, script: hubbub::NodeDataPtr, url: &Url, js_chan: &oldcomm::Chan<JSMessage>) {
fn complete_script(scope: &NodeScope,
script: hubbub::NodeDataPtr,
url: &Url,
js_chan: SharedChan<JSMessage>) {
unsafe {
do scope.read(&cow::wrap(cast::transmute(script))) |node_contents| {
match *node_contents.kind {
@ -360,14 +371,14 @@ pub fn parse_html(scope: NodeScope,
}
}
}
complete_script(scope, script, url, &js_chan);
complete_script(scope, script, url, js_chan2.clone());
debug!("complete script");
}
});
debug!("set tree handler");
let input_port = Port();
resource_task.send(Load(copy *url, input_port.chan()));
let (input_port, input_chan) = pipes::stream();
resource_task.send(Load(copy *url, input_chan));
debug!("loaded page");
loop {
match input_port.recv() {

View File

@ -1,16 +1,20 @@
use au = gfx::geometry;
// Block layout.
use layout::box::{RenderBox};
use layout::context::LayoutContext;
use layout::display_list_builder::{DisplayListBuilder, FlowDisplayListBuilderMethods};
use layout::flow::{FlowContext, FlowTree, InlineBlockFlow, BlockFlow, RootFlow};
use layout::inline::InlineLayout;
use newcss::values::*;
use util::tree;
use au = gfx::geometry;
use core::mutable::Mut;
use geom::point::Point2D;
use geom::rect::Rect;
use geom::size::Size2D;
use gfx::display_list::DisplayList;
use gfx::geometry::Au;
use layout::box::{RenderBox};
use layout::context::LayoutContext;
use layout::display_list_builder::DisplayListBuilder;
use layout::flow::{FlowContext, FlowTree, InlineBlockFlow, BlockFlow, RootFlow};
use util::tree;
use core::mutable::Mut;
pub struct BlockFlowData {
mut box: Option<@RenderBox>
@ -22,15 +26,18 @@ pub fn BlockFlowData() -> BlockFlowData {
}
}
trait BlockLayout {
pub trait BlockLayout {
pure fn starts_block_flow() -> bool;
pure fn with_block_box(@self, fn(box: &@RenderBox) -> ()) -> ();
fn bubble_widths_block(@self, ctx: &LayoutContext);
fn assign_widths_block(@self, ctx: &LayoutContext);
fn assign_height_block(@self, ctx: &LayoutContext);
fn build_display_list_block(@self, a: &DisplayListBuilder, b: &Rect<Au>,
c: &Point2D<Au>, d: &Mut<DisplayList>);
fn build_display_list_block(@self,
a: &DisplayListBuilder,
b: &Rect<Au>,
c: &Point2D<Au>,
d: &Mut<DisplayList>);
}
impl FlowContext : BlockLayout {
@ -54,7 +61,7 @@ impl FlowContext : BlockLayout {
let mut box = self.root().box;
box.iter(cb);
},
_ => fail fmt!("Tried to do something with_block_box(), but this is a %?", self)
_ => fail!(fmt!("Tried to do something with_block_box(), but this is a %?", self))
}
}

View File

@ -1,5 +1,6 @@
/* Fundamental layout structures and algorithms. */
use css::node_style::StyledNode;
use dom::element::{ElementKind, HTMLDivElement, HTMLImageElement};
use dom::node::{Element, Node, NodeData, NodeKind, NodeTree};
use layout::context::LayoutContext;
@ -8,23 +9,6 @@ use layout::display_list_builder::DisplayListBuilder;
use layout::flow::FlowContext;
use layout::text::TextBoxData;
use layout;
use util::tree::ReadMethods;
use core::mutable::Mut;
use arc = std::arc;
use core::managed;
use core::dvec::DVec;
use core::to_str::ToStr;
use core::rand;
use core::task::spawn;
use geom::{Point2D, Rect, Size2D};
use gfx;
use gfx::display_list::{DisplayItem, DisplayList};
use gfx::font::{FontStyle, FontWeight300};
use gfx::geometry::Au;
use gfx::image::base::Image;
use gfx::image::holder::ImageHolder;
use gfx::text::text_run::TextRun;
use gfx::util::range::*;
use newcss::color::{Color, rgba, rgb};
use newcss::complete::CompleteStyle;
use newcss::units::{BoxSizing, Cursive, Em, Fantasy, Length, Monospace, Pt, Px, SansSerif, Serif};
@ -33,7 +17,25 @@ use newcss::values::{CSSBorderWidthLength, CSSBorderWidthMedium, CSSDisplay};
use newcss::values::{CSSFontFamilyFamilyName, CSSFontFamilyGenericFamily, CSSPositionAbsolute};
use newcss::values::{CSSFontSizeLength, CSSFontStyleItalic, CSSFontStyleNormal};
use newcss::values::{CSSFontStyleOblique, CSSTextAlign, Specified};
use util::tree::ReadMethods;
use core::dvec::DVec;
use core::managed;
use core::mutable::Mut;
use core::rand;
use core::task::spawn;
use core::to_str::ToStr;
use geom::{Point2D, Rect, Size2D};
use gfx::display_list::{DisplayItem, DisplayList};
use gfx::font::{FontStyle, FontWeight300};
use gfx::geometry::Au;
use gfx::image::base::Image;
use gfx::image::holder::ImageHolder;
use gfx::text::text_run::TextRun;
use gfx::util::range::*;
use gfx;
use std::arc::ARC;
use std::arc;
use std::net::url::Url;
/**
@ -165,7 +167,7 @@ impl RenderBox {
match self {
@GenericBox(*) => CannotSplit(self),
@ImageBox(*) => CannotSplit(self),
@UnscannedTextBox(*) => fail ~"WAT: shouldn't be an unscanned text box here.",
@UnscannedTextBox(*) => fail!(~"WAT: shouldn't be an unscanned text box here."),
@TextBox(_,data) => {
let mut pieces_processed_count : uint = 0;
@ -249,7 +251,7 @@ impl RenderBox {
// TODO: If image isn't available, consult 'width'.
&ImageBox(_, ref i) => Au::from_px(i.get_size().get_or_default(Size2D(0,0)).width),
&TextBox(_,d) => d.run.min_width_for_range(&const d.range),
&UnscannedTextBox(*) => fail ~"Shouldn't see unscanned boxes here."
&UnscannedTextBox(*) => fail!(~"Shouldn't see unscanned boxes here.")
}
}
@ -281,7 +283,7 @@ impl RenderBox {
max_line_width
},
&UnscannedTextBox(*) => fail ~"Shouldn't see unscanned boxes here."
&UnscannedTextBox(*) => fail!(~"Shouldn't see unscanned boxes here.")
}
}
@ -333,7 +335,7 @@ impl RenderBox {
&TextBox(*) => {
copy self.d().position
},
&UnscannedTextBox(*) => fail ~"Shouldn't see unscanned boxes here."
&UnscannedTextBox(*) => fail!(~"Shouldn't see unscanned boxes here.")
}
}
@ -401,7 +403,7 @@ impl RenderBox {
self.add_bgcolor_to_list(list, &abs_box_bounds);
match self {
@UnscannedTextBox(*) => fail ~"Shouldn't see unscanned boxes here.",
@UnscannedTextBox(*) => fail!(~"Shouldn't see unscanned boxes here."),
@TextBox(_,data) => {
do list.borrow_mut |list| {
let nearest_ancestor_element = self.nearest_ancestor_element();
@ -606,7 +608,7 @@ impl RenderBox {
let mut node = self.d().node;
while !node.is_element() {
match NodeTree.get_parent(&node) {
None => fail ~"no nearest element?!",
None => fail!(~"no nearest element?!"),
Some(move parent) => node = move parent,
}
}

View File

@ -6,6 +6,7 @@ use dom::node::{Comment, Doctype, Element, Text, Node, LayoutData};
use layout::box::*;
use layout::block::BlockFlowData;
use layout::context::LayoutContext;
use layout::debug::{BoxedDebugMethods, DebugMethods};
use layout::flow::*;
use layout::inline::InlineFlowData;
use layout::root::RootFlowData;
@ -370,7 +371,7 @@ impl LayoutTreeBuilder {
fn fixup_split_inline(_foo: @FlowContext) {
// TODO: finish me.
fail ~"TODO: handle case where an inline is split by a block"
fail!(~"TODO: handle case where an inline is split by a block")
}
/** entry point for box creation. Should only be
@ -435,9 +436,9 @@ impl LayoutTreeBuilder {
self.make_generic_box(layout_ctx, node, ctx)
}
},
_ => fail ~"WAT error: why couldn't we make an image box?"
_ => fail!(~"WAT error: why couldn't we make an image box?")
},
_ => fail ~"WAT error: why couldn't we make an image box?"
_ => fail!(~"WAT error: why couldn't we make an image box?")
}
}
@ -447,7 +448,7 @@ impl LayoutTreeBuilder {
do node.read |n| {
match n.kind {
~Text(ref string) => @UnscannedTextBox(RenderBoxData(node, ctx, self.next_box_id()), copy *string),
_ => fail ~"WAT error: why couldn't we make a text box?"
_ => fail!(~"WAT error: why couldn't we make a text box?")
}
}
}
@ -455,14 +456,19 @@ impl LayoutTreeBuilder {
fn decide_box_type(node: Node, display: CSSDisplay) -> RenderBoxType {
do node.read |n| {
match n.kind {
~Doctype(*) | ~Comment(*) => fail ~"Hey, doctypes and comments shouldn't get here! They are display:none!",
~Doctype(*) | ~Comment(*) => {
fail!(~"Hey, doctypes and comments shouldn't get here! \
They are display:none!")
}
~Text(*) => RenderBox_Text,
~Element(ref element) => {
match (&element.kind, display) {
(&~HTMLImageElement(ref d), _) if d.image.is_some() => RenderBox_Image,
// (_, Specified(_)) => GenericBox,
(_, _) => RenderBox_Generic // TODO: replace this with the commented lines
// (_, _) => fail ~"Can't create box for Node with non-specified 'display' type"
//(_, _) => {
// fail!(~"Can't create box for Node with non-specified 'display' type")
//}
}
}
}

View File

@ -1,5 +1,3 @@
export DisplayListBuilder;
use newcss::values::Specified;
use newcss::values::{CSSBackgroundColorColor, CSSBackgroundColorTransparent};
use dom::node::{Text, NodeScope};
@ -31,16 +29,20 @@ pub struct DisplayListBuilder {
ctx: &LayoutContext,
}
trait FlowDisplayListBuilderMethods {
pub trait FlowDisplayListBuilderMethods {
fn build_display_list(@self, a: &DisplayListBuilder, b: &Rect<Au>, c: &Mut<DisplayList>);
fn build_display_list_for_child(@self, a: &DisplayListBuilder, b: @FlowContext,
c: &Rect<Au>, d: &Point2D<Au>, e: &Mut<DisplayList>);
fn build_display_list_for_child(@self,
a: &DisplayListBuilder,
b: @FlowContext,
c: &Rect<Au>,
d: &Point2D<Au>,
e: &Mut<DisplayList>);
}
impl FlowContext: FlowDisplayListBuilderMethods {
fn build_display_list(@self, builder: &DisplayListBuilder, dirty: &Rect<Au>,
impl FlowDisplayListBuilderMethods for FlowContext {
fn build_display_list(@self,
builder: &DisplayListBuilder,
dirty: &Rect<Au>,
list: &Mut<DisplayList>) {
let zero = gfx::geometry::zero_point();
self.build_display_list_recurse(builder, dirty, &zero, list);

View File

@ -1,12 +1,12 @@
use core;
use dom::node::Node;
use layout::block::BlockFlowData;
use layout::block::{BlockFlowData, BlockLayout};
use layout::box::RenderBox;
use layout::context::LayoutContext;
use layout::debug::BoxedDebugMethods;
use layout::display_list_builder::DisplayListBuilder;
use layout::inline::{InlineFlowData, NodeRange};
use layout::root::RootFlowData;
use layout::inline::{InlineFlowData, InlineLayout, NodeRange};
use layout::root::{RootFlowData, RootLayout};
use util::tree;
use core::mutable::Mut;
use core::dvec::DVec;
@ -109,21 +109,21 @@ impl FlowContext {
pure fn inline(&self) -> &self/InlineFlowData {
match *self {
InlineFlow(_, ref i) => i,
_ => fail fmt!("Tried to access inline data of non-inline: f%d", self.d().id)
_ => fail!(fmt!("Tried to access inline data of non-inline: f%d", self.d().id))
}
}
pure fn block(&self) -> &self/BlockFlowData {
match *self {
BlockFlow(_, ref b) => b,
_ => fail fmt!("Tried to access block data of non-block: f%d", self.d().id)
_ => fail!(fmt!("Tried to access block data of non-block: f%d", self.d().id))
}
}
pure fn root(&self) -> &self/RootFlowData {
match *self {
RootFlow(_, ref r) => r,
_ => fail fmt!("Tried to access root data of non-root: f%d", self.d().id)
_ => fail!(fmt!("Tried to access root data of non-root: f%d", self.d().id))
}
}
@ -132,7 +132,7 @@ impl FlowContext {
@BlockFlow(*) => self.bubble_widths_block(ctx),
@InlineFlow(*) => self.bubble_widths_inline(ctx),
@RootFlow(*) => self.bubble_widths_root(ctx),
_ => fail fmt!("Tried to bubble_widths of flow: f%d", self.d().id)
_ => fail!(fmt!("Tried to bubble_widths of flow: f%d", self.d().id))
}
}
@ -141,7 +141,7 @@ impl FlowContext {
@BlockFlow(*) => self.assign_widths_block(ctx),
@InlineFlow(*) => self.assign_widths_inline(ctx),
@RootFlow(*) => self.assign_widths_root(ctx),
_ => fail fmt!("Tried to assign_widths of flow: f%d", self.d().id)
_ => fail!(fmt!("Tried to assign_widths of flow: f%d", self.d().id))
}
}
@ -150,7 +150,7 @@ impl FlowContext {
@BlockFlow(*) => self.assign_height_block(ctx),
@InlineFlow(*) => self.assign_height_inline(ctx),
@RootFlow(*) => self.assign_height_root(ctx),
_ => fail fmt!("Tried to assign_height of flow: f%d", self.d().id)
_ => fail!(fmt!("Tried to assign_height of flow: f%d", self.d().id))
}
}
@ -162,7 +162,7 @@ impl FlowContext {
@RootFlow(*) => self.build_display_list_root(builder, dirty, offset, list),
@BlockFlow(*) => self.build_display_list_block(builder, dirty, offset, list),
@InlineFlow(*) => self.build_display_list_inline(builder, dirty, offset, list),
_ => fail fmt!("Tried to build_display_list_recurse of flow: %?", self)
_ => fail!(fmt!("Tried to build_display_list_recurse of flow: %?", self))
}
}
@ -173,7 +173,7 @@ impl FlowContext {
RootFlow(*) => option::map_default(&self.root().box, seed, |box| { cb(seed, *box) }),
BlockFlow(*) => option::map_default(&self.block().box, seed, |box| { cb(seed, *box) }),
InlineFlow(*) => do self.inline().boxes.foldl(seed) |acc, box| { cb(*acc, *box) },
_ => fail fmt!("Don't know how to iterate node's RenderBoxes for %?", self)
_ => fail!(fmt!("Don't know how to iterate node's RenderBoxes for %?", self))
}
}
@ -190,7 +190,7 @@ impl FlowContext {
RootFlow(*) => do self.root().box.iter |box| { cb(*box); },
BlockFlow(*) => do self.block().box.iter |box| { cb(*box); },
InlineFlow(*) => for self.inline().boxes.each |box| { cb(*box); },
_ => fail fmt!("Don't know how to iterate node's RenderBoxes for %?", self)
_ => fail!(fmt!("Don't know how to iterate node's RenderBoxes for %?", self))
}
}

View File

@ -2,13 +2,13 @@ use core;
use dom::node::Node;
use layout::box::*;
use layout::context::LayoutContext;
use layout::debug::{BoxedDebugMethods, DebugMethods};
use layout::flow::{FlowContext, InlineFlow};
use layout::text::TextBoxData;
use layout::text::{TextBoxData, UnscannedMethods};
use util::tree;
use core::dlist::DList;
use core::dvec::DVec;
use core::num::Num;
use geom::{Point2D, Rect, Size2D};
use gfx::font::FontStyle;
use gfx::geometry::Au;
@ -227,7 +227,9 @@ priv impl TextRunScanner {
};
match (is_singleton, is_text_clump) {
(false, false) => fail ~"WAT: can't coalesce non-text nodes in flush_clump_to_list()!",
(false, false) => {
fail!(~"WAT: can't coalesce non-text nodes in flush_clump_to_list()!")
}
(true, false) => {
debug!("TextRunScanner: pushing single non-text box in range: %?", self.clump);
out_boxes.push(in_boxes[self.clump.begin()]);
@ -323,7 +325,7 @@ priv impl TextRunScanner {
struct LineboxScanner {
flow: @FlowContext,
new_boxes: DVec<@RenderBox>,
work_list: @DList<@RenderBox>,
work_list: @mut DList<@RenderBox>,
pending_line: {mut range: Range, mut width: Au},
line_spans: DVec<Range>,
}
@ -341,19 +343,19 @@ fn LineboxScanner(inline: @FlowContext) -> LineboxScanner {
}
impl LineboxScanner {
priv fn reset_scanner() {
priv fn reset_scanner(&mut self) {
debug!("Resetting line box scanner's state for flow f%d.", self.flow.d().id);
self.line_spans.set(~[]);
self.new_boxes.set(~[]);
self.reset_linebox();
}
priv fn reset_linebox() {
priv fn reset_linebox(&mut self) {
self.pending_line.range.reset(0,0);
self.pending_line.width = Au(0);
}
pub fn scan_for_lines(ctx: &LayoutContext) {
pub fn scan_for_lines(&mut self, ctx: &LayoutContext) {
self.reset_scanner();
let boxes = &self.flow.inline().boxes;
@ -362,7 +364,7 @@ impl LineboxScanner {
loop {
// acquire the next box to lay out from work list or box list
let cur_box = match self.work_list.pop() {
Some(box) => {
Some(box) => {
debug!("LineboxScanner: Working with box from work list: b%d", box.d().id);
box
},
@ -394,7 +396,7 @@ impl LineboxScanner {
self.swap_out_results();
}
priv fn swap_out_results() {
priv fn swap_out_results(&mut self) {
debug!("LineboxScanner: Propagating scanned lines[n=%u] to inline flow f%d",
self.line_spans.len(), self.flow.d().id);
@ -408,7 +410,7 @@ impl LineboxScanner {
};
}
priv fn flush_current_line() {
priv fn flush_current_line(&mut self) {
debug!("LineboxScanner: Flushing line %u: %?",
self.line_spans.len(), self.pending_line);
// set box horizontal offsets
@ -465,7 +467,7 @@ impl LineboxScanner {
}
// return value: whether any box was appended.
priv fn try_append_to_line(ctx: &LayoutContext, in_box: @RenderBox) -> bool {
priv fn try_append_to_line(&mut self, ctx: &LayoutContext, in_box: @RenderBox) -> bool {
let remaining_width = self.flow.d().position.size.width - self.pending_line.width;
let in_box_width = in_box.d().position.size.width;
let line_is_empty: bool = self.pending_line.range.length() == 0;
@ -545,7 +547,7 @@ impl LineboxScanner {
}
// unconditional push
priv fn push_box_to_line(box: @RenderBox) {
priv fn push_box_to_line(&mut self, box: @RenderBox) {
debug!("LineboxScanner: Pushing box b%d to line %u", box.d().id, self.line_spans.len());
if self.pending_line.range.length() == 0 {
@ -579,7 +581,7 @@ pub fn InlineFlowData() -> InlineFlowData {
}
}
trait InlineLayout {
pub trait InlineLayout {
pure fn starts_inline_flow() -> bool;
fn bubble_widths_inline(@self, ctx: &LayoutContext);
@ -630,7 +632,7 @@ impl FlowContext : InlineLayout {
},
// TODO(Issue #225): different cases for 'inline-block', other replaced content
@GenericBox(*) => Au::from_px(45),
_ => fail fmt!("Tried to assign width to unknown Box variant: %?", box)
_ => fail!(fmt!("Tried to assign width to unknown Box variant: %?", box))
};
} // for boxes.each |box|
@ -670,7 +672,10 @@ impl FlowContext : InlineLayout {
},
// TODO(Issue #225): different cases for 'inline-block', other replaced content
@GenericBox(*) => Au::from_px(30),
_ => fail fmt!("Tried to assign height to unknown Box variant: %s", cur_box.debug_str())
_ => {
fail!(fmt!("Tried to assign height to unknown Box variant: %s",
cur_box.debug_str()))
}
};
// compute bounding rect, with left baseline as origin.
@ -691,7 +696,10 @@ impl FlowContext : InlineLayout {
let text_bounds = data.run.metrics_for_range(&const data.range).bounding_box;
text_bounds.translate(&Point2D(cur_box.d().position.origin.x, Au(0)))
},
_ => fail fmt!("Tried to compute bounding box of unknown Box variant: %s", cur_box.debug_str())
_ => {
fail!(fmt!("Tried to compute bounding box of unknown Box variant: %s",
cur_box.debug_str()))
}
};
debug!("assign_height_inline: bounding box for box b%d = %?", cur_box.d().id, bounding_box);
linebox_bounding_box = linebox_bounding_box.union(&bounding_box);

View File

@ -1,23 +1,24 @@
/**
The layout task. Performs layout on the DOM, builds display lists and sends them to be
rendered.
*/
/// The layout task. Performs layout on the DOM, builds display lists and sends them to be
/// rendered.
use content::content_task;
use css::matching::MatchMethods;
use css::select::new_css_select_ctx;
use dom::event::{Event, ReflowEvent};
use dom::node::{Node, LayoutData};
use layout::aux::LayoutAuxMethods;
use layout::box::RenderBox;
use layout::box_builder::LayoutTreeBuilder;
use layout::context::LayoutContext;
use layout::display_list_builder::DisplayListBuilder;
use layout::debug::{BoxedDebugMethods, DebugMethods};
use layout::display_list_builder::{DisplayListBuilder, FlowDisplayListBuilderMethods};
use layout::traverse::*;
use resource::image_cache_task::{ImageCacheTask, ImageResponseMsg};
use resource::local_image_cache::LocalImageCache;
use util::time::time;
use util::task::spawn_listener;
use util::time::time;
use core::oldcomm::*; // FIXME: Bad! Pipe-ify me.
use core::pipes::{Chan, Port, SharedChan};
use core::dvec::DVec;
use core::mutable::Mut;
use core::task::*;
@ -34,12 +35,11 @@ use gfx::render_task::{RenderMsg, RenderTask};
use newcss::select::SelectCtx;
use newcss::stylesheet::Stylesheet;
use newcss::types::OriginAuthor;
use opt = core::option;
use std::arc::ARC;
use std::cell::Cell;
use std::net::url::Url;
pub type LayoutTask = oldcomm::Chan<Msg>;
pub type LayoutTask = SharedChan<Msg>;
pub enum LayoutQuery {
ContentBox(Node)
@ -54,7 +54,7 @@ enum LayoutQueryResponse_ {
pub enum Msg {
AddStylesheet(Stylesheet),
BuildMsg(BuildData),
QueryMsg(LayoutQuery, oldcomm::Chan<LayoutQueryResponse>),
QueryMsg(LayoutQuery, Chan<LayoutQueryResponse>),
ExitMsg
}
@ -86,18 +86,18 @@ pub struct BuildData {
}
pub fn LayoutTask(render_task: RenderTask,
img_cache_task: ImageCacheTask,
opts: Opts) -> LayoutTask {
do spawn_listener::<Msg> |from_content, move img_cache_task, move opts| {
Layout(render_task, img_cache_task.clone(), from_content, &opts).start();
}
img_cache_task: ImageCacheTask,
opts: Opts) -> LayoutTask {
SharedChan(spawn_listener::<Msg>(|from_content| {
Layout(render_task.clone(), img_cache_task.clone(), from_content, &opts).start();
}))
}
struct Layout {
render_task: RenderTask,
image_cache_task: ImageCacheTask,
local_image_cache: @LocalImageCache,
from_content: oldcomm::Port<Msg>,
from_content: Port<Msg>,
font_ctx: @FontContext,
// This is used to root auxilliary RCU reader data
@ -107,9 +107,9 @@ struct Layout {
fn Layout(render_task: RenderTask,
image_cache_task: ImageCacheTask,
from_content: oldcomm::Port<Msg>,
opts: &Opts) -> Layout {
from_content: Port<Msg>,
opts: &Opts)
-> Layout {
let fctx = @FontContext::new(opts.render_backend, true);
Layout {
@ -146,8 +146,9 @@ impl Layout {
}
QueryMsg(query, chan) => {
let chan = Cell(chan);
do time("layout: querying layout") {
self.handle_query(query, chan)
self.handle_query(query, chan.take())
}
}
ExitMsg => {
@ -213,7 +214,7 @@ impl Layout {
let layout_root: @FlowContext = match builder.construct_trees(&layout_ctx,
*node) {
Ok(root) => root,
Err(*) => fail ~"Root flow should always exist"
Err(*) => fail!(~"Root flow should always exist")
};
debug!("layout: constructed Flow tree");
@ -238,7 +239,8 @@ impl Layout {
// TODO: set options on the builder before building
// TODO: be smarter about what needs painting
layout_root.build_display_list(&builder, &copy layout_root.d().position,
layout_root.build_display_list(&builder,
&copy layout_root.d().position,
&display_list);
let render_layer = RenderLayer {
@ -256,7 +258,7 @@ impl Layout {
fn handle_query(query: LayoutQuery,
reply_chan: oldcomm::Chan<LayoutQueryResponse>) {
reply_chan: Chan<LayoutQueryResponse>) {
match query {
ContentBox(node) => {
let response = do node.aux |a| {

View File

@ -4,6 +4,7 @@ use geom::point::Point2D;
use geom::rect::Rect;
use gfx::display_list::DisplayList;
use gfx::geometry::Au;
use layout::block::BlockLayout;
use layout::box::RenderBox;
use layout::context::LayoutContext;
use layout::flow::{FlowContext, FlowTree, InlineBlockFlow, BlockFlow, RootFlow};
@ -21,7 +22,7 @@ pub fn RootFlowData() -> RootFlowData {
}
}
trait RootLayout {
pub trait RootLayout {
pure fn starts_root_flow() -> bool;
fn bubble_widths_root(@self, ctx: &LayoutContext);

View File

@ -32,15 +32,15 @@ pub fn adapt_textbox_with_range(box_data: &RenderBoxData, run: @TextRun,
@TextBox(move new_box_data, move new_text_data)
}
trait UnscannedMethods {
pure fn raw_text() -> ~str;
pub trait UnscannedMethods {
pure fn raw_text(&self) -> ~str;
}
impl RenderBox : UnscannedMethods {
pure fn raw_text() -> ~str {
match &self {
pure fn raw_text(&self) -> ~str {
match self {
&UnscannedTextBox(_, ref s) => copy *s,
_ => fail ~"unsupported operation: box.raw_text() on non-unscanned text box."
_ => fail!(~"unsupported operation: box.raw_text() on non-unscanned text box.")
}
}
}

View File

@ -4,7 +4,7 @@ use platform::resize_rate_limiter::ResizeRateLimiter;
use azure::azure_hl::{BackendType, B8G8R8A8, DataSourceSurface, DrawTarget, SourceSurfaceMethods};
use core::dvec::DVec;
use core::pipes::Chan;
use core::pipes::{Chan, SharedChan, Port};
use core::task::TaskBuilder;
use core::util;
use geom::matrix::{Matrix4, identity};
@ -23,7 +23,15 @@ use sharegl;
use sharegl::ShareGlContext;
pub struct OSMain {
chan: oldcomm::Chan<Msg>
chan: SharedChan<Msg>
}
impl Clone for OSMain {
fn clone(&self) -> OSMain {
OSMain {
chan: self.chan.clone()
}
}
}
// FIXME: Move me over to opts.rs.
@ -45,9 +53,10 @@ pub enum Msg {
}
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(dom_event_chan);
OSMain {
chan: do on_osmain::<Msg> |po, move dom_event_chan, move opts| {
chan: SharedChan(on_osmain::<Msg>(|po, move dom_event_chan, move opts| {
let po = Cell(po);
do platform::runmain {
debug!("preparing to enter main loop");
@ -58,9 +67,9 @@ pub fn OSMain(dom_event_chan: pipes::SharedChan<Event>, opts: Opts) -> OSMain {
None => mode = GlutMode
}
mainloop(mode, po, dom_event_chan.take(), &opts);
mainloop(mode, po.take(), dom_event_chan.take(), &opts);
}
}
}))
}
}
@ -86,10 +95,10 @@ impl AzureDrawTargetImageData : layers::layers::ImageData {
}
fn mainloop(mode: Mode,
po: oldcomm::Port<Msg>,
dom_event_chan: pipes::SharedChan<Event>,
po: Port<Msg>,
dom_event_chan: SharedChan<Event>,
opts: &Opts) {
let key_handlers: @DVec<pipes::Chan<()>> = @DVec();
let key_handlers: @DVec<Chan<()>> = @DVec();
let window;
match mode {
@ -101,7 +110,8 @@ fn mainloop(mode: Mode,
window = GlutWindow(move glut_window);
}
ShareMode => {
let share_context: ShareGlContext = sharegl::base::ShareContext::new(Size2D(800, 600));
let size = Size2D(800, 600);
let share_context: ShareGlContext = sharegl::base::ShareContext::new(size);
io::println(fmt!("Sharing ID is %d", share_context.id()));
window = ShareWindow(move share_context);
}
@ -114,20 +124,21 @@ fn mainloop(mode: Mode,
let root_layer = @layers::layers::ContainerLayer();
let original_layer_transform;
{
let image_data = @layers::layers::BasicImageData::new(
Size2D(0u, 0u), 0, layers::layers::RGB24Format, ~[]);
let image_data = @layers::layers::BasicImageData::new(Size2D(0u, 0u),
0,
layers::layers::RGB24Format,
~[]);
let image = @layers::layers::Image::new(image_data as @layers::layers::ImageData);
let image_layer = @layers::layers::ImageLayer(image);
original_layer_transform = image_layer.common.transform;
image_layer.common.set_transform(original_layer_transform.scale(&800.0f32, &600.0f32,
&1f32));
image_layer.common.set_transform(original_layer_transform.scale(800.0, 600.0, 1.0));
root_layer.add_child(layers::layers::ImageLayerKind(image_layer));
}
let scene = @layers::scene::Scene(layers::layers::ContainerLayerKind(root_layer),
Size2D(800.0f32, 600.0f32),
identity(0.0f32));
Size2D(800.0, 600.0),
identity());
let done = @mut false;
let resize_rate_limiter = @ResizeRateLimiter(move dom_event_chan);
@ -185,7 +196,7 @@ fn mainloop(mode: Mode,
}
}
Some(_) => {
fail ~"found unexpected layer kind"
fail!(~"found unexpected layer kind")
}
};
@ -193,8 +204,8 @@ fn mainloop(mode: Mode,
let x = buffer.rect.origin.x as f32;
let y = buffer.rect.origin.y as f32;
image_layer.common.set_transform(
original_layer_transform.translate(&x, &y, &0.0f32)
.scale(&(width as f32), &(height as f32), &1.0f32));
original_layer_transform.translate(x, y, 0.0)
.scale(width as f32, height as f32, 1.0));
}
surfaces.front.layer_buffer_set.buffers = move buffers;
}
@ -264,7 +275,7 @@ fn mainloop(mode: Mode,
Implementation to allow the osmain channel to be used as a graphics
compositor for the renderer
*/
impl OSMain : Compositor {
impl Compositor for OSMain {
fn begin_drawing(next_dt: pipes::Chan<LayerBufferSet>) {
self.chan.send(BeginDrawing(move next_dt))
}
@ -337,16 +348,14 @@ fn Surface(backend: BackendType) -> Surface {
}
/// A function for spawning into the platform's main thread
fn on_osmain<T: Owned>(f: fn~(po: oldcomm::Port<T>)) -> oldcomm::Chan<T> {
let setup_po = oldcomm::Port();
let setup_ch = oldcomm::Chan(&setup_po);
fn on_osmain<T: Owned>(f: fn~(po: Port<T>)) -> Chan<T> {
let (setup_po, setup_ch) = pipes::stream();
do task::task().sched_mode(task::PlatformThread).spawn |move f| {
let po = oldcomm::Port();
let ch = oldcomm::Chan(&po);
oldcomm::send(setup_ch, ch);
let (po, ch) = pipes::stream();
setup_ch.send(ch);
f(move po);
}
oldcomm::recv(setup_po)
setup_po.recv()
}
// #[cfg(target_os = "linux")]

View File

@ -7,6 +7,8 @@
#[license = "MPL"];
#[crate_type = "lib"];
#[legacy_records];
extern mod azure;
extern mod cairo;
extern mod geom;
@ -94,7 +96,6 @@ extern mod core_text;
use engine::{Engine, ExitMsg, LoadURLMsg}; // FIXME: "ExitMsg" is pollution.
use platform::osmain::{AddKeyHandler, OSMain};
use core::oldcomm::*; // FIXME: Bad!
use core::option::swap_unwrap;
use core::pipes::{Port, Chan};
@ -115,9 +116,9 @@ fn run(opts: &Opts) {
match &opts.render_mode {
&Screen => run_pipeline_screen(opts),
&Png(ref outfile) => {
assert opts.urls.is_not_empty();
assert !opts.urls.is_empty();
if opts.urls.len() > 1u {
fail ~"servo asks that you stick to a single URL in PNG output mode"
fail!(~"servo asks that you stick to a single URL in PNG output mode")
}
run_pipeline_png(opts, *outfile)
}
@ -137,9 +138,13 @@ fn run_pipeline_screen(opts: &Opts) {
// 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);
let image_cache_task = ImageCacheTask(resource_task.clone());
let engine_task = Engine(osmain.clone(),
opts,
dom_event_port,
dom_event_chan,
resource_task,
image_cache_task);
for opts.urls.each |filename| {
let url = make_url(copy *filename, None);
@ -163,7 +168,7 @@ fn run_pipeline_screen(opts: &Opts) {
}
fn run_pipeline_png(_opts: &Opts, _outfile: &str) {
fail ~"PNG compositor is broken";
fail!(~"PNG compositor is broken");
}
#[cfg(broken)]
@ -190,7 +195,7 @@ fn run_pipeline_png(url: ~str, outfile: &str) {
match buffered_file_writer(&Path(outfile)) {
Ok(writer) => writer.write(pngdata_from_compositor.recv()),
Err(e) => fail e
Err(e) => fail!(e)
}
let (exit_chan, exit_response_from_engine) = pipes::stream();

View File

@ -1,25 +1,23 @@
use core::pipes::{Chan, Port};
use core::pipes;
use core::task;
use std::cell::Cell;
pub fn spawn_listener<A: Owned>(
f: fn~(oldcomm::Port<A>)) -> oldcomm::Chan<A> {
let setup_po = oldcomm::Port();
let setup_ch = oldcomm::Chan(&setup_po);
do task::spawn |move f| {
let po = oldcomm::Port();
let ch = oldcomm::Chan(&po);
oldcomm::send(setup_ch, ch);
f(move po);
pub fn spawn_listener<A: Owned>(f: fn~(Port<A>)) -> Chan<A> {
let (setup_po, setup_ch) = pipes::stream();
do task::spawn {
let (po, ch) = pipes::stream();
setup_ch.send(ch);
f(po);
}
oldcomm::recv(setup_po)
setup_po.recv()
}
pub fn spawn_conversation<A: Owned, B: Owned>
(f: fn~(oldcomm::Port<A>, oldcomm::Chan<B>))
-> (oldcomm::Port<B>, oldcomm::Chan<A>) {
let from_child = oldcomm::Port();
let to_parent = oldcomm::Chan(&from_child);
let to_child = do spawn_listener |move f, from_parent| {
f(from_parent, to_parent)
pub fn spawn_conversation<A: Owned, B: Owned>(f: fn~(Port<A>, Chan<B>)) -> (Port<B>, Chan<A>) {
let (from_child, to_parent) = pipes::stream();
let to_parent = Cell(to_parent);
let to_child = do spawn_listener |from_parent| {
f(from_parent, to_parent.take())
};
(from_child, to_child)
}

View File

@ -71,7 +71,7 @@ pub fn add_child<T:Copy,O:WriteMethods<T>>(ops: &O, parent: T, child: T) {
ops.with_tree_fields(&child, |child_tf| {
match child_tf.parent {
Some(_) => { fail ~"Already has a parent"; }
Some(_) => { fail!(~"Already has a parent"); }
None => { child_tf.parent = Some(parent); }
}
@ -100,14 +100,14 @@ pub fn add_child<T:Copy,O:WriteMethods<T>>(ops: &O, parent: T, child: T) {
pub fn remove_child<T:Copy,O:WriteMethods<T>>(ops: &O, parent: T, child: T) {
do ops.with_tree_fields(&child) |child_tf| {
match copy child_tf.parent {
None => { fail ~"Not a child"; }
None => { fail!(~"Not a child"); }
Some(parent_n) => {
assert ops.tree_eq(&parent, &parent_n);
// adjust parent fields
do ops.with_tree_fields(&parent) |parent_tf| {
match copy parent_tf.first_child {
None => { fail ~"parent had no first child??" },
None => { fail!(~"parent had no first child??") },
Some(first_child) if ops.tree_eq(&child, &first_child) => {
parent_tf.first_child = child_tf.next_sibling;
},
@ -115,7 +115,7 @@ pub fn remove_child<T:Copy,O:WriteMethods<T>>(ops: &O, parent: T, child: T) {
};
match copy parent_tf.last_child {
None => { fail ~"parent had no last child??" },
None => { fail!(~"parent had no last child??") },
Some(last_child) if ops.tree_eq(&child, &last_child) => {
parent_tf.last_child = child_tf.prev_sibling;
},