Rust upgrades

This commit is contained in:
Lars Bergstrom 2014-03-04 09:04:51 -08:00
parent caf1ed9446
commit bbac8aa5c3
130 changed files with 1236 additions and 985 deletions

2
.gitmodules vendored
View file

@ -69,7 +69,7 @@
url = https://github.com/mozilla-servo/skia.git url = https://github.com/mozilla-servo/skia.git
[submodule "src/compiler/rust"] [submodule "src/compiler/rust"]
path = src/compiler/rust path = src/compiler/rust
url = https://github.com/mozilla-servo/rust.git url = https://github.com/mozilla/rust.git
[submodule "src/support/alert/rust-alert"] [submodule "src/support/alert/rust-alert"]
path = src/support/alert/rust-alert path = src/support/alert/rust-alert
url = https://github.com/mozilla-servo/rust-alert.git url = https://github.com/mozilla-servo/rust-alert.git

View file

@ -38,15 +38,10 @@ else
CFG_RUSTC_FLAGS += -O -Z no-debug-borrows CFG_RUSTC_FLAGS += -O -Z no-debug-borrows
endif endif
CFG_RUSTC_FLAGS += -g
ifdef CFG_ENABLE_DEBUG ifdef CFG_ENABLE_DEBUG
$(info cfg: enabling more debugging (CFG_ENABLE_DEBUG)) $(info cfg: enabling more debugging in RUSTC (CFG_ENABLE_DEBUG))
CFG_RUSTC_FLAGS += -Z extra-debug-info CFG_RUSTC_SELF_FLAGS += -g
CFG_RUSTC_SELF_FLAGS += -Z extra-debug-info
else
# Enable debug!() etc even without configure --enable-debug
# The evaluation of these prints & their arguments is controlled
# at runtime by the environment variable RUST_LOG.
CFG_RUSTC_FLAGS += -Z debug-info
endif endif
export CFG_RUSTC export CFG_RUSTC
@ -135,8 +130,6 @@ endif
# their name already, while others don't. # their name already, while others don't.
DONE_$(1) = $$(B)src/$$(PATH_$(1))/lib*.dummy DONE_$(1) = $$(B)src/$$(PATH_$(1))/lib*.dummy
DEPS_SUBMODULES += $$(PATH_$(1)) DEPS_SUBMODULES += $$(PATH_$(1))
DEPS_SUBMODULES += $$(PATH_$(1))/.libs
DEPS_SUBMODULES += $$(PATH_$(1))/src/.libs
endef endef
# these will get populated. # these will get populated.
@ -163,7 +156,7 @@ endef
define DEF_SUBMODULE_RULES define DEF_SUBMODULE_RULES
ENV_RLDFLAGS_$(1) = -L $$(CFG_BUILD_HOME)workspace/lib/$$(CFG_TARGET_TRIPLES) ENV_RLDFLAGS_$(1) = -L $$(CFG_BUILD_HOME)workspace/lib/$$(CFG_TARGET_TRIPLES)
ENV_RLDFLAGS_$(1) += $$(foreach dep,$$(DEPS_$(1)),-L $$(B)src/$$(PATH_$$(dep)) -L $$(B)src/$$(PATH_$$(dep))/.libs -L $$(B)src/$$(PATH_$$(dep))/src/.libs) ENV_RLDFLAGS_$(1) += $$(foreach dep,$$(DEPS_$(1)),-L $$(B)src/$$(PATH_$$(dep)))
# variables that depend on dependency definitions from sub.mk! # variables that depend on dependency definitions from sub.mk!
ENV_CFLAGS_$(1) = CFLAGS="$$(CFLAGS_$(1))" ENV_CFLAGS_$(1) = CFLAGS="$$(CFLAGS_$(1))"
@ -329,11 +322,11 @@ $(BINDINGS_SRC)/ParserResults.pkl: $(globalgen_dependencies) \
ifneq ($(CFG_OSTYPE),linux-androideabi) ifneq ($(CFG_OSTYPE),linux-androideabi)
servo: $(DEPS_servo) servo: $(DEPS_servo)
@$(call E, compile: $@) @$(call E, compile: $@)
$(Q)$(RUSTC) $(RFLAGS_servo) -o $@ $< --bin $(Q)$(RUSTC) $(RFLAGS_servo) -o $@ $<
else else
servo: $(DEPS_servo) servo: $(DEPS_servo)
@$(call E, compile: $@) @$(call E, compile: $@)
$(Q)$(RUSTC) $(RFLAGS_servo) -Z gen-crate-map -o $@ $< --lib $(Q)$(RUSTC) $(RFLAGS_servo) -Z gen-crate-map -o $@ $< --crate-type lib
endif endif
# Darwin app packaging # Darwin app packaging

@ -1 +1 @@
Subproject commit d3b3c66a3a54a0455b068ede8fe2f48ed99ca908 Subproject commit 68a4f7d9babb0c638f3425ced08e13f9fbfdcf56

View file

@ -1,4 +1,4 @@
# If this file is modified, then rust will be forcibly cleaned and then rebuilt. # If this file is modified, then rust will be forcibly cleaned and then rebuilt.
# The actual contents of this file do not matter, but to trigger a change on the # The actual contents of this file do not matter, but to trigger a change on the
# build bots then the contents should be changed so git updates the mtime. # build bots then the contents should be changed so git updates the mtime.
2014-01-08 2014-02-24

View file

@ -2,12 +2,13 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use collections::hashmap::HashMap;
use geom::size::Size2D; use geom::size::Size2D;
use layers::platform::surface::NativePaintingGraphicsContext; use layers::platform::surface::NativePaintingGraphicsContext;
use servo_msg::compositor_msg::Tile; use servo_msg::compositor_msg::Tile;
use std::hashmap::HashMap; use std::hash::Hash;
use std::to_bytes::Cb; use std::hash::sip::SipState;
use std::util; use std::mem;
/// This is a struct used to store buffers when they are not in use. /// This is a struct used to store buffers when they are not in use.
/// The render task can quickly query for a particular size of buffer when it /// The render task can quickly query for a particular size of buffer when it
@ -27,16 +28,18 @@ pub struct BufferMap<T> {
/// A key with which to store buffers. It is based on the size of the buffer. /// A key with which to store buffers. It is based on the size of the buffer.
struct BufferKey([uint, ..2]); struct BufferKey([uint, ..2]);
impl IterBytes for BufferKey { impl Hash for BufferKey {
fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool { fn hash(&self, state: &mut SipState) {
let i = if lsb0 {0} else {1}; let BufferKey(ref bytes) = *self;
self[i].iter_bytes(lsb0, |x| f(x)) && self[1 - i].iter_bytes(lsb0, |x| f(x)) bytes.as_slice().hash(state);
} }
} }
impl Eq for BufferKey { impl Eq for BufferKey {
fn eq(&self, other: &BufferKey) -> bool { fn eq(&self, other: &BufferKey) -> bool {
self[0] == other[0] && self[1] == other[1] let BufferKey(s) = *self;
let BufferKey(o) = *other;
s[0] == o[0] && s[1] == o[1]
} }
} }
@ -79,9 +82,10 @@ impl<T: Tile> BufferMap<T> {
self.mem += new_buffer.get_mem(); self.mem += new_buffer.get_mem();
// use lazy insertion function to prevent unnecessary allocation // use lazy insertion function to prevent unnecessary allocation
let counter = &self.counter;
self.map.find_or_insert_with(new_key, |_| BufferValue { self.map.find_or_insert_with(new_key, |_| BufferValue {
buffers: ~[], buffers: ~[],
last_action: self.counter last_action: *counter
}).buffers.push(new_buffer); }).buffers.push(new_buffer);
let mut opt_key: Option<BufferKey> = None; let mut opt_key: Option<BufferKey> = None;
@ -97,7 +101,7 @@ impl<T: Tile> BufferMap<T> {
}; };
if { if {
let list = &mut self.map.get_mut(&old_key).buffers; let list = &mut self.map.get_mut(&old_key).buffers;
let condemned_buffer = list.pop(); let condemned_buffer = list.pop().take_unwrap();
self.mem -= condemned_buffer.get_mem(); self.mem -= condemned_buffer.get_mem();
condemned_buffer.destroy(graphics_context); condemned_buffer.destroy(graphics_context);
list.is_empty() list.is_empty()
@ -120,7 +124,7 @@ impl<T: Tile> BufferMap<T> {
buffer_val.last_action = self.counter; buffer_val.last_action = self.counter;
self.counter += 1; self.counter += 1;
let buffer = buffer_val.buffers.pop(); let buffer = buffer_val.buffers.pop().take_unwrap();
self.mem -= buffer.get_mem(); self.mem -= buffer.get_mem();
if buffer_val.buffers.is_empty() { if buffer_val.buffers.is_empty() {
flag = true; flag = true;
@ -139,7 +143,7 @@ impl<T: Tile> BufferMap<T> {
/// Destroys all buffers. /// Destroys all buffers.
pub fn clear(&mut self, graphics_context: &NativePaintingGraphicsContext) { pub fn clear(&mut self, graphics_context: &NativePaintingGraphicsContext) {
let map = util::replace(&mut self.map, HashMap::new()); let map = mem::replace(&mut self.map, HashMap::new());
for (_, value) in map.move_iter() { for (_, value) in map.move_iter() {
for tile in value.buffers.move_iter() { for tile in value.buffers.move_iter() {
tile.destroy(graphics_context) tile.destroy(graphics_context)

View file

@ -18,14 +18,14 @@ use color::Color;
use render_context::RenderContext; use render_context::RenderContext;
use text::TextRun; use text::TextRun;
use extra::arc::Arc;
use geom::{Point2D, Rect, Size2D, SideOffsets2D}; use geom::{Point2D, Rect, Size2D, SideOffsets2D};
use servo_net::image::base::Image; use servo_net::image::base::Image;
use servo_util::geometry::Au; use servo_util::geometry::Au;
use servo_util::range::Range; use servo_util::range::Range;
use std::cast::transmute_region; use std::cast::transmute_region;
use std::vec::VecIterator; use std::vec::Items;
use style::computed_values::border_style; use style::computed_values::border_style;
use sync::Arc;
pub struct DisplayListCollection<E> { pub struct DisplayListCollection<E> {
lists: ~[DisplayList<E>] lists: ~[DisplayList<E>]
@ -70,7 +70,7 @@ pub struct DisplayList<E> {
pub enum DisplayListIterator<'a,E> { pub enum DisplayListIterator<'a,E> {
EmptyDisplayListIterator, EmptyDisplayListIterator,
ParentDisplayListIterator(VecIterator<'a,DisplayList<E>>), ParentDisplayListIterator(Items<'a,DisplayList<E>>),
} }
impl<'a,E> Iterator<&'a DisplayList<E>> for DisplayListIterator<'a,E> { impl<'a,E> Iterator<&'a DisplayList<E>> for DisplayListIterator<'a,E> {
@ -226,7 +226,7 @@ pub struct ClipDisplayItem<E> {
pub enum DisplayItemIterator<'a,E> { pub enum DisplayItemIterator<'a,E> {
EmptyDisplayItemIterator, EmptyDisplayItemIterator,
ParentDisplayItemIterator(VecIterator<'a,DisplayItem<E>>), ParentDisplayItemIterator(Items<'a,DisplayItem<E>>),
} }
impl<'a,E> Iterator<&'a DisplayItem<E>> for DisplayItemIterator<'a,E> { impl<'a,E> Iterator<&'a DisplayItem<E>> for DisplayItemIterator<'a,E> {

View file

@ -5,7 +5,6 @@
use azure::{AzFloat, AzScaledFontRef}; use azure::{AzFloat, AzScaledFontRef};
use azure::azure_hl::{BackendType, ColorPattern}; use azure::azure_hl::{BackendType, ColorPattern};
use azure::scaled_font::ScaledFont; use azure::scaled_font::ScaledFont;
use extra::arc::Arc;
use geom::{Point2D, Rect, Size2D}; use geom::{Point2D, Rect, Size2D};
use std::cast; use std::cast;
use std::ptr; use std::ptr;
@ -15,6 +14,7 @@ use std::cell::RefCell;
use servo_util::cache::{Cache, HashCache}; use servo_util::cache::{Cache, HashCache};
use servo_util::range::Range; use servo_util::range::Range;
use style::computed_values::{text_decoration, font_weight, font_style}; use style::computed_values::{text_decoration, font_weight, font_style};
use sync::Arc;
use color::Color; use color::Color;
use font_context::FontContext; use font_context::FontContext;
@ -230,7 +230,7 @@ impl<'a> Font {
let metrics = handle.get_metrics(); let metrics = handle.get_metrics();
return Ok(Rc::from_mut(RefCell::new(Font { return Ok(Rc::new(RefCell::new(Font {
handle: handle, handle: handle,
azure_font: None, azure_font: None,
shaper: None, shaper: None,
@ -269,7 +269,7 @@ impl<'a> Font {
Err(()) => return Err(()) Err(()) => return Err(())
}; };
return Ok(Rc::from_mut(RefCell::new(Font::new_from_adopted_handle(fctx, styled_handle, style, backend)))); return Ok(Rc::new(RefCell::new(Font::new_from_adopted_handle(fctx, styled_handle, style, backend))));
} }
fn make_shaper(&'a mut self) -> &'a Shaper { fn make_shaper(&'a mut self) -> &'a Shaper {
@ -394,9 +394,9 @@ impl Font {
// TODO(Issue #64): this call needs to move into azure_hl.rs // TODO(Issue #64): this call needs to move into azure_hl.rs
AzDrawTargetFillGlyphs(target.azure_draw_target, AzDrawTargetFillGlyphs(target.azure_draw_target,
azfontref, azfontref,
ptr::to_unsafe_ptr(&glyphbuf), &glyphbuf,
azure_pattern, azure_pattern,
ptr::to_unsafe_ptr(&options), &options,
ptr::null()); ptr::null());
} }
} }
@ -428,9 +428,10 @@ impl Font {
//FIXME (ksh8281) //FIXME (ksh8281)
self.make_shaper(); self.make_shaper();
let shaper = &self.shaper;
self.shape_cache.find_or_create(&text, |txt| { self.shape_cache.find_or_create(&text, |txt| {
let mut glyphs = GlyphStore::new(text.char_len(), is_whitespace); let mut glyphs = GlyphStore::new(text.char_len(), is_whitespace);
self.shaper.get_ref().shape_text(*txt, &mut glyphs); shaper.get_ref().shape_text(*txt, &mut glyphs);
Arc::new(glyphs) Arc::new(glyphs)
}) })
} }
@ -444,8 +445,9 @@ impl Font {
} }
pub fn glyph_h_advance(&mut self, glyph: GlyphIndex) -> FractionalPixel { pub fn glyph_h_advance(&mut self, glyph: GlyphIndex) -> FractionalPixel {
let handle = &self.handle;
self.glyph_advance_cache.find_or_create(&glyph, |glyph| { self.glyph_advance_cache.find_or_create(&glyph, |glyph| {
match self.handle.glyph_h_advance(*glyph) { match handle.glyph_h_advance(*glyph) {
Some(adv) => adv, Some(adv) => adv,
None => /* FIXME: Need fallback strategy */ 10f64 as FractionalPixel None => /* FIXME: Need fallback strategy */ 10f64 as FractionalPixel
} }

View file

@ -9,9 +9,9 @@ use platform::font::FontHandle;
use platform::font_context::FontContextHandle; use platform::font_context::FontContextHandle;
use azure::azure_hl::BackendType; use azure::azure_hl::BackendType;
use collections::hashmap::HashMap;
use servo_util::cache::{Cache, LRUCache}; use servo_util::cache::{Cache, LRUCache};
use servo_util::time::ProfilerChan; use servo_util::time::ProfilerChan;
use std::hashmap::HashMap;
use std::rc::Rc; use std::rc::Rc;
use std::cell::RefCell; use std::cell::RefCell;
@ -198,11 +198,9 @@ impl FontContext {
debug!("(create font group) --- finished ---"); debug!("(create font group) --- finished ---");
unsafe { Rc::new(
Rc::new_unchecked( RefCell::new(
RefCell::new( FontGroup::new(style.families.to_owned(), &used_style, fonts)))
FontGroup::new(style.families.to_owned(), &used_style, fonts)))
}
} }
fn create_font_instance(&self, desc: &FontDescriptor) -> Result<Rc<RefCell<Font>>, ()> { fn create_font_instance(&self, desc: &FontDescriptor) -> Result<Rc<RefCell<Font>>, ()> {
@ -213,7 +211,7 @@ impl FontContext {
desc.style.clone()); desc.style.clone());
result_handle.and_then(|handle| { result_handle.and_then(|handle| {
Ok( Ok(
Rc::from_mut( Rc::new(
RefCell::new( RefCell::new(
Font::new_from_adopted_handle(self, Font::new_from_adopted_handle(self,
handle, handle,

View file

@ -2,6 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use collections::hashmap::HashMap;
use font::SpecifiedFontStyle; use font::SpecifiedFontStyle;
use gfx_font::FontHandleMethods; use gfx_font::FontHandleMethods;
use platform::font::FontHandle; use platform::font::FontHandle;
@ -11,7 +12,6 @@ use style::computed_values::{font_weight, font_style};
use servo_util::time::{ProfilerChan, profile}; use servo_util::time::{ProfilerChan, profile};
use servo_util::time; use servo_util::time;
use std::hashmap::HashMap;
pub type FontFamilyMap = HashMap<~str, FontFamily>; pub type FontFamilyMap = HashMap<~str, FontFamily>;

View file

@ -7,29 +7,31 @@
#[feature(globs, managed_boxes, macro_rules)]; #[feature(globs, managed_boxes, macro_rules)];
extern mod azure; extern crate azure;
extern mod extra; extern crate collections;
extern mod geom; extern crate extra;
extern mod layers; extern crate geom;
extern mod stb_image; extern crate layers;
extern mod png; extern crate stb_image;
extern mod servo_net = "net"; extern crate png;
extern mod servo_util = "util"; extern crate servo_net = "net";
extern mod style; extern crate servo_util = "util";
extern mod servo_msg = "msg"; extern crate servo_msg = "msg";
extern crate style;
extern crate sync;
// Eventually we would like the shaper to be pluggable, as many operating systems have their own // Eventually we would like the shaper to be pluggable, as many operating systems have their own
// shapers. For now, however, this is a hard dependency. // shapers. For now, however, this is a hard dependency.
extern mod harfbuzz; extern crate harfbuzz;
// Linux and Android-specific library dependencies // Linux and Android-specific library dependencies
#[cfg(target_os="linux")] #[cfg(target_os="android")] extern mod fontconfig; #[cfg(target_os="linux")] #[cfg(target_os="android")] extern crate fontconfig;
#[cfg(target_os="linux")] #[cfg(target_os="android")] extern mod freetype; #[cfg(target_os="linux")] #[cfg(target_os="android")] extern crate freetype;
// Mac OS-specific library dependencies // Mac OS-specific library dependencies
#[cfg(target_os="macos")] extern mod core_foundation; #[cfg(target_os="macos")] extern crate core_foundation;
#[cfg(target_os="macos")] extern mod core_graphics; #[cfg(target_os="macos")] extern crate core_graphics;
#[cfg(target_os="macos")] extern mod core_text; #[cfg(target_os="macos")] extern crate core_text;
pub use gfx_font = font; pub use gfx_font = font;
pub use gfx_font_context = font_context; pub use gfx_font_context = font_context;

View file

@ -9,12 +9,14 @@ macro_rules! bitfield(
impl $bitfieldname { impl $bitfieldname {
#[inline] #[inline]
pub fn $getter(self) -> bool { pub fn $getter(self) -> bool {
(*self & $value) != 0 let $bitfieldname(this) = self;
(this & $value) != 0
} }
#[inline] #[inline]
pub fn $setter(&mut self, value: bool) { pub fn $setter(&mut self, value: bool) {
*self = $bitfieldname((**self & !$value) | (if value { $value } else { 0 })) let $bitfieldname(this) = *self;
*self = $bitfieldname((this & !$value) | (if value { $value } else { 0 }))
} }
} }
) )

View file

@ -2,7 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
extern mod freetype; extern crate freetype;
use font::{FontHandleMethods, FontMetrics, FontTableMethods}; use font::{FontHandleMethods, FontMetrics, FontTableMethods};
use font::{FontTableTag, FractionalPixel, SpecifiedFontStyle, UsedFontStyle}; use font::{FontTableTag, FractionalPixel, SpecifiedFontStyle, UsedFontStyle};

View file

@ -2,8 +2,8 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
extern mod freetype; extern crate freetype;
extern mod fontconfig; extern crate fontconfig;
use fontconfig::fontconfig::{ use fontconfig::fontconfig::{
FcChar8, FcResultMatch, FcSetSystem, FcPattern, FcChar8, FcResultMatch, FcSetSystem, FcPattern,

View file

@ -2,7 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
extern mod freetype; extern crate freetype;
use font::{FontHandleMethods, FontMetrics, FontTableMethods}; use font::{FontHandleMethods, FontMetrics, FontTableMethods};
use font::{FontTableTag, FractionalPixel, SpecifiedFontStyle, UsedFontStyle}; use font::{FontTableTag, FractionalPixel, SpecifiedFontStyle, UsedFontStyle};
@ -102,7 +102,7 @@ impl FontHandleMethods for FontHandle {
let mut face: FT_Face = ptr::null(); let mut face: FT_Face = ptr::null();
let face_index = 0 as FT_Long; let face_index = 0 as FT_Long;
let result = FT_New_Memory_Face(lib, cbuf, cbuflen as FT_Long, let result = FT_New_Memory_Face(lib, cbuf, cbuflen as FT_Long,
face_index, ptr::to_mut_unsafe_ptr(&mut face)); face_index, &mut face);
if !result.succeeded() || face.is_null() { if !result.succeeded() || face.is_null() {
return Err(()); return Err(());
@ -286,7 +286,7 @@ impl<'a> FontHandle {
let face_index = 0 as FT_Long; let face_index = 0 as FT_Long;
file.to_c_str().with_ref(|file_str| { file.to_c_str().with_ref(|file_str| {
FT_New_Face(ft_ctx, file_str, FT_New_Face(ft_ctx, file_str,
face_index, ptr::to_mut_unsafe_ptr(&mut face)); face_index, &mut face);
}); });
if face.is_null() { if face.is_null() {
return Err(()); return Err(());
@ -313,7 +313,7 @@ impl<'a> FontHandle {
let face_index = 0 as FT_Long; let face_index = 0 as FT_Long;
file.to_c_str().with_ref(|file_str| { file.to_c_str().with_ref(|file_str| {
FT_New_Face(ft_ctx, file_str, FT_New_Face(ft_ctx, file_str,
face_index, ptr::to_mut_unsafe_ptr(&mut face)); face_index, &mut face);
}); });
if face.is_null() { if face.is_null() {
return Err(()); return Err(());

View file

@ -14,7 +14,7 @@ use std::ptr;
use std::rc::Rc; use std::rc::Rc;
#[deriving(Clone)] #[deriving(Clone)]
struct FreeTypeLibraryHandle { pub struct FreeTypeLibraryHandle {
ctx: FT_Library, ctx: FT_Library,
} }

View file

@ -2,8 +2,8 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
extern mod freetype; extern crate freetype;
extern mod fontconfig; extern crate fontconfig;
use fontconfig::fontconfig::{ use fontconfig::fontconfig::{
FcChar8, FcResultMatch, FcSetSystem, FcPattern, FcChar8, FcResultMatch, FcSetSystem, FcPattern,
@ -25,7 +25,7 @@ use font_list::{FontEntry, FontFamily, FontFamilyMap};
use platform::font::FontHandle; use platform::font::FontHandle;
use platform::font_context::FontContextHandle; use platform::font_context::FontContextHandle;
use std::hashmap::HashMap; use collections::HashMap;
use std::libc; use std::libc;
use std::libc::{c_int, c_char}; use std::libc::{c_int, c_char};
use std::ptr; use std::ptr;
@ -68,7 +68,7 @@ impl FontListHandle {
unsafe { unsafe {
let config = FcConfigGetCurrent(); let config = FcConfigGetCurrent();
let font_set = FcConfigGetFonts(config, FcSetSystem); let font_set = FcConfigGetFonts(config, FcSetSystem);
let font_set_array_ptr = ptr::to_unsafe_ptr(&font_set); let font_set_array_ptr = &font_set;
let pattern = FcPatternCreate(); let pattern = FcPatternCreate();
assert!(pattern.is_not_null()); assert!(pattern.is_not_null());
"family".to_c_str().with_ref(|FC_FAMILY| { "family".to_c_str().with_ref(|FC_FAMILY| {

View file

@ -4,9 +4,9 @@
/// Implementation of Quartz (CoreGraphics) fonts. /// Implementation of Quartz (CoreGraphics) fonts.
extern mod core_foundation; extern crate core_foundation;
extern mod core_graphics; extern crate core_graphics;
extern mod core_text; extern crate core_text;
use font::{FontHandleMethods, FontMetrics, FontTableMethods}; use font::{FontHandleMethods, FontMetrics, FontTableMethods};
use font::FontTableTag; use font::FontTableTag;
@ -130,8 +130,8 @@ impl FontHandleMethods for FontHandle {
let glyphs: [CGGlyph, ..1] = [0 as CGGlyph]; let glyphs: [CGGlyph, ..1] = [0 as CGGlyph];
let count: CFIndex = 1; let count: CFIndex = 1;
let result = self.ctfont.get_glyphs_for_characters(ptr::to_unsafe_ptr(&characters[0]), let result = self.ctfont.get_glyphs_for_characters(&characters[0],
ptr::to_unsafe_ptr(&glyphs[0]), &glyphs[0],
count); count);
if !result { if !result {

View file

@ -7,12 +7,12 @@ use font_list::{FontEntry, FontFamily, FontFamilyMap};
use platform::macos::font::FontHandle; use platform::macos::font::FontHandle;
use platform::macos::font_context::FontContextHandle; use platform::macos::font_context::FontContextHandle;
use collections::hashmap::HashMap;
use core_foundation::base::TCFType; use core_foundation::base::TCFType;
use core_foundation::string::{CFString, CFStringRef}; use core_foundation::string::{CFString, CFStringRef};
use core_text::font_descriptor::{CTFontDescriptor, CTFontDescriptorRef}; use core_text::font_descriptor::{CTFontDescriptor, CTFontDescriptorRef};
use core_text; use core_text;
use std::cast; use std::cast;
use std::hashmap::HashMap;
pub struct FontListHandle { pub struct FontListHandle {
fctx: FontContextHandle, fctx: FontContextHandle,

View file

@ -9,7 +9,6 @@ use azure::azure_hl::{B8G8R8A8, Color, ColorPattern, DrawOptions};
use azure::azure_hl::{DrawSurfaceOptions, DrawTarget, Linear, StrokeOptions}; use azure::azure_hl::{DrawSurfaceOptions, DrawTarget, Linear, StrokeOptions};
use azure::AZ_CAP_BUTT; use azure::AZ_CAP_BUTT;
use azure::AzFloat; use azure::AzFloat;
use extra::arc::Arc;
use geom::point::Point2D; use geom::point::Point2D;
use geom::rect::Rect; use geom::rect::Rect;
use geom::size::Size2D; use geom::size::Size2D;
@ -20,6 +19,7 @@ use servo_util::geometry::Au;
use servo_util::opts::Opts; use servo_util::opts::Opts;
use std::libc::types::common::c99::uint16_t; use std::libc::types::common::c99::uint16_t;
use std::libc::size_t; use std::libc::size_t;
use sync::Arc;
pub struct RenderContext<'a> { pub struct RenderContext<'a> {
draw_target: &'a DrawTarget, draw_target: &'a DrawTarget,

View file

@ -22,9 +22,9 @@ use servo_util::time::{ProfilerChan, profile};
use servo_util::time; use servo_util::time;
use servo_util::task::send_on_failure; use servo_util::task::send_on_failure;
use std::comm::{Chan, Port, SharedChan}; use std::comm::{Chan, Port, Chan};
use std::task; use std::task;
use extra::arc::Arc; use sync::Arc;
use buffer_map::BufferMap; use buffer_map::BufferMap;
use display_list::DisplayListCollection; use display_list::DisplayListCollection;
@ -66,7 +66,7 @@ pub fn BufferRequest(screen_rect: Rect<uint>, page_rect: Rect<f32>) -> BufferReq
// FIXME(rust#9155): this should be a newtype struct, but // FIXME(rust#9155): this should be a newtype struct, but
// generic newtypes ICE when compiled cross-crate // generic newtypes ICE when compiled cross-crate
pub struct RenderChan<T> { pub struct RenderChan<T> {
chan: SharedChan<Msg<T>>, chan: Chan<Msg<T>>,
} }
impl<T: Send> Clone for RenderChan<T> { impl<T: Send> Clone for RenderChan<T> {
@ -79,7 +79,7 @@ impl<T: Send> Clone for RenderChan<T> {
impl<T: Send> RenderChan<T> { impl<T: Send> RenderChan<T> {
pub fn new() -> (Port<Msg<T>>, RenderChan<T>) { pub fn new() -> (Port<Msg<T>>, RenderChan<T>) {
let (port, chan) = SharedChan::new(); let (port, chan) = Chan::new();
let render_chan = RenderChan { let render_chan = RenderChan {
chan: chan, chan: chan,
}; };
@ -149,9 +149,9 @@ impl<C: RenderListener + Send,T:Send+Freeze> RenderTask<C,T> {
opts: Opts, opts: Opts,
profiler_chan: ProfilerChan, profiler_chan: ProfilerChan,
shutdown_chan: Chan<()>) { shutdown_chan: Chan<()>) {
let mut builder = task::task(); let mut builder = task::task().named("RenderTask");
send_on_failure(&mut builder, FailureMsg(failure_msg), (*constellation_chan).clone()); let ConstellationChan(c) = constellation_chan.clone();
builder.name("RenderTask"); send_on_failure(&mut builder, FailureMsg(failure_msg), c);
builder.spawn(proc() { builder.spawn(proc() {
{ // Ensures RenderTask and graphics context are destroyed before shutdown msg { // Ensures RenderTask and graphics context are destroyed before shutdown msg
@ -191,8 +191,10 @@ impl<C: RenderListener + Send,T:Send+Freeze> RenderTask<C,T> {
render_task.start(); render_task.start();
// Destroy all the buffers. // Destroy all the buffers.
render_task.native_graphics_context.as_ref().map( {
|ctx| render_task.buffer_map.clear(ctx)); let ctx = render_task.native_graphics_context.as_ref().unwrap();
render_task.buffer_map.clear(ctx);
}
} }
debug!("render_task: shutdown_chan send"); debug!("render_task: shutdown_chan send");
@ -211,7 +213,8 @@ impl<C: RenderListener + Send,T:Send+Freeze> RenderTask<C,T> {
self.compositor.set_layer_page_size_and_color(self.id, render_layer.size, self.epoch, render_layer.color); self.compositor.set_layer_page_size_and_color(self.id, render_layer.size, self.epoch, render_layer.color);
} else { } else {
debug!("render_task: render ready msg"); debug!("render_task: render ready msg");
self.constellation_chan.send(RendererReadyMsg(self.id)); let ConstellationChan(ref mut c) = self.constellation_chan;
c.send(RendererReadyMsg(self.id));
} }
self.render_layer = Some(render_layer); self.render_layer = Some(render_layer);
} }
@ -251,12 +254,8 @@ impl<C: RenderListener + Send,T:Send+Freeze> RenderTask<C,T> {
} }
fn render(&mut self, tiles: ~[BufferRequest], scale: f32) { fn render(&mut self, tiles: ~[BufferRequest], scale: f32) {
let render_layer; if self.render_layer.is_none() {
match self.render_layer { return
Some(ref r_layer) => {
render_layer = r_layer;
}
_ => return, // nothing to do
} }
self.compositor.set_render_state(RenderingRenderState); self.compositor.set_render_state(RenderingRenderState);
@ -311,6 +310,7 @@ impl<C: RenderListener + Send,T:Send+Freeze> RenderTask<C,T> {
// Draw the display list. // Draw the display list.
profile(time::RenderingDrawingCategory, self.profiler_chan.clone(), || { profile(time::RenderingDrawingCategory, self.profiler_chan.clone(), || {
let render_layer = self.render_layer.as_ref().unwrap();
render_layer.display_list_collection.get().draw_lists_into_context(&mut ctx); render_layer.display_list_collection.get().draw_lists_into_context(&mut ctx);
ctx.draw_target.flush(); ctx.draw_target.flush();
}); });
@ -395,7 +395,8 @@ impl<C: RenderListener + Send,T:Send+Freeze> RenderTask<C,T> {
self.compositor.paint(self.id, layer_buffer_set, self.epoch); self.compositor.paint(self.id, layer_buffer_set, self.epoch);
} else { } else {
debug!("render_task: RendererReadyMsg send"); debug!("render_task: RendererReadyMsg send");
self.constellation_chan.send(RendererReadyMsg(self.id)); let ConstellationChan(ref mut c) = self.constellation_chan;
c.send(RendererReadyMsg(self.id));
} }
self.compositor.set_render_state(IdleRenderState); self.compositor.set_render_state(IdleRenderState);
}) })

View file

@ -9,9 +9,10 @@ use servo_util::geometry;
use std::cmp::{Ord, Eq}; use std::cmp::{Ord, Eq};
use std::num::NumCast; use std::num::NumCast;
use std::mem;
use std::u16; use std::u16;
use std::uint;
use std::vec; use std::vec;
use std::util;
use std::iter; use std::iter;
use geom::point::Point2D; use geom::point::Point2D;
@ -45,7 +46,8 @@ impl GlyphEntry {
assert!(is_simple_advance(advance)); assert!(is_simple_advance(advance));
let index_mask = index as u32; let index_mask = index as u32;
let advance_mask = (*advance as u32) << GLYPH_ADVANCE_SHIFT; let Au(advance) = advance;
let advance_mask = (advance as u32) << GLYPH_ADVANCE_SHIFT;
GlyphEntry::new(index_mask | advance_mask | FLAG_IS_SIMPLE_GLYPH) GlyphEntry::new(index_mask | advance_mask | FLAG_IS_SIMPLE_GLYPH)
} }
@ -53,7 +55,7 @@ impl GlyphEntry {
// Create a GlyphEntry for uncommon case; should be accompanied by // Create a GlyphEntry for uncommon case; should be accompanied by
// initialization of the actual DetailedGlyph data in DetailedGlyphStore // initialization of the actual DetailedGlyph data in DetailedGlyphStore
fn complex(starts_cluster: bool, starts_ligature: bool, glyph_count: uint) -> GlyphEntry { fn complex(starts_cluster: bool, starts_ligature: bool, glyph_count: uint) -> GlyphEntry {
assert!(glyph_count <= u16::max_value as uint); assert!(glyph_count <= uint::MAX);
debug!("creating complex glyph entry: starts_cluster={}, starts_ligature={}, \ debug!("creating complex glyph entry: starts_cluster={}, starts_ligature={}, \
glyph_count={}", glyph_count={}",
@ -77,7 +79,7 @@ impl GlyphEntry {
/// Create a GlyphEntry for the case where glyphs couldn't be found for the specified /// Create a GlyphEntry for the case where glyphs couldn't be found for the specified
/// character. /// character.
fn missing(glyph_count: uint) -> GlyphEntry { fn missing(glyph_count: uint) -> GlyphEntry {
assert!(glyph_count <= u16::max_value as uint); assert!(glyph_count <= uint::MAX);
GlyphEntry::new((glyph_count as u32) << GLYPH_COUNT_SHIFT) GlyphEntry::new((glyph_count as u32) << GLYPH_COUNT_SHIFT)
} }
@ -404,7 +406,7 @@ impl<'a> DetailedGlyphStore {
// Thar be dragons here. You have been warned. (Tips accepted.) // Thar be dragons here. You have been warned. (Tips accepted.)
let mut unsorted_records: ~[DetailedGlyphRecord] = ~[]; let mut unsorted_records: ~[DetailedGlyphRecord] = ~[];
util::swap(&mut self.detail_lookup, &mut unsorted_records); mem::swap(&mut self.detail_lookup, &mut unsorted_records);
let mut mut_records : ~[DetailedGlyphRecord] = unsorted_records; let mut mut_records : ~[DetailedGlyphRecord] = unsorted_records;
mut_records.sort_by(|a, b| { mut_records.sort_by(|a, b| {
if a < b { if a < b {
@ -414,7 +416,7 @@ impl<'a> DetailedGlyphStore {
} }
}); });
let mut sorted_records = mut_records; let mut sorted_records = mut_records;
util::swap(&mut self.detail_lookup, &mut sorted_records); mem::swap(&mut self.detail_lookup, &mut sorted_records);
self.lookup_is_sorted = true; self.lookup_is_sorted = true;
} }

View file

@ -2,7 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
extern mod harfbuzz; extern crate harfbuzz;
use font::{Font, FontHandleMethods, FontTableMethods, FontTableTag}; use font::{Font, FontHandleMethods, FontTableMethods, FontTableTag};
use platform::font::FontTable; use platform::font::FontTable;
@ -39,8 +39,8 @@ use servo_util::geometry::Au;
use servo_util::range::Range; use servo_util::range::Range;
use std::cast::transmute; use std::cast::transmute;
use std::char; use std::char;
use std::cmp;
use std::libc::{c_uint, c_int, c_void, c_char}; use std::libc::{c_uint, c_int, c_void, c_char};
use std::num;
use std::ptr::null; use std::ptr::null;
use std::ptr; use std::ptr;
use std::vec; use std::vec;
@ -86,7 +86,7 @@ impl ShapedGlyphData {
assert!(i < self.count); assert!(i < self.count);
unsafe { unsafe {
let glyph_info_i = ptr::offset(self.glyph_infos, i as int); let glyph_info_i = self.glyph_infos.offset(i as int);
(*glyph_info_i).cluster as uint (*glyph_info_i).cluster as uint
} }
} }
@ -100,8 +100,8 @@ impl ShapedGlyphData {
assert!(i < self.count); assert!(i < self.count);
unsafe { unsafe {
let glyph_info_i = ptr::offset(self.glyph_infos, i as int); let glyph_info_i = self.glyph_infos.offset(i as int);
let pos_info_i = ptr::offset(self.pos_infos, i as int); let pos_info_i = self.pos_infos.offset(i as int);
let x_offset = Shaper::fixed_to_float((*pos_info_i).x_offset); let x_offset = Shaper::fixed_to_float((*pos_info_i).x_offset);
let y_offset = Shaper::fixed_to_float((*pos_info_i).y_offset); let y_offset = Shaper::fixed_to_float((*pos_info_i).y_offset);
let x_advance = Shaper::fixed_to_float((*pos_info_i).x_advance); let x_advance = Shaper::fixed_to_float((*pos_info_i).x_advance);
@ -318,7 +318,7 @@ impl Shaper {
let mut max_glyph_idx = glyph_span.end(); let mut max_glyph_idx = glyph_span.end();
for i in char_byte_span.eachi() { for i in char_byte_span.eachi() {
if byteToGlyph[i] > NO_GLYPH { if byteToGlyph[i] > NO_GLYPH {
max_glyph_idx = num::max(byteToGlyph[i] as uint + 1, max_glyph_idx); max_glyph_idx = cmp::max(byteToGlyph[i] as uint + 1, max_glyph_idx);
} }
} }
@ -393,7 +393,7 @@ impl Shaper {
// clamp to end of text. (I don't think this will be necessary, but..) // clamp to end of text. (I don't think this will be necessary, but..)
let end = covered_byte_span.end(); // FIXME: borrow checker workaround let end = covered_byte_span.end(); // FIXME: borrow checker workaround
covered_byte_span.extend_to(num::min(end, byte_max)); covered_byte_span.extend_to(cmp::min(end, byte_max));
// fast path: 1-to-1 mapping of single char and single glyph. // fast path: 1-to-1 mapping of single char and single glyph.
if glyph_span.length() == 1 { if glyph_span.length() == 1 {

View file

@ -2,12 +2,12 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use extra::arc::Arc;
use font::{Font, FontDescriptor, RunMetrics, FontStyle, FontMetrics}; use font::{Font, FontDescriptor, RunMetrics, FontStyle, FontMetrics};
use servo_util::geometry::Au; use servo_util::geometry::Au;
use servo_util::range::Range; use servo_util::range::Range;
use std::vec::VecIterator; use std::vec::Items;
use style::computed_values::text_decoration; use style::computed_values::text_decoration;
use sync::Arc;
use text::glyph::GlyphStore; use text::glyph::GlyphStore;
/// A text run. /// A text run.
@ -22,7 +22,7 @@ pub struct TextRun {
} }
pub struct SliceIterator<'a> { pub struct SliceIterator<'a> {
priv glyph_iter: VecIterator<'a, Arc<GlyphStore>>, priv glyph_iter: Items<'a, Arc<GlyphStore>>,
priv range: Range, priv range: Range,
priv offset: uint, priv offset: uint,
} }

View file

@ -18,7 +18,6 @@ use windowing::{WindowEvent, WindowMethods,
use azure::azure_hl::{SourceSurfaceMethods, Color}; use azure::azure_hl::{SourceSurfaceMethods, Color};
use azure::azure_hl; use azure::azure_hl;
use extra::time::precise_time_s;
use geom::matrix::identity; use geom::matrix::identity;
use geom::point::Point2D; use geom::point::Point2D;
use geom::rect::Rect; use geom::rect::Rect;
@ -36,19 +35,16 @@ use servo_msg::constellation_msg;
use servo_util::opts::Opts; use servo_util::opts::Opts;
use servo_util::time::{profile, ProfilerChan, Timer}; use servo_util::time::{profile, ProfilerChan, Timer};
use servo_util::{time, url}; use servo_util::{time, url};
use std::comm::Port; use std::cmp;
use std::num::Orderable; use std::comm::{Empty, Disconnected, Data, Port};
use std::path::Path; use std::path::Path;
use std::rc::Rc;
use time::precise_time_s;
//FIXME: switch to std::rc when we upgrade Rust
use layers::temp_rc::Rc;
//use std::rc::Rc;
use std::rc;
pub struct IOCompositor { pub struct IOCompositor {
/// The application window. /// The application window.
window: rc::Rc<Window>, window: Rc<Window>,
/// The port on which we receive messages. /// The port on which we receive messages.
port: Port<Msg>, port: Port<Msg>,
@ -120,7 +116,7 @@ impl IOCompositor {
port: Port<Msg>, port: Port<Msg>,
constellation_chan: ConstellationChan, constellation_chan: ConstellationChan,
profiler_chan: ProfilerChan) -> IOCompositor { profiler_chan: ProfilerChan) -> IOCompositor {
let window: rc::Rc<Window> = WindowMethods::new(app); let window: Rc<Window> = WindowMethods::new(app);
// Create an initial layer tree. // Create an initial layer tree.
// //
@ -171,7 +167,10 @@ impl IOCompositor {
fn run (&mut self) { fn run (&mut self) {
// Tell the constellation about the initial window size. // Tell the constellation about the initial window size.
self.constellation_chan.send(ResizedWindowMsg(self.window_size)); {
let ConstellationChan(ref chan) = self.constellation_chan;
chan.send(ResizedWindowMsg(self.window_size));
}
// Enter the main event loop. // Enter the main event loop.
while !self.done { while !self.done {
@ -213,80 +212,89 @@ impl IOCompositor {
// Drain compositor port, sometimes messages contain channels that are blocking // Drain compositor port, sometimes messages contain channels that are blocking
// another task from finishing (i.e. SetIds) // another task from finishing (i.e. SetIds)
while self.port.try_recv().is_some() {} while true {
match self.port.try_recv() {
Empty | Disconnected => break,
Data(_) => {},
}
}
// Tell the profiler to shut down. // Tell the profiler to shut down.
self.profiler_chan.send(time::ExitMsg); let ProfilerChan(ref chan) = self.profiler_chan;
chan.send(time::ExitMsg);
} }
fn handle_message(&mut self) { fn handle_message(&mut self) {
loop { loop {
match (self.port.try_recv(), self.shutting_down) { match (self.port.try_recv(), self.shutting_down) {
(None, _) => break, (Empty, _) => break,
(Disconnected, _) => break,
(Some(Exit(chan)), _) => { (Data(Exit(chan)), _) => {
debug!("shutting down the constellation"); debug!("shutting down the constellation");
self.constellation_chan.send(ExitMsg); let ConstellationChan(ref con_chan) = self.constellation_chan;
con_chan.send(ExitMsg);
chan.send(()); chan.send(());
self.shutting_down = true; self.shutting_down = true;
} }
(Some(ShutdownComplete), _) => { (Data(ShutdownComplete), _) => {
debug!("constellation completed shutdown"); debug!("constellation completed shutdown");
self.done = true; self.done = true;
} }
(Some(ChangeReadyState(ready_state)), false) => { (Data(ChangeReadyState(ready_state)), false) => {
self.window.borrow().set_ready_state(ready_state); self.window.borrow().set_ready_state(ready_state);
self.ready_state = ready_state; self.ready_state = ready_state;
} }
(Some(ChangeRenderState(render_state)), false) => { (Data(ChangeRenderState(render_state)), false) => {
self.change_render_state(render_state); self.change_render_state(render_state);
} }
(Some(SetUnRenderedColor(_id, color)), false) => { (Data(SetUnRenderedColor(_id, color)), false) => {
self.set_unrendered_color(_id, color); self.set_unrendered_color(_id, color);
} }
(Some(SetIds(frame_tree, response_chan, new_constellation_chan)), _) => { (Data(SetIds(frame_tree, response_chan, new_constellation_chan)), _) => {
self.set_ids(frame_tree, response_chan, new_constellation_chan); self.set_ids(frame_tree, response_chan, new_constellation_chan);
} }
(Some(GetGraphicsMetadata(chan)), false) => { (Data(GetGraphicsMetadata(chan)), false) => {
chan.send(Some(azure_hl::current_graphics_metadata())); chan.send(Some(azure_hl::current_graphics_metadata()));
} }
(Some(NewLayer(_id, new_size)), false) => { (Data(NewLayer(_id, new_size)), false) => {
self.create_new_layer(_id, new_size); self.create_new_layer(_id, new_size);
} }
(Some(SetLayerPageSize(id, new_size, epoch)), false) => { (Data(SetLayerPageSize(id, new_size, epoch)), false) => {
self.set_layer_page_size(id, new_size, epoch); self.set_layer_page_size(id, new_size, epoch);
} }
(Some(SetLayerClipRect(id, new_rect)), false) => { (Data(SetLayerClipRect(id, new_rect)), false) => {
self.set_layer_clip_rect(id, new_rect); self.set_layer_clip_rect(id, new_rect);
} }
(Some(DeleteLayer(id)), _) => { (Data(DeleteLayer(id)), _) => {
self.delete_layer(id); self.delete_layer(id);
} }
(Some(Paint(id, new_layer_buffer_set, epoch)), false) => { (Data(Paint(id, new_layer_buffer_set, epoch)), false) => {
self.paint(id, new_layer_buffer_set, epoch); self.paint(id, new_layer_buffer_set, epoch);
} }
(Some(InvalidateRect(id, rect)), false) => { (Data(InvalidateRect(id, rect)), false) => {
self.invalidate_rect(id, rect); self.invalidate_rect(id, rect);
} }
(Some(ScrollFragmentPoint(id, point)), false) => { (Data(ScrollFragmentPoint(id, point)), false) => {
self.scroll_fragment_to_point(id, point); self.scroll_fragment_to_point(id, point);
} }
(Some(LoadComplete(..)), false) => { (Data(LoadComplete(..)), false) => {
self.load_complete = true; self.load_complete = true;
} }
@ -350,7 +358,10 @@ impl IOCompositor {
let window_size = self.window.borrow().size(); let window_size = self.window.borrow().size();
let window_size = Size2D(window_size.width as uint, let window_size = Size2D(window_size.width as uint,
window_size.height as uint); window_size.height as uint);
new_constellation_chan.send(ResizedWindowMsg(window_size)); {
let ConstellationChan(ref chan) = new_constellation_chan;
chan.send(ResizedWindowMsg(window_size));
}
self.constellation_chan = new_constellation_chan; self.constellation_chan = new_constellation_chan;
} }
@ -397,7 +408,7 @@ impl IOCompositor {
let page_window = Size2D(window_size.width as f32 / world_zoom, let page_window = Size2D(window_size.width as f32 / world_zoom,
window_size.height as f32 / world_zoom); window_size.height as f32 / world_zoom);
layer.resize(id, new_size, page_window, epoch); layer.resize(id, new_size, page_window, epoch);
let move = self.fragment_point.take().map_default(false, |point| layer.move(point, page_window)); let move = self.fragment_point.take().map_or(false, |point| layer.move(point, page_window));
(true, move) (true, move)
} }
@ -551,14 +562,16 @@ impl IOCompositor {
let exit = self.opts.exit_after_load; let exit = self.opts.exit_after_load;
if exit { if exit {
debug!("shutting down the constellation for FinishedWindowEvent"); debug!("shutting down the constellation for FinishedWindowEvent");
self.constellation_chan.send(ExitMsg); let ConstellationChan(ref chan) = self.constellation_chan;
chan.send(ExitMsg);
self.shutting_down = true; self.shutting_down = true;
} }
} }
QuitWindowEvent => { QuitWindowEvent => {
debug!("shutting down the constellation for QuitWindowEvent"); debug!("shutting down the constellation for QuitWindowEvent");
self.constellation_chan.send(ExitMsg); let ConstellationChan(ref chan) = self.constellation_chan;
chan.send(ExitMsg);
self.shutting_down = true; self.shutting_down = true;
} }
} }
@ -569,7 +582,8 @@ impl IOCompositor {
if self.window_size != new_size { if self.window_size != new_size {
debug!("osmain: window resized to {:u}x{:u}", width, height); debug!("osmain: window resized to {:u}x{:u}", width, height);
self.window_size = new_size; self.window_size = new_size;
self.constellation_chan.send(ResizedWindowMsg(new_size)) let ConstellationChan(ref chan) = self.constellation_chan;
chan.send(ResizedWindowMsg(new_size))
} else { } else {
debug!("osmain: dropping window resize since size is still {:u}x{:u}", width, height); debug!("osmain: dropping window resize since size is still {:u}x{:u}", width, height);
} }
@ -584,7 +598,8 @@ impl IOCompositor {
}; };
let msg = LoadUrlMsg(root_pipeline_id, url::parse_url(url_string, None)); let msg = LoadUrlMsg(root_pipeline_id, url::parse_url(url_string, None));
self.constellation_chan.send(msg); let ConstellationChan(ref chan) = self.constellation_chan;
chan.send(msg);
} }
fn on_mouse_window_event_class(&self, mouse_window_event: MouseWindowEvent) { fn on_mouse_window_event_class(&self, mouse_window_event: MouseWindowEvent) {
@ -628,7 +643,7 @@ impl IOCompositor {
let window_size = &self.window_size; let window_size = &self.window_size;
// Determine zoom amount // Determine zoom amount
self.world_zoom = (self.world_zoom * magnification).max(&1.0); self.world_zoom = cmp::max(self.world_zoom * magnification, 1.0);
let world_zoom = self.world_zoom; let world_zoom = self.world_zoom;
self.root_layer.borrow().common.with_mut(|common| common.set_transform(identity().scale(world_zoom, world_zoom, 1f32))); self.root_layer.borrow().common.with_mut(|common| common.set_transform(identity().scale(world_zoom, world_zoom, 1f32)));
@ -652,7 +667,8 @@ impl IOCompositor {
windowing::Forward => constellation_msg::Forward, windowing::Forward => constellation_msg::Forward,
windowing::Back => constellation_msg::Back, windowing::Back => constellation_msg::Back,
}; };
self.constellation_chan.send(NavigateMsg(direction)) let ConstellationChan(ref chan) = self.constellation_chan;
chan.send(NavigateMsg(direction))
} }
/// Get BufferRequests from each layer. /// Get BufferRequests from each layer.
@ -721,7 +737,8 @@ impl IOCompositor {
assert!(res.is_ok()); assert!(res.is_ok());
debug!("shutting down the constellation after generating an output file"); debug!("shutting down the constellation after generating an output file");
self.constellation_chan.send(ExitMsg); let ConstellationChan(ref chan) = self.constellation_chan;
chan.send(ExitMsg);
self.shutting_down = true; self.shutting_down = true;
} }
@ -730,7 +747,8 @@ impl IOCompositor {
let exit = self.opts.exit_after_load; let exit = self.opts.exit_after_load;
if exit { if exit {
debug!("shutting down the constellation for exit_after_load"); debug!("shutting down the constellation for exit_after_load");
self.constellation_chan.send(ExitMsg); let ConstellationChan(ref chan) = self.constellation_chan;
chan.send(ExitMsg);
} }
} }

View file

@ -19,12 +19,11 @@ use layers::texturegl::{Texture, TextureTarget};
#[cfg(target_os="macos")] use layers::texturegl::TextureTargetRectangle; #[cfg(target_os="macos")] use layers::texturegl::TextureTargetRectangle;
use pipeline::CompositionPipeline; use pipeline::CompositionPipeline;
use script::dom::event::{ClickEvent, MouseDownEvent, MouseMoveEvent, MouseUpEvent}; use script::dom::event::{ClickEvent, MouseDownEvent, MouseMoveEvent, MouseUpEvent};
use script::script_task::SendEventMsg; use script::script_task::{ScriptChan, SendEventMsg};
use servo_msg::compositor_msg::{LayerBuffer, LayerBufferSet, Epoch, Tile}; use servo_msg::compositor_msg::{LayerBuffer, LayerBufferSet, Epoch, Tile};
use servo_msg::constellation_msg::PipelineId; use servo_msg::constellation_msg::PipelineId;
//FIXME: switch to std::rc when we upgrade Rust use std::cmp;
use layers::temp_rc::Rc; use std::rc::Rc;
//use std::rc::Rc;
use windowing::{MouseWindowEvent, MouseWindowClickEvent, MouseWindowMouseDownEvent}; use windowing::{MouseWindowEvent, MouseWindowClickEvent, MouseWindowMouseDownEvent};
use windowing::{MouseWindowMouseUpEvent}; use windowing::{MouseWindowMouseUpEvent};
use azure::azure_hl::Color; use azure::azure_hl::Color;
@ -105,6 +104,25 @@ enum ScrollBehavior {
FixedPosition, FixedPosition,
} }
trait Clampable {
fn clamp(&self, mn: &Self, mx: &Self) -> Self;
}
impl Clampable for f32 {
/// Returns the number constrained within the range `mn <= self <= mx`.
/// If any of the numbers are `NAN` then `NAN` is returned.
#[inline]
fn clamp(&self, mn: &f32, mx: &f32) -> f32 {
match () {
_ if self.is_nan() => *self,
_ if !(*self <= *mx) => *mx,
_ if !(*self >= *mn) => *mn,
_ => *self,
}
}
}
impl CompositorLayer { impl CompositorLayer {
/// Creates a new CompositorLayer with an optional page size. If no page size is given, /// Creates a new CompositorLayer with an optional page size. If no page size is given,
/// the layer is initially hidden and initialized without a quadtree. /// the layer is initially hidden and initialized without a quadtree.
@ -207,9 +225,9 @@ impl CompositorLayer {
Some(size) => size, Some(size) => size,
None => fail!("CompositorLayer: tried to scroll with no page size set"), None => fail!("CompositorLayer: tried to scroll with no page size set"),
}; };
let min_x = (window_size.width - page_size.width).min(&0.0); let min_x = cmp::min(window_size.width - page_size.width, 0.0);
self.scroll_offset.x = self.scroll_offset.x.clamp(&min_x, &0.0); self.scroll_offset.x = self.scroll_offset.x.clamp(&min_x, &0.0);
let min_y = (window_size.height - page_size.height).min(&0.0); let min_y = cmp::min(window_size.height - page_size.height, 0.0);
self.scroll_offset.y = self.scroll_offset.y.clamp(&min_y, &0.0); self.scroll_offset.y = self.scroll_offset.y.clamp(&min_y, &0.0);
// check to see if we scrolled // check to see if we scrolled
@ -253,13 +271,15 @@ impl CompositorLayer {
MouseWindowClickEvent(button, _) => ClickEvent(button, cursor), MouseWindowClickEvent(button, _) => ClickEvent(button, cursor),
MouseWindowMouseDownEvent(button, _) => MouseDownEvent(button, cursor), MouseWindowMouseDownEvent(button, _) => MouseDownEvent(button, cursor),
MouseWindowMouseUpEvent(button, _) => MouseUpEvent(button, cursor), MouseWindowMouseUpEvent(button, _) => MouseUpEvent(button, cursor),
}; };
self.pipeline.script_chan.try_send(SendEventMsg(self.pipeline.id.clone(), message)); let ScriptChan(ref chan) = self.pipeline.script_chan;
chan.try_send(SendEventMsg(self.pipeline.id.clone(), message));
} }
pub fn send_mouse_move_event(&self, cursor: Point2D<f32>) { pub fn send_mouse_move_event(&self, cursor: Point2D<f32>) {
let message = MouseMoveEvent(cursor); let message = MouseMoveEvent(cursor);
self.pipeline.script_chan.try_send(SendEventMsg(self.pipeline.id.clone(), message)); let ScriptChan(ref chan) = self.pipeline.script_chan;
chan.try_send(SendEventMsg(self.pipeline.id.clone(), message));
} }
// Given the current window size, determine which tiles need to be (re)rendered // Given the current window size, determine which tiles need to be (re)rendered
@ -410,9 +430,9 @@ impl CompositorLayer {
Some(size) => size, Some(size) => size,
None => fail!("CompositorLayer: tried to scroll with no page size set"), None => fail!("CompositorLayer: tried to scroll with no page size set"),
}; };
let min_x = (window_size.width - page_size.width).min(&0.0); let min_x = cmp::min(window_size.width - page_size.width, 0.0);
self.scroll_offset.x = self.scroll_offset.x.clamp(&min_x, &0.0); self.scroll_offset.x = self.scroll_offset.x.clamp(&min_x, &0.0);
let min_y = (window_size.height - page_size.height).min(&0.0); let min_y = cmp::min(window_size.height - page_size.height, 0.0);
self.scroll_offset.y = self.scroll_offset.y.clamp(&min_y, &0.0); self.scroll_offset.y = self.scroll_offset.y.clamp(&min_y, &0.0);
// check to see if we scrolled // check to see if we scrolled
@ -674,7 +694,7 @@ impl CompositorLayer {
NoTree(..) => {} // Nothing to do NoTree(..) => {} // Nothing to do
Tree(ref mut quadtree) => { Tree(ref mut quadtree) => {
// NOTE: work around borrowchk // NOTE: work around borrowchk
let tmp = child.container.borrow().scissor.borrow(); let tmp = child.get_ref().container.borrow().scissor.borrow();
match *tmp.get() { match *tmp.get() {
Some(rect) => { Some(rect) => {
quadtree.set_status_page(rect, Normal, false); // Unhide this rect quadtree.set_status_page(rect, Normal, false); // Unhide this rect
@ -685,7 +705,7 @@ impl CompositorLayer {
} }
// Send back all tiles to renderer. // Send back all tiles to renderer.
child.child.clear(); child.get_mut_ref().child.clear();
self.build_layer_tree(graphics_context); self.build_layer_tree(graphics_context);
true true

View file

@ -18,8 +18,7 @@ use servo_msg::compositor_msg::{ScriptListener, Tile};
use servo_msg::constellation_msg::{ConstellationChan, PipelineId}; use servo_msg::constellation_msg::{ConstellationChan, PipelineId};
use servo_util::opts::Opts; use servo_util::opts::Opts;
use servo_util::time::ProfilerChan; use servo_util::time::ProfilerChan;
use std::comm::{Chan, SharedChan, Port}; use std::comm::{Chan, Port};
use std::num::Orderable;
use extra::url::Url; use extra::url::Url;
@ -36,7 +35,7 @@ mod headless;
#[deriving(Clone)] #[deriving(Clone)]
pub struct CompositorChan { pub struct CompositorChan {
/// A channel on which messages can be sent to the compositor. /// A channel on which messages can be sent to the compositor.
chan: SharedChan<Msg>, chan: Chan<Msg>,
} }
/// Implementation of the abstract `ScriptListener` interface. /// Implementation of the abstract `ScriptListener` interface.
@ -106,7 +105,7 @@ impl RenderListener for CompositorChan {
impl CompositorChan { impl CompositorChan {
pub fn new() -> (Port<Msg>, CompositorChan) { pub fn new() -> (Port<Msg>, CompositorChan) {
let (port, chan) = SharedChan::new(); let (port, chan) = Chan::new();
let compositor_chan = CompositorChan { let compositor_chan = CompositorChan {
chan: chan, chan: chan,
}; };

View file

@ -6,7 +6,7 @@ use compositing::*;
use geom::size::Size2D; use geom::size::Size2D;
use servo_msg::constellation_msg::{ConstellationChan, ExitMsg, ResizedWindowMsg}; use servo_msg::constellation_msg::{ConstellationChan, ExitMsg, ResizedWindowMsg};
use std::comm::Port; use std::comm::{Empty, Disconnected, Data, Port};
use servo_util::time::ProfilerChan; use servo_util::time::ProfilerChan;
use servo_util::time; use servo_util::time;
@ -32,13 +32,22 @@ impl NullCompositor {
let compositor = NullCompositor::new(port); let compositor = NullCompositor::new(port);
// Tell the constellation about the initial fake size. // Tell the constellation about the initial fake size.
constellation_chan.send(ResizedWindowMsg(Size2D(640u, 480u))); {
let ConstellationChan(ref chan) = constellation_chan;
chan.send(ResizedWindowMsg(Size2D(640u, 480u)));
}
compositor.handle_message(constellation_chan); compositor.handle_message(constellation_chan);
// Drain compositor port, sometimes messages contain channels that are blocking // Drain compositor port, sometimes messages contain channels that are blocking
// another task from finishing (i.e. SetIds) // another task from finishing (i.e. SetIds)
while compositor.port.try_recv().is_some() {} while true {
match compositor.port.try_recv() {
Empty | Disconnected => break,
Data(_) => {},
}
}
let ProfilerChan(ref chan) = profiler_chan;
profiler_chan.send(time::ExitMsg); profiler_chan.send(time::ExitMsg);
} }
@ -47,7 +56,8 @@ impl NullCompositor {
match self.port.recv() { match self.port.recv() {
Exit(chan) => { Exit(chan) => {
debug!("shutting down the constellation"); debug!("shutting down the constellation");
constellation_chan.send(ExitMsg); let ConstellationChan(ref con_chan) = constellation_chan;
con_chan.send(ExitMsg);
chan.send(()); chan.send(());
} }

View file

@ -9,9 +9,10 @@ use geom::point::Point2D;
use geom::size::Size2D; use geom::size::Size2D;
use geom::rect::Rect; use geom::rect::Rect;
use gfx::render_task::BufferRequest; use gfx::render_task::BufferRequest;
use std::uint::{div_ceil, next_power_of_two}; use std::cmp;
use std::num::next_power_of_two;
use std::vec; use std::vec;
use std::util::replace; use std::mem::replace;
use std::vec::build; use std::vec::build;
use servo_msg::compositor_msg::Tile; use servo_msg::compositor_msg::Tile;
@ -72,6 +73,12 @@ enum Quadrant {
BR = 3, BR = 3,
} }
fn div_ceil(x: uint, y: uint) -> uint {
let div = x / y;
if x % y == 0u { div }
else { div + 1u }
}
impl<T: Tile> Quadtree<T> { impl<T: Tile> Quadtree<T> {
/// Public method to create a new Quadtree /// Public method to create a new Quadtree
/// Takes in the initial width and height of the space, a maximum tile size, and /// Takes in the initial width and height of the space, a maximum tile size, and
@ -79,7 +86,7 @@ impl<T: Tile> Quadtree<T> {
/// Set max_mem to None to turn off automatic tile removal. /// Set max_mem to None to turn off automatic tile removal.
pub fn new(clip_size: Size2D<uint>, tile_size: uint, max_mem: Option<uint>) -> Quadtree<T> { pub fn new(clip_size: Size2D<uint>, tile_size: uint, max_mem: Option<uint>) -> Quadtree<T> {
// Spaces must be squares and powers of 2, so expand the space until it is // Spaces must be squares and powers of 2, so expand the space until it is
let longer = clip_size.width.max(&clip_size.height); let longer = cmp::max(clip_size.width, clip_size.height);
let num_tiles = div_ceil(longer, tile_size); let num_tiles = div_ceil(longer, tile_size);
let power_of_two = next_power_of_two(num_tiles); let power_of_two = next_power_of_two(num_tiles);
let size = power_of_two * tile_size; let size = power_of_two * tile_size;
@ -153,7 +160,7 @@ impl<T: Tile> Quadtree<T> {
/// Creates a new quadtree at the specified size. This should be called when the window changes size. /// Creates a new quadtree at the specified size. This should be called when the window changes size.
pub fn resize(&mut self, width: uint, height: uint) -> ~[T] { pub fn resize(&mut self, width: uint, height: uint) -> ~[T] {
// Spaces must be squares and powers of 2, so expand the space until it is // Spaces must be squares and powers of 2, so expand the space until it is
let longer = width.max(&height); let longer = cmp::max(width, height);
let num_tiles = div_ceil(longer, self.max_tile_size); let num_tiles = div_ceil(longer, self.max_tile_size);
let power_of_two = next_power_of_two(num_tiles); let power_of_two = next_power_of_two(num_tiles);
let size = power_of_two * self.max_tile_size; let size = power_of_two * self.max_tile_size;
@ -176,7 +183,7 @@ impl<T: Tile> Quadtree<T> {
#[cfg(test)] #[cfg(test)]
pub fn bad_resize(&mut self, width: uint, height: uint) { pub fn bad_resize(&mut self, width: uint, height: uint) {
self.clip_size = Size2D(width, height); self.clip_size = Size2D(width, height);
let longer = width.max(&height); let longer = cmp::max(width, height);
let new_num_tiles = div_ceil(longer, self.max_tile_size); let new_num_tiles = div_ceil(longer, self.max_tile_size);
let new_size = next_power_of_two(new_num_tiles); let new_size = next_power_of_two(new_num_tiles);
// difference here indicates the number of times the underlying size of the quadtree needs // difference here indicates the number of times the underlying size of the quadtree needs
@ -348,8 +355,8 @@ impl<T: Tile> QuadtreeNode<T> {
if self.size <= tile_size { if self.size <= tile_size {
let pix_x = (self.origin.x * scale).ceil() as uint; let pix_x = (self.origin.x * scale).ceil() as uint;
let pix_y = (self.origin.y * scale).ceil() as uint; let pix_y = (self.origin.y * scale).ceil() as uint;
let page_width = (clip_x - self.origin.x).min(&self.size); let page_width = cmp::min(clip_x - self.origin.x, self.size);
let page_height = (clip_y - self.origin.y).min(&self.size); let page_height = cmp::min(clip_y - self.origin.y, self.size);
let pix_width = (page_width * scale).ceil() as uint; let pix_width = (page_width * scale).ceil() as uint;
let pix_height = (page_height * scale).ceil() as uint; let pix_height = (page_height * scale).ceil() as uint;
self.status = Rendering; self.status = Rendering;
@ -472,8 +479,8 @@ impl<T: Tile> QuadtreeNode<T> {
} }
// clip window to visible region // clip window to visible region
let w_width = (clip.width - w_x).min(&w_width); let w_width = cmp::min(clip.width - w_x, w_width);
let w_height = (clip.height - w_y).min(&w_height); let w_height = cmp::min(clip.height - w_y, w_height);
if s_size <= tile_size { // We are the child if s_size <= tile_size { // We are the child
return match self.tile { return match self.tile {
@ -545,20 +552,20 @@ impl<T: Tile> QuadtreeNode<T> {
// Recurse into child // Recurse into child
let new_window = match *quad { let new_window = match *quad {
TL => Rect(window.origin, TL => Rect(window.origin,
Size2D(w_width.min(&(s_x + s_size / 2.0 - w_x)), Size2D(cmp::min(w_width, s_x + s_size / 2.0 - w_x),
w_height.min(&(s_y + s_size / 2.0 - w_y)))), cmp::min(w_height, (s_y + s_size / 2.0 - w_y)))),
TR => Rect(Point2D(w_x.max(&(s_x + s_size / 2.0)), TR => Rect(Point2D(cmp::max(w_x, s_x + s_size / 2.0),
w_y), w_y),
Size2D(w_width.min(&(w_x + w_width - (s_x + s_size / 2.0))), Size2D(cmp::min(w_width, w_x + w_width - (s_x + s_size / 2.0)),
w_height.min(&(s_y + s_size / 2.0 - w_y)))), cmp::min(w_height, s_y + s_size / 2.0 - w_y))),
BL => Rect(Point2D(w_x, BL => Rect(Point2D(w_x,
w_y.max(&(s_y + s_size / 2.0))), cmp::max(w_y, s_y + s_size / 2.0)),
Size2D(w_width.min(&(s_x + s_size / 2.0 - w_x)), Size2D(cmp::min(w_width, s_x + s_size / 2.0 - w_x),
w_height.min(&(w_y + w_height - (s_y + s_size / 2.0))))), cmp::min(w_height, w_y + w_height - (s_y + s_size / 2.0)))),
BR => Rect(Point2D(w_x.max(&(s_x + s_size / 2.0)), BR => Rect(Point2D(cmp::max(w_x, s_x + s_size / 2.0),
w_y.max(&(s_y + s_size / 2.0))), cmp::max(w_y, s_y + s_size / 2.0)),
Size2D(w_width.min(&(w_x + w_width - (s_x + s_size / 2.0))), Size2D(cmp::min(w_width, w_x + w_width - (s_x + s_size / 2.0)),
w_height.min(&(w_y + w_height - (s_y + s_size / 2.0))))), cmp::min(w_height, w_y + w_height - (s_y + s_size / 2.0)))),
}; };

View file

@ -4,6 +4,7 @@
use compositing::{CompositorChan, LoadComplete, SetIds, SetLayerClipRect, ShutdownComplete}; use compositing::{CompositorChan, LoadComplete, SetIds, SetLayerClipRect, ShutdownComplete};
use collections::hashmap::{HashMap, HashSet};
use extra::url::Url; use extra::url::Url;
use geom::rect::Rect; use geom::rect::Rect;
use geom::size::Size2D; use geom::size::Size2D;
@ -11,6 +12,8 @@ use gfx::render_task;
use pipeline::{Pipeline, CompositionPipeline}; use pipeline::{Pipeline, CompositionPipeline};
use script::script_task::{ResizeMsg, ResizeInactiveMsg, ExitPipelineMsg}; use script::script_task::{ResizeMsg, ResizeInactiveMsg, ExitPipelineMsg};
use script::layout_interface; use script::layout_interface;
use script::layout_interface::LayoutChan;
use script::script_task::ScriptChan;
use servo_msg::constellation_msg::{ConstellationChan, ExitMsg, FailureMsg, Failure, FrameRectMsg}; use servo_msg::constellation_msg::{ConstellationChan, ExitMsg, FailureMsg, Failure, FrameRectMsg};
use servo_msg::constellation_msg::{IFrameSandboxState, IFrameUnsandboxed, InitLoadUrlMsg}; use servo_msg::constellation_msg::{IFrameSandboxState, IFrameUnsandboxed, InitLoadUrlMsg};
use servo_msg::constellation_msg::{LoadCompleteMsg, LoadIframeUrlMsg, LoadUrlMsg, Msg, NavigateMsg}; use servo_msg::constellation_msg::{LoadCompleteMsg, LoadIframeUrlMsg, LoadUrlMsg, Msg, NavigateMsg};
@ -25,13 +28,10 @@ use servo_util::time::ProfilerChan;
use servo_util::url::parse_url; use servo_util::url::parse_url;
use servo_util::task::spawn_named; use servo_util::task::spawn_named;
use std::cell::RefCell; use std::cell::RefCell;
use std::hashmap::{HashMap, HashSet}; use std::mem::replace;
//FIXME: switch to std::rc when we upgrade Rust
use layers::temp_rc::Rc;
//use std::rc::Rc;
use std::util::replace;
use std::io; use std::io;
use std::libc; use std::libc;
use std::rc::Rc;
/// Maintains the pipelines and navigation context and grants permission to composite /// Maintains the pipelines and navigation context and grants permission to composite
pub struct Constellation { pub struct Constellation {
@ -199,12 +199,12 @@ impl Iterator<Rc<FrameTree>> for FrameTreeIterator {
let next = self.stack.pop(); let next = self.stack.pop();
{ {
// NOTE: work around borrowchk issues // NOTE: work around borrowchk issues
let tmp = next.borrow().children.borrow(); let tmp = next.get_ref().borrow().children.borrow();
for cft in tmp.get().rev_iter() { for cft in tmp.get().rev_iter() {
self.stack.push(cft.frame_tree.clone()); self.stack.push(cft.frame_tree.clone());
} }
} }
Some(next) Some(next.unwrap())
} else { } else {
None None
} }
@ -239,14 +239,14 @@ impl NavigationContext {
pub fn back(&mut self) -> Rc<FrameTree> { pub fn back(&mut self) -> Rc<FrameTree> {
self.next.push(self.current.take_unwrap()); self.next.push(self.current.take_unwrap());
let prev = self.previous.pop(); let prev = self.previous.pop().unwrap();
self.current = Some(prev.clone()); self.current = Some(prev.clone());
prev prev
} }
pub fn forward(&mut self) -> Rc<FrameTree> { pub fn forward(&mut self) -> Rc<FrameTree> {
self.previous.push(self.current.take_unwrap()); self.previous.push(self.current.take_unwrap());
let next = self.next.pop(); let next = self.next.pop().unwrap();
self.current = Some(next.clone()); self.current = Some(next.clone());
next next
} }
@ -335,7 +335,8 @@ impl Constellation {
/// Helper function for getting a unique pipeline Id /// Helper function for getting a unique pipeline Id
fn get_next_pipeline_id(&mut self) -> PipelineId { fn get_next_pipeline_id(&mut self) -> PipelineId {
let id = self.next_pipeline_id; let id = self.next_pipeline_id;
*self.next_pipeline_id += 1; let PipelineId(ref mut i) = self.next_pipeline_id;
*i += 1;
id id
} }
@ -437,9 +438,11 @@ impl Constellation {
Some(id) => id.clone() Some(id) => id.clone()
}; };
old_pipeline.borrow().script_chan.try_send(ExitPipelineMsg(pipeline_id)); let ScriptChan(ref old_script) = old_pipeline.borrow().script_chan;
old_pipeline.borrow().render_chan.try_send(render_task::ExitMsg(None)); old_script.try_send(ExitPipelineMsg(pipeline_id));
old_pipeline.borrow().layout_chan.try_send(layout_interface::ExitNowMsg); old_pipeline.borrow().render_chan.chan.try_send(render_task::ExitMsg(None));
let LayoutChan(ref old_layout) = old_pipeline.borrow().layout_chan;
old_layout.try_send(layout_interface::ExitNowMsg);
self.pipelines.remove(&pipeline_id); self.pipelines.remove(&pipeline_id);
let new_id = self.get_next_pipeline_id(); let new_id = self.get_next_pipeline_id();
@ -508,51 +511,57 @@ impl Constellation {
== subpage_id == subpage_id
}; };
// Update a child's frame rect and inform its script task of the change, {
// if it hasn't been already. Optionally inform the compositor if // Update a child's frame rect and inform its script task of the change,
// resize happens immediately. // if it hasn't been already. Optionally inform the compositor if
let update_child_rect = |child_frame_tree: &mut ChildFrameTree, is_active: bool| { // resize happens immediately.
child_frame_tree.rect = Some(rect.clone()); let compositor_chan = self.compositor_chan.clone();
// NOTE: work around borrowchk issues let update_child_rect = |child_frame_tree: &mut ChildFrameTree, is_active: bool| {
let pipeline = &child_frame_tree.frame_tree.borrow().pipeline.borrow(); child_frame_tree.rect = Some(rect.clone());
if !already_sent.contains(&pipeline.get().borrow().id) {
let Size2D { width, height } = rect.size;
if is_active {
let pipeline = pipeline.get().borrow();
pipeline.script_chan.send(ResizeMsg(pipeline.id, Size2D {
width: width as uint,
height: height as uint
}));
self.compositor_chan.send(SetLayerClipRect(pipeline.id, rect));
} else {
let pipeline = pipeline.get().borrow();
pipeline.script_chan.send(ResizeInactiveMsg(pipeline.id,
Size2D(width as uint, height as uint)));
}
let pipeline = pipeline.get().borrow();
already_sent.insert(pipeline.id);
}
};
// If the subframe is in the current frame tree, the compositor needs the new size
for current_frame in self.current_frame().iter() {
debug!("Constellation: Sending size for frame in current frame tree.");
let source_frame = current_frame.borrow().find(pipeline_id);
for source_frame in source_frame.iter() {
// NOTE: work around borrowchk issues // NOTE: work around borrowchk issues
let mut tmp = source_frame.borrow().children.borrow_mut(); let pipeline = &child_frame_tree.frame_tree.borrow().pipeline.borrow();
let found_child = tmp.get().mut_iter().find(|child| subpage_eq(child)); if !already_sent.contains(&pipeline.get().borrow().id) {
found_child.map(|child| update_child_rect(child, true)); let Size2D { width, height } = rect.size;
if is_active {
let pipeline = pipeline.get().borrow();
let ScriptChan(ref chan) = pipeline.script_chan;
chan.send(ResizeMsg(pipeline.id, Size2D {
width: width as uint,
height: height as uint
}));
compositor_chan.send(SetLayerClipRect(pipeline.id, rect));
} else {
let pipeline = pipeline.get().borrow();
let ScriptChan(ref chan) = pipeline.script_chan;
chan.send(ResizeInactiveMsg(pipeline.id,
Size2D(width as uint, height as uint)));
}
let pipeline = pipeline.get().borrow();
already_sent.insert(pipeline.id);
}
};
// If the subframe is in the current frame tree, the compositor needs the new size
for current_frame in self.current_frame().iter() {
debug!("Constellation: Sending size for frame in current frame tree.");
let source_frame = current_frame.borrow().find(pipeline_id);
for source_frame in source_frame.iter() {
// NOTE: work around borrowchk issues
let mut tmp = source_frame.borrow().children.borrow_mut();
let found_child = tmp.get().mut_iter().find(|child| subpage_eq(child));
found_child.map(|child| update_child_rect(child, true));
}
} }
}
// Update all frames with matching pipeline- and subpage-ids // Update all frames with matching pipeline- and subpage-ids
let frames = self.find_all(pipeline_id); let frames = self.find_all(pipeline_id);
for frame_tree in frames.iter() { for frame_tree in frames.iter() {
// NOTE: work around borrowchk issues // NOTE: work around borrowchk issues
let mut tmp = frame_tree.borrow().children.borrow_mut(); let mut tmp = frame_tree.borrow().children.borrow_mut();
let found_child = tmp.get().mut_iter().find(|child| subpage_eq(child)); let found_child = tmp.get().mut_iter().find(|child| subpage_eq(child));
found_child.map(|child| update_child_rect(child, false)); found_child.map(|child| update_child_rect(child, false));
}
} }
// At this point, if no pipelines were sent a resize msg, then this subpage id // At this point, if no pipelines were sent a resize msg, then this subpage id
@ -871,7 +880,8 @@ impl Constellation {
// NOTE: work around borrowchk issues // NOTE: work around borrowchk issues
let tmp = frame_tree.borrow().pipeline.borrow(); let tmp = frame_tree.borrow().pipeline.borrow();
let pipeline = tmp.get().borrow(); let pipeline = tmp.get().borrow();
pipeline.script_chan.try_send(ResizeMsg(pipeline.id, new_size)); let ScriptChan(ref chan) = pipeline.script_chan;
chan.try_send(ResizeMsg(pipeline.id, new_size));
already_seen.insert(pipeline.id); already_seen.insert(pipeline.id);
} }
for frame_tree in self.navigation_context.previous.iter() for frame_tree in self.navigation_context.previous.iter()
@ -881,7 +891,8 @@ impl Constellation {
let pipeline = &tmp.get().borrow(); let pipeline = &tmp.get().borrow();
if !already_seen.contains(&pipeline.id) { if !already_seen.contains(&pipeline.id) {
debug!("constellation sending resize message to inactive frame"); debug!("constellation sending resize message to inactive frame");
pipeline.script_chan.try_send(ResizeInactiveMsg(pipeline.id, new_size)); let ScriptChan(ref chan) = pipeline.script_chan;
chan.try_send(ResizeInactiveMsg(pipeline.id, new_size));
already_seen.insert(pipeline.id); already_seen.insert(pipeline.id);
} }
} }
@ -897,7 +908,8 @@ impl Constellation {
// NOTE: work around borrowchk issues // NOTE: work around borrowchk issues
let tmp = frame_tree.pipeline.borrow(); let tmp = frame_tree.pipeline.borrow();
let pipeline = tmp.get().borrow(); let pipeline = tmp.get().borrow();
pipeline.script_chan.send(ResizeMsg(pipeline.id, new_size)) let ScriptChan(ref chan) = pipeline.script_chan;
chan.send(ResizeMsg(pipeline.id, new_size))
} }
} }

View file

@ -11,16 +11,16 @@ use layout::extra::LayoutAuxMethods;
use layout::util::{LayoutDataAccess, LayoutDataWrapper}; use layout::util::{LayoutDataAccess, LayoutDataWrapper};
use layout::wrapper::{LayoutElement, LayoutNode, PostorderNodeMutTraversal, ThreadSafeLayoutNode}; use layout::wrapper::{LayoutElement, LayoutNode, PostorderNodeMutTraversal, ThreadSafeLayoutNode};
use extra::arc::Arc;
use gfx::font_context::FontContext; use gfx::font_context::FontContext;
use servo_util::cache::{Cache, LRUCache, SimpleHashCache}; use servo_util::cache::{Cache, LRUCache, SimpleHashCache};
use servo_util::namespace::Null; use servo_util::namespace::Null;
use servo_util::smallvec::{SmallVec, SmallVec0, SmallVec16}; use servo_util::smallvec::{SmallVec, SmallVec0, SmallVec16};
use servo_util::str::DOMString; use servo_util::str::DOMString;
use std::cast; use std::cast;
use std::to_bytes; use std::hash::{Hash, sip};
use std::vec::VecIterator; use std::vec::Items;
use style::{After, Before, ComputedValues, MatchedProperty, Stylist, TElement, TNode, cascade}; use style::{After, Before, ComputedValues, MatchedProperty, Stylist, TElement, TNode, cascade};
use sync::Arc;
pub struct ApplicableDeclarations { pub struct ApplicableDeclarations {
normal: SmallVec16<MatchedProperty>, normal: SmallVec16<MatchedProperty>,
@ -73,9 +73,10 @@ impl Eq for ApplicableDeclarationsCacheEntry {
} }
} }
impl IterBytes for ApplicableDeclarationsCacheEntry { impl Hash for ApplicableDeclarationsCacheEntry {
fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { fn hash(&self, state: &mut sip::SipState) {
ApplicableDeclarationsCacheQuery::new(self.declarations.as_slice()).iter_bytes(lsb0, f) let tmp = ApplicableDeclarationsCacheQuery::new(self.declarations.as_slice());
tmp.hash(state);
} }
} }
@ -115,16 +116,15 @@ impl<'a> Equiv<ApplicableDeclarationsCacheEntry> for ApplicableDeclarationsCache
} }
} }
impl<'a> IterBytes for ApplicableDeclarationsCacheQuery<'a> {
fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { impl<'a> Hash for ApplicableDeclarationsCacheQuery<'a> {
let mut result = true; fn hash(&self, state: &mut sip::SipState) {
for declaration in self.declarations.iter() { for declaration in self.declarations.iter() {
let ptr: uint = unsafe { let ptr: uint = unsafe {
cast::transmute_copy(declaration) cast::transmute_copy(declaration)
}; };
result = ptr.iter_bytes(lsb0, |x| f(x)); ptr.hash(state);
} }
result
} }
} }
@ -160,13 +160,13 @@ pub struct StyleSharingCandidateCache {
#[deriving(Clone)] #[deriving(Clone)]
struct StyleSharingCandidate { struct StyleSharingCandidate {
priv style: Arc<ComputedValues>, style: Arc<ComputedValues>,
priv parent_style: Arc<ComputedValues>, parent_style: Arc<ComputedValues>,
// TODO(pcwalton): Intern. // TODO(pcwalton): Intern.
priv local_name: DOMString, local_name: DOMString,
priv class: Option<DOMString>, class: Option<DOMString>,
} }
impl Eq for StyleSharingCandidate { impl Eq for StyleSharingCandidate {
@ -255,7 +255,7 @@ impl StyleSharingCandidateCache {
} }
} }
pub fn iter<'a>(&'a self) -> VecIterator<'a,(StyleSharingCandidate,())> { pub fn iter<'a>(&'a self) -> Items<'a,(StyleSharingCandidate,())> {
self.cache.iter() self.cache.iter()
} }

View file

@ -8,8 +8,8 @@ use css::node_util::NodeUtil;
use layout::incremental::RestyleDamage; use layout::incremental::RestyleDamage;
use layout::wrapper::ThreadSafeLayoutNode; use layout::wrapper::ThreadSafeLayoutNode;
use extra::arc::Arc;
use style::ComputedValues; use style::ComputedValues;
use sync::Arc;
/// Node mixin providing `style` method that returns a `NodeStyle` /// Node mixin providing `style` method that returns a `NodeStyle`
pub trait StyledNode { pub trait StyledNode {

View file

@ -6,9 +6,9 @@ use layout::incremental::RestyleDamage;
use layout::util::LayoutDataAccess; use layout::util::LayoutDataAccess;
use layout::wrapper::{TLayoutNode, ThreadSafeLayoutNode}; use layout::wrapper::{TLayoutNode, ThreadSafeLayoutNode};
use extra::arc::Arc;
use std::cast; use std::cast;
use style::ComputedValues; use style::ComputedValues;
use sync::Arc;
pub trait NodeUtil { pub trait NodeUtil {
fn get_css_select_results<'a>(&'a self) -> &'a Arc<ComputedValues>; fn get_css_select_results<'a>(&'a self) -> &'a Arc<ComputedValues>;

View file

@ -291,7 +291,9 @@ impl<'a> PreorderFlowTraversal for AbsoluteAssignHeightsTraversal<'a> {
return true; return true;
} }
block_flow.calculate_abs_height_and_margins(**self);
let AbsoluteAssignHeightsTraversal(ref ctx) = *self;
block_flow.calculate_abs_height_and_margins(*ctx);
true true
} }
} }

View file

@ -5,8 +5,9 @@
//! The `Box` type, which represents the leaves of the layout tree. //! The `Box` type, which represents the leaves of the layout tree.
use extra::url::Url; use extra::url::Url;
use extra::arc::{MutexArc, Arc}; use sync::{MutexArc, Arc};
use geom::{Point2D, Rect, Size2D, SideOffsets2D}; use geom::{Point2D, Rect, Size2D, SideOffsets2D};
use geom::approxeq::ApproxEq;
use gfx::color::rgb; use gfx::color::rgb;
use gfx::display_list::{BaseDisplayItem, BorderDisplayItem, BorderDisplayItemClass}; use gfx::display_list::{BaseDisplayItem, BorderDisplayItem, BorderDisplayItemClass};
use gfx::display_list::{LineDisplayItem, LineDisplayItemClass}; use gfx::display_list::{LineDisplayItem, LineDisplayItemClass};
@ -16,7 +17,7 @@ use gfx::display_list::{TextDisplayItemClass, TextDisplayItemFlags, ClipDisplayI
use gfx::display_list::{ClipDisplayItemClass, DisplayListCollection}; use gfx::display_list::{ClipDisplayItemClass, DisplayListCollection};
use gfx::font::FontStyle; use gfx::font::FontStyle;
use gfx::text::text_run::TextRun; use gfx::text::text_run::TextRun;
use servo_msg::constellation_msg::{FrameRectMsg, PipelineId, SubpageId}; use servo_msg::constellation_msg::{ConstellationChan, FrameRectMsg, PipelineId, SubpageId};
use servo_net::image::holder::ImageHolder; use servo_net::image::holder::ImageHolder;
use servo_net::local_image_cache::LocalImageCache; use servo_net::local_image_cache::LocalImageCache;
use servo_util::geometry::Au; use servo_util::geometry::Au;
@ -1327,7 +1328,7 @@ impl Box {
UnscannedTextBox(_) => fail!("Unscanned text boxes should have been scanned by now!"), UnscannedTextBox(_) => fail!("Unscanned text boxes should have been scanned by now!"),
ScannedTextBox(ref text_box_info) => { ScannedTextBox(ref text_box_info) => {
let mut new_line_pos = self.new_line_pos.clone(); let mut new_line_pos = self.new_line_pos.clone();
let cur_new_line_pos = new_line_pos.shift(); let cur_new_line_pos = new_line_pos.shift().unwrap();
let left_range = Range::new(text_box_info.range.begin(), cur_new_line_pos); let left_range = Range::new(text_box_info.range.begin(), cur_new_line_pos);
let right_range = Range::new(text_box_info.range.begin() + cur_new_line_pos + 1, text_box_info.range.length() - (cur_new_line_pos + 1)); let right_range = Range::new(text_box_info.range.begin() + cur_new_line_pos + 1, text_box_info.range.length() - (cur_new_line_pos + 1));
@ -1442,7 +1443,7 @@ impl Box {
None None
}; };
let right_box = right_range.map_default(None, |range: Range| { let right_box = right_range.map_or(None, |range: Range| {
let new_text_box_info = ScannedTextBoxInfo::new(text_box_info.run.clone(), range); let new_text_box_info = ScannedTextBoxInfo::new(text_box_info.run.clone(), range);
let mut new_metrics = new_text_box_info.run.get().metrics_for_range(&range); let mut new_metrics = new_text_box_info.run.get().metrics_for_range(&range);
new_metrics.bounding_box.size.height = self.border_box.get().size.height; new_metrics.bounding_box.size.height = self.border_box.get().size.height;
@ -1621,10 +1622,10 @@ impl Box {
} }
format!(" {}{},{},{},{}", format!(" {}{},{},{},{}",
name, name,
*value.top, value.top,
*value.right, value.right,
*value.bottom, value.bottom,
*value.left) value.left)
} }
/// Sends the size and position of this iframe box to the constellation. This is out of line to /// Sends the size and position of this iframe box to the constellation. This is out of line to
@ -1648,6 +1649,7 @@ impl Box {
iframe_box.pipeline_id, iframe_box.pipeline_id,
iframe_box.subpage_id); iframe_box.subpage_id);
let msg = FrameRectMsg(iframe_box.pipeline_id, iframe_box.subpage_id, rect); let msg = FrameRectMsg(iframe_box.pipeline_id, iframe_box.subpage_id, rect);
layout_context.constellation_chan.send(msg) let ConstellationChan(ref chan) = layout_context.constellation_chan;
chan.send(msg)
} }
} }

View file

@ -51,8 +51,8 @@ use servo_util::url::is_image_data;
use servo_util::str::is_whitespace; use servo_util::str::is_whitespace;
use extra::url::Url; use extra::url::Url;
use extra::arc::Arc; use sync::Arc;
use std::util; use std::mem;
use std::num::Zero; use std::num::Zero;
/// The results of flow construction for a DOM node. /// The results of flow construction for a DOM node.
@ -319,7 +319,7 @@ impl<'a> FlowConstructor<'a> {
opt_boxes: &mut Option<~[Box]>, opt_boxes: &mut Option<~[Box]>,
flow: &mut ~Flow, flow: &mut ~Flow,
node: &ThreadSafeLayoutNode) { node: &ThreadSafeLayoutNode) {
let opt_boxes = util::replace(opt_boxes, None); let opt_boxes = mem::replace(opt_boxes, None);
if opt_boxes.len() > 0 { if opt_boxes.len() > 0 {
self.flush_inline_boxes_to_flow(opt_boxes.to_vec(), flow, node) self.flush_inline_boxes_to_flow(opt_boxes.to_vec(), flow, node)
} }
@ -357,7 +357,7 @@ impl<'a> FlowConstructor<'a> {
// {ib} splits. // {ib} splits.
debug!("flushing {} inline box(es) to flow A", debug!("flushing {} inline box(es) to flow A",
opt_boxes_for_inline_flow.as_ref() opt_boxes_for_inline_flow.as_ref()
.map_default(0, |boxes| boxes.len())); .map_or(0, |boxes| boxes.len()));
self.flush_inline_boxes_to_flow_if_necessary(&mut opt_boxes_for_inline_flow, self.flush_inline_boxes_to_flow_if_necessary(&mut opt_boxes_for_inline_flow,
&mut flow, &mut flow,
node); node);
@ -397,8 +397,8 @@ impl<'a> FlowConstructor<'a> {
// Flush any inline boxes that we were gathering up. // Flush any inline boxes that we were gathering up.
debug!("flushing {} inline box(es) to flow A", debug!("flushing {} inline box(es) to flow A",
opt_boxes_for_inline_flow.as_ref() opt_boxes_for_inline_flow.as_ref()
.map_default(0, .map_or(0,
|boxes| boxes.len())); |boxes| boxes.len()));
self.flush_inline_boxes_to_flow_if_necessary( self.flush_inline_boxes_to_flow_if_necessary(
&mut opt_boxes_for_inline_flow, &mut opt_boxes_for_inline_flow,
&mut flow, &mut flow,
@ -486,7 +486,7 @@ impl<'a> FlowConstructor<'a> {
// {ib} split. Flush the accumulator to our new split and make a new // {ib} split. Flush the accumulator to our new split and make a new
// accumulator to hold any subsequent boxes we come across. // accumulator to hold any subsequent boxes we come across.
let split = InlineBlockSplit { let split = InlineBlockSplit {
predecessor_boxes: util::replace(&mut opt_box_accumulator, None).to_vec(), predecessor_boxes: mem::replace(&mut opt_box_accumulator, None).to_vec(),
flow: flow, flow: flow,
}; };
opt_inline_block_splits.push(split); opt_inline_block_splits.push(split);
@ -513,7 +513,7 @@ impl<'a> FlowConstructor<'a> {
opt_box_accumulator.push_all_move(boxes); opt_box_accumulator.push_all_move(boxes);
let split = InlineBlockSplit { let split = InlineBlockSplit {
predecessor_boxes: util::replace(&mut opt_box_accumulator, predecessor_boxes: mem::replace(&mut opt_box_accumulator,
None).to_vec(), None).to_vec(),
flow: kid_flow, flow: kid_flow,
}; };
@ -830,7 +830,7 @@ impl<'ln> NodeUtils for ThreadSafeLayoutNode<'ln> {
let mut layout_data_ref = self.mutate_layout_data(); let mut layout_data_ref = self.mutate_layout_data();
match *layout_data_ref.get() { match *layout_data_ref.get() {
Some(ref mut layout_data) => { Some(ref mut layout_data) => {
util::replace(&mut layout_data.data.flow_construction_result, NoConstructionResult) mem::replace(&mut layout_data.data.flow_construction_result, NoConstructionResult)
} }
None => fail!("no layout data"), None => fail!("no layout data"),
} }
@ -872,7 +872,7 @@ impl<'ln> ObjectElement for ThreadSafeLayoutNode<'ln> {
/// Strips ignorable whitespace from the start of a list of boxes. /// Strips ignorable whitespace from the start of a list of boxes.
fn strip_ignorable_whitespace_from_start(opt_boxes: &mut Option<~[Box]>) { fn strip_ignorable_whitespace_from_start(opt_boxes: &mut Option<~[Box]>) {
match util::replace(opt_boxes, None) { match mem::replace(opt_boxes, None) {
None => return, None => return,
Some(boxes) => { Some(boxes) => {
// FIXME(pcwalton): This is slow because vector shift is broken. :( // FIXME(pcwalton): This is slow because vector shift is broken. :(
@ -907,9 +907,9 @@ fn strip_ignorable_whitespace_from_end(opt_boxes: &mut Option<~[Box]>) {
match *opt_boxes { match *opt_boxes {
None => {} None => {}
Some(ref mut boxes) => { Some(ref mut boxes) => {
while boxes.len() > 0 && boxes.last().is_whitespace_only() { while boxes.len() > 0 && boxes.last().get_ref().is_whitespace_only() {
debug!("stripping ignorable whitespace from end"); debug!("stripping ignorable whitespace from end");
let box_ = boxes.pop(); let box_ = boxes.pop().unwrap();
if boxes.len() > 0 { if boxes.len() > 0 {
boxes[boxes.len() - 1].merge_noncontent_inline_right(&box_); boxes[boxes.len() - 1].merge_noncontent_inline_right(&box_);
} }

View file

@ -7,7 +7,6 @@
use css::matching::{ApplicableDeclarationsCache, StyleSharingCandidateCache}; use css::matching::{ApplicableDeclarationsCache, StyleSharingCandidateCache};
use layout::util::OpaqueNode; use layout::util::OpaqueNode;
use extra::arc::{Arc, MutexArc};
use extra::url::Url; use extra::url::Url;
use geom::size::Size2D; use geom::size::Size2D;
use gfx::font_context::{FontContext, FontContextInfo}; use gfx::font_context::{FontContext, FontContextInfo};
@ -23,6 +22,7 @@ use std::rt::Runtime;
use std::rt::local::Local; use std::rt::local::Local;
use std::rt::task::Task; use std::rt::task::Task;
use style::{ComputedValues, Stylist}; use style::{ComputedValues, Stylist};
use sync::{Arc, MutexArc};
#[thread_local] #[thread_local]
static mut FONT_CONTEXT: *mut FontContext = 0 as *mut FontContext; static mut FONT_CONTEXT: *mut FontContext = 0 as *mut FontContext;

View file

@ -147,7 +147,7 @@ impl Floats {
match self.list.get() { match self.list.get() {
None => None, None => None,
Some(list) => { Some(list) => {
match list.floats.last_opt() { match list.floats.last() {
None => None, None => None,
Some(float) => Some(float.bounds.origin + self.offset), Some(float) => Some(float.bounds.origin + self.offset),
} }
@ -299,11 +299,11 @@ impl Floats {
match info.kind { match info.kind {
FloatLeft => { FloatLeft => {
return Rect(Point2D(Au(0), info.ceiling), return Rect(Point2D(Au(0), info.ceiling),
Size2D(info.max_width, Au(i32::max_value))) Size2D(info.max_width, Au(i32::MAX)))
} }
FloatRight => { FloatRight => {
return Rect(Point2D(info.max_width - info.size.width, info.ceiling), return Rect(Point2D(info.max_width - info.size.width, info.ceiling),
Size2D(info.max_width, Au(i32::max_value))) Size2D(info.max_width, Au(i32::MAX)))
} }
} }
} }
@ -320,11 +320,11 @@ impl Floats {
return match info.kind { return match info.kind {
FloatLeft => { FloatLeft => {
Rect(Point2D(Au(0), float_y), Rect(Point2D(Au(0), float_y),
Size2D(info.max_width, Au(i32::max_value))) Size2D(info.max_width, Au(i32::MAX)))
} }
FloatRight => { FloatRight => {
Rect(Point2D(info.max_width - info.size.width, float_y), Rect(Point2D(info.max_width - info.size.width, float_y),
Size2D(info.max_width, Au(i32::max_value))) Size2D(info.max_width, Au(i32::MAX)))
} }
} }
} }
@ -337,7 +337,7 @@ impl Floats {
let height = self.max_height_for_bounds(rect.origin.x, let height = self.max_height_for_bounds(rect.origin.x,
rect.origin.y, rect.origin.y,
rect.size.width); rect.size.width);
let height = height.unwrap_or(Au(i32::max_value)); let height = height.unwrap_or(Au(i32::MAX));
return match info.kind { return match info.kind {
FloatLeft => { FloatLeft => {
Rect(Point2D(rect.origin.x, float_y), Rect(Point2D(rect.origin.x, float_y),

View file

@ -39,7 +39,7 @@ use layout::parallel;
use layout::wrapper::ThreadSafeLayoutNode; use layout::wrapper::ThreadSafeLayoutNode;
use layout::flow_list::{FlowList, Link, Rawlink, FlowListIterator, MutFlowListIterator}; use layout::flow_list::{FlowList, Link, Rawlink, FlowListIterator, MutFlowListIterator};
use extra::container::Deque; use collections::Deque;
use geom::point::Point2D; use geom::point::Point2D;
use geom::Size2D; use geom::Size2D;
use geom::rect::Rect; use geom::rect::Rect;
@ -51,7 +51,7 @@ use servo_util::geometry::Au;
use std::cast; use std::cast;
use std::cell::RefCell; use std::cell::RefCell;
use std::sync::atomics::Relaxed; use std::sync::atomics::Relaxed;
use std::vec::VecMutIterator; use std::vec::MutItems;
use std::iter::Zip; use std::iter::Zip;
use style::ComputedValues; use style::ComputedValues;
use style::computed_values::{text_align, position}; use style::computed_values::{text_align, position};
@ -531,27 +531,34 @@ bitfield!(FlowFlags, override_line_through, set_override_line_through, 0b0000_10
impl FlowFlags { impl FlowFlags {
#[inline] #[inline]
pub fn text_align(self) -> text_align::T { pub fn text_align(self) -> text_align::T {
FromPrimitive::from_u8((*self & TEXT_ALIGN_BITMASK) >> TEXT_ALIGN_SHIFT).unwrap() let FlowFlags(ff) = self;
FromPrimitive::from_u8((ff & TEXT_ALIGN_BITMASK) >> TEXT_ALIGN_SHIFT).unwrap()
} }
#[inline] #[inline]
pub fn set_text_align(&mut self, value: text_align::T) { pub fn set_text_align(&mut self, value: text_align::T) {
*self = FlowFlags((**self & !TEXT_ALIGN_BITMASK) | ((value as u8) << TEXT_ALIGN_SHIFT)) let FlowFlags(ff) = *self;
*self = FlowFlags((ff & !TEXT_ALIGN_BITMASK) | ((value as u8) << TEXT_ALIGN_SHIFT))
} }
#[inline] #[inline]
pub fn set_text_align_override(&mut self, parent: FlowFlags) { pub fn set_text_align_override(&mut self, parent: FlowFlags) {
*self = FlowFlags(**self | (*parent & TEXT_ALIGN_BITMASK)) let FlowFlags(ff) = *self;
let FlowFlags(pff) = parent;
*self = FlowFlags(ff | (pff & TEXT_ALIGN_BITMASK))
} }
#[inline] #[inline]
pub fn set_text_decoration_override(&mut self, parent: FlowFlags) { pub fn set_text_decoration_override(&mut self, parent: FlowFlags) {
*self = FlowFlags(**self | (*parent & TEXT_DECORATION_OVERRIDE_BITMASK)); let FlowFlags(ff) = *self;
let FlowFlags(pff) = parent;
*self = FlowFlags(ff | (pff & TEXT_DECORATION_OVERRIDE_BITMASK));
} }
#[inline] #[inline]
pub fn is_text_decoration_enabled(&self) -> bool { pub fn is_text_decoration_enabled(&self) -> bool {
(**self & TEXT_DECORATION_OVERRIDE_BITMASK) != 0 let FlowFlags(ref ff) = *self;
(*ff & TEXT_DECORATION_OVERRIDE_BITMASK) != 0
} }
} }
@ -606,9 +613,9 @@ impl Descendants {
pub type AbsDescendants = Descendants; pub type AbsDescendants = Descendants;
pub type FixedDescendants = Descendants; pub type FixedDescendants = Descendants;
type DescendantIter<'a> = VecMutIterator<'a, Rawlink>; type DescendantIter<'a> = MutItems<'a, Rawlink>;
type DescendantOffsetIter<'a> = Zip<VecMutIterator<'a, Rawlink>, VecMutIterator<'a, Au>>; type DescendantOffsetIter<'a> = Zip<MutItems<'a, Rawlink>, MutItems<'a, Au>>;
/// Data common to all flows. /// Data common to all flows.
pub struct BaseFlow { pub struct BaseFlow {
@ -1020,7 +1027,7 @@ impl<'a> MutableFlowUtils for &'a mut Flow {
let result = lists.lists[index].list.mut_rev_iter().position(|item| { let result = lists.lists[index].list.mut_rev_iter().position(|item| {
match *item { match *item {
ClipDisplayItemClass(ref mut item) => { ClipDisplayItemClass(ref mut item) => {
item.child_list.push_all_move(child_lists.lists.shift().list); item.child_list.push_all_move(child_lists.lists.shift().unwrap().list);
true true
}, },
_ => false, _ => false,

View file

@ -6,8 +6,8 @@
//! indirection. //! indirection.
use std::cast; use std::cast;
use std::mem;
use std::ptr; use std::ptr;
use std::util;
use layout::flow::{Flow, base, mut_base}; use layout::flow::{Flow, base, mut_base};
@ -30,7 +30,6 @@ pub struct FlowList {
} }
/// Double-ended FlowList iterator /// Double-ended FlowList iterator
#[deriving(Clone)]
pub struct FlowListIterator<'a> { pub struct FlowListIterator<'a> {
priv head: &'a Link, priv head: &'a Link,
priv tail: Rawlink, priv tail: Rawlink,
@ -156,7 +155,7 @@ impl FlowList {
Some(ref mut head) => { Some(ref mut head) => {
mut_base(new_head).prev_sibling = Rawlink::none(); mut_base(new_head).prev_sibling = Rawlink::none();
mut_base(*head).prev_sibling = Rawlink::some(new_head); mut_base(*head).prev_sibling = Rawlink::some(new_head);
util::swap(head, &mut new_head); mem::swap(head, &mut new_head);
mut_base(*head).next_sibling = Some(new_head); mut_base(*head).next_sibling = Some(new_head);
} }
} }

View file

@ -13,15 +13,14 @@ use layout::flow;
use layout::util::ElementMapping; use layout::util::ElementMapping;
use layout::wrapper::ThreadSafeLayoutNode; use layout::wrapper::ThreadSafeLayoutNode;
use extra::container::Deque; use collections::{Deque, RingBuf};
use extra::ringbuf::RingBuf;
use geom::{Point2D, Rect, Size2D}; use geom::{Point2D, Rect, Size2D};
use gfx::display_list::DisplayListCollection; use gfx::display_list::DisplayListCollection;
use servo_util::geometry::Au; use servo_util::geometry::Au;
use servo_util::range::Range; use servo_util::range::Range;
use std::cell::RefCell; use std::cell::RefCell;
use std::mem;
use std::u16; use std::u16;
use std::util;
use style::computed_values::{text_align, vertical_align, white_space}; use style::computed_values::{text_align, vertical_align, white_space};
/// Lineboxes are represented as offsets into the child list, rather than /// Lineboxes are represented as offsets into the child list, rather than
@ -107,7 +106,7 @@ impl LineboxScanner {
if flow.boxes.is_empty() { if flow.boxes.is_empty() {
break; break;
} }
let box_ = flow.boxes.remove(0); // FIXME: use a linkedlist let box_ = flow.boxes.remove(0).unwrap(); // FIXME: use a linkedlist
debug!("LineboxScanner: Working with box from box list: b{}", box_.debug_id()); debug!("LineboxScanner: Working with box from box list: b{}", box_.debug_id());
box_ box_
} else { } else {
@ -145,8 +144,8 @@ impl LineboxScanner {
debug!("LineboxScanner: Propagating scanned lines[n={:u}] to inline flow", debug!("LineboxScanner: Propagating scanned lines[n={:u}] to inline flow",
self.lines.len()); self.lines.len());
util::swap(&mut flow.boxes, &mut self.new_boxes); mem::swap(&mut flow.boxes, &mut self.new_boxes);
util::swap(&mut flow.lines, &mut self.lines); mem::swap(&mut flow.lines, &mut self.lines);
} }
fn flush_current_line(&mut self) { fn flush_current_line(&mut self) {
@ -433,7 +432,7 @@ impl LineboxScanner {
debug!("LineboxScanner: Pushing box {} to line {:u}", box_.debug_id(), self.lines.len()); debug!("LineboxScanner: Pushing box {} to line {:u}", box_.debug_id(), self.lines.len());
if self.pending_line.range.length() == 0 { if self.pending_line.range.length() == 0 {
assert!(self.new_boxes.len() <= (u16::max_value as uint)); assert!(self.new_boxes.len() <= (u16::MAX as uint));
self.pending_line.range.reset(self.new_boxes.len(), 0); self.pending_line.range.reset(self.new_boxes.len(), 0);
} }
self.pending_line.range.extend_by(1); self.pending_line.range.extend_by(1);
@ -872,7 +871,7 @@ impl Flow for InlineFlow {
self.base.position.size.height = self.base.position.size.height =
if self.lines.len() > 0 { if self.lines.len() > 0 {
self.lines.last().bounds.origin.y + self.lines.last().bounds.size.height self.lines.last().get_ref().bounds.origin.y + self.lines.last().get_ref().bounds.size.height
} else { } else {
Au::new(0) Au::new(0)
}; };

View file

@ -22,7 +22,6 @@ use layout::util::{LayoutDataAccess, OpaqueNode, LayoutDataWrapper};
use layout::wrapper::{LayoutNode, TLayoutNode, ThreadSafeLayoutNode}; use layout::wrapper::{LayoutNode, TLayoutNode, ThreadSafeLayoutNode};
use extra::url::Url; use extra::url::Url;
use extra::arc::{Arc, MutexArc};
use geom::point::Point2D; use geom::point::Point2D;
use geom::rect::Rect; use geom::rect::Rect;
use geom::size::Size2D; use geom::size::Size2D;
@ -55,11 +54,12 @@ use std::cast::transmute;
use std::cast; use std::cast;
use std::cell::RefCell; use std::cell::RefCell;
use std::comm::Port; use std::comm::Port;
use std::mem;
use std::ptr; use std::ptr;
use std::task; use std::task;
use std::util;
use style::{AuthorOrigin, ComputedValues, Stylesheet, Stylist}; use style::{AuthorOrigin, ComputedValues, Stylesheet, Stylist};
use style; use style;
use sync::{Arc, MutexArc};
/// Information needed by the layout task. /// Information needed by the layout task.
pub struct LayoutTask { pub struct LayoutTask {
@ -236,7 +236,8 @@ impl ImageResponder for LayoutImageResponder {
let id = self.id.clone(); let id = self.id.clone();
let script_chan = self.script_chan.clone(); let script_chan = self.script_chan.clone();
let f: proc(ImageResponseMsg) = proc(_) { let f: proc(ImageResponseMsg) = proc(_) {
drop(script_chan.try_send(SendEventMsg(id.clone(), ReflowEvent))) let ScriptChan(chan) = script_chan;
drop(chan.try_send(SendEventMsg(id.clone(), ReflowEvent)))
}; };
f f
} }
@ -255,9 +256,9 @@ impl LayoutTask {
opts: Opts, opts: Opts,
profiler_chan: ProfilerChan, profiler_chan: ProfilerChan,
shutdown_chan: Chan<()>) { shutdown_chan: Chan<()>) {
let mut builder = task::task(); let mut builder = task::task().named("LayoutTask");
send_on_failure(&mut builder, FailureMsg(failure_msg), (*constellation_chan).clone()); let ConstellationChan(con_chan) = constellation_chan.clone();
builder.name("LayoutTask"); send_on_failure(&mut builder, FailureMsg(failure_msg), con_chan);
builder.spawn(proc() { builder.spawn(proc() {
{ // Ensures layout task is destroyed before we send shutdown message { // Ensures layout task is destroyed before we send shutdown message
let mut layout = LayoutTask::new(id, let mut layout = LayoutTask::new(id,
@ -426,7 +427,7 @@ impl LayoutTask {
let mut layout_data_ref = node.mutate_layout_data(); let mut layout_data_ref = node.mutate_layout_data();
let result = match *layout_data_ref.get() { let result = match *layout_data_ref.get() {
Some(ref mut layout_data) => { Some(ref mut layout_data) => {
util::replace(&mut layout_data.data.flow_construction_result, NoConstructionResult) mem::replace(&mut layout_data.data.flow_construction_result, NoConstructionResult)
} }
None => fail!("no layout data for root node"), None => fail!("no layout data for root node"),
}; };
@ -539,11 +540,9 @@ impl LayoutTask {
debug!("{:?}", node.dump()); debug!("{:?}", node.dump());
// Reset the image cache. // Reset the image cache.
unsafe { self.local_image_cache.access(|local_image_cache| {
self.local_image_cache.unsafe_access(|local_image_cache| { local_image_cache.next_round(self.make_on_image_available_cb())
local_image_cache.next_round(self.make_on_image_available_cb()) });
});
}
// true => Do the reflow with full style damage, because content // true => Do the reflow with full style damage, because content
// changed or the window was resized. // changed or the window was resized.
@ -691,7 +690,8 @@ impl LayoutTask {
// FIXME(pcwalton): This should probably be *one* channel, but we can't fix this without // FIXME(pcwalton): This should probably be *one* channel, but we can't fix this without
// either select or a filtered recv() that only looks for messages of a given type. // either select or a filtered recv() that only looks for messages of a given type.
data.script_join_chan.send(()); data.script_join_chan.send(());
data.script_chan.send(ReflowCompleteMsg(self.id, data.id)); let ScriptChan(ref chan) = data.script_chan;
chan.send(ReflowCompleteMsg(self.id, data.id));
} }
/// Handles a query from the script task. This is the main routine that DOM functions like /// Handles a query from the script task. This is the main routine that DOM functions like
@ -857,6 +857,6 @@ impl LayoutTask {
unsafe fn handle_reap_layout_data(&self, layout_data: LayoutDataRef) { unsafe fn handle_reap_layout_data(&self, layout_data: LayoutDataRef) {
let mut layout_data_ref = layout_data.borrow_mut(); let mut layout_data_ref = layout_data.borrow_mut();
let _: Option<LayoutDataWrapper> = cast::transmute( let _: Option<LayoutDataWrapper> = cast::transmute(
util::replace(layout_data_ref.get(), None)); mem::replace(layout_data_ref.get(), None));
} }
} }

View file

@ -29,7 +29,7 @@ use style::{Stylist, TNode};
#[allow(dead_code)] #[allow(dead_code)]
fn static_assertion(node: UnsafeLayoutNode) { fn static_assertion(node: UnsafeLayoutNode) {
unsafe { unsafe {
let _: PaddedUnsafeFlow = ::std::unstable::intrinsics::transmute(node); let _: PaddedUnsafeFlow = ::std::intrinsics::transmute(node);
} }
} }
@ -235,7 +235,7 @@ fn recalc_style_for_node(unsafe_layout_node: UnsafeLayoutNode,
let layout_context: &mut LayoutContext = cast::transmute(*proxy.user_data()); let layout_context: &mut LayoutContext = cast::transmute(*proxy.user_data());
// Get a real layout node. // Get a real layout node.
let node: LayoutNode = ::std::unstable::intrinsics::transmute(unsafe_layout_node); let node: LayoutNode = ::std::intrinsics::transmute(unsafe_layout_node);
// Initialize layout data. // Initialize layout data.
// //

View file

@ -7,13 +7,13 @@
use layout::box_::{Box, ScannedTextBox, ScannedTextBoxInfo, UnscannedTextBox}; use layout::box_::{Box, ScannedTextBox, ScannedTextBoxInfo, UnscannedTextBox};
use layout::flow::Flow; use layout::flow::Flow;
use extra::arc::Arc;
use gfx::font_context::FontContext; use gfx::font_context::FontContext;
use gfx::text::text_run::TextRun; use gfx::text::text_run::TextRun;
use gfx::text::util::{CompressWhitespaceNewline, transform_text, CompressNone}; use gfx::text::util::{CompressWhitespaceNewline, transform_text, CompressNone};
use servo_util::range::Range; use servo_util::range::Range;
use std::vec; use std::vec;
use style::computed_values::white_space; use style::computed_values::white_space;
use sync::Arc;
/// A stack-allocated object for scanning an inline flow into `TextRun`-containing `TextBox`es. /// A stack-allocated object for scanning an inline flow into `TextRun`-containing `TextBox`es.
pub struct TextRunScanner { pub struct TextRunScanner {

View file

@ -7,7 +7,6 @@ use layout::construct::{ConstructionResult, NoConstructionResult};
use layout::parallel::DomParallelInfo; use layout::parallel::DomParallelInfo;
use layout::wrapper::{LayoutNode, TLayoutNode, ThreadSafeLayoutNode}; use layout::wrapper::{LayoutNode, TLayoutNode, ThreadSafeLayoutNode};
use extra::arc::Arc;
use script::dom::bindings::js::JS; use script::dom::bindings::js::JS;
use script::dom::bindings::utils::Reflectable; use script::dom::bindings::utils::Reflectable;
use script::dom::node::Node; use script::dom::node::Node;
@ -17,8 +16,9 @@ use std::cast;
use std::cell::{Ref, RefMut}; use std::cell::{Ref, RefMut};
use std::iter::Enumerate; use std::iter::Enumerate;
use std::libc::uintptr_t; use std::libc::uintptr_t;
use std::vec::VecIterator; use std::vec::Items;
use style::ComputedValues; use style::ComputedValues;
use sync::Arc;
/// A range of nodes. /// A range of nodes.
pub struct NodeRange { pub struct NodeRange {
@ -59,7 +59,7 @@ impl ElementMapping {
true true
} }
pub fn eachi<'a>(&'a self) -> Enumerate<VecIterator<'a, NodeRange>> { pub fn eachi<'a>(&'a self) -> Enumerate<Items<'a, NodeRange>> {
self.entries.iter().enumerate() self.entries.iter().enumerate()
} }
@ -113,8 +113,8 @@ impl ElementMapping {
old_i += 1; old_i += 1;
// possibly pop several items // possibly pop several items
while repair_stack.len() > 0 && old_i == entries[repair_stack.last().entry_idx].range.end() { while repair_stack.len() > 0 && old_i == entries[repair_stack.last().get_ref().entry_idx].range.end() {
let item = repair_stack.pop(); let item = repair_stack.pop().unwrap();
debug!("repair_for_box_changes: Set range for {:u} to {}", debug!("repair_for_box_changes: Set range for {:u} to {}",
item.entry_idx, Range::new(item.begin_idx, new_j - item.begin_idx)); item.entry_idx, Range::new(item.begin_idx, new_j - item.begin_idx));
entries[item.entry_idx].range = Range::new(item.begin_idx, new_j - item.begin_idx); entries[item.entry_idx].range = Range::new(item.begin_idx, new_j - item.begin_idx);

View file

@ -139,7 +139,6 @@ pub trait TLayoutNode {
/// A wrapper so that layout can access only the methods that it should have access to. Layout must /// A wrapper so that layout can access only the methods that it should have access to. Layout must
/// only ever see these and must never see instances of `JS`. /// only ever see these and must never see instances of `JS`.
#[deriving(Clone, Eq)]
pub struct LayoutNode<'a> { pub struct LayoutNode<'a> {
/// The wrapped node. /// The wrapped node.
priv node: JS<Node>, priv node: JS<Node>,
@ -148,6 +147,24 @@ pub struct LayoutNode<'a> {
priv chain: &'a (), priv chain: &'a (),
} }
impl<'ln> Clone for LayoutNode<'ln> {
fn clone(&self) -> LayoutNode<'ln> {
LayoutNode {
node: self.node.clone(),
chain: self.chain,
}
}
}
impl<'a> Eq for LayoutNode<'a> {
#[inline]
fn eq(&self, other: &LayoutNode) -> bool {
self.node == other.node &&
self.chain == other.chain
}
}
impl<'ln> TLayoutNode for LayoutNode<'ln> { impl<'ln> TLayoutNode for LayoutNode<'ln> {
unsafe fn new_with_this_lifetime(&self, node: &JS<Node>) -> LayoutNode<'ln> { unsafe fn new_with_this_lifetime(&self, node: &JS<Node>) -> LayoutNode<'ln> {
LayoutNode { LayoutNode {
@ -244,7 +261,7 @@ impl<'ln> TNode<LayoutElement<'ln>> for LayoutNode<'ln> {
match attr.namespace { match attr.namespace {
SpecificNamespace(ref ns) => { SpecificNamespace(ref ns) => {
element.get_attr(ns, name) element.get_attr(ns, name)
.map_default(false, |attr| test(attr)) .map_or(false, |attr| test(attr))
}, },
// FIXME: https://github.com/mozilla/servo/issues/1558 // FIXME: https://github.com/mozilla/servo/issues/1558
AnyNamespace => false, AnyNamespace => false,

View file

@ -12,12 +12,14 @@ macro_rules! bitfield(
impl $bitfieldname { impl $bitfieldname {
#[inline] #[inline]
pub fn $getter(self) -> bool { pub fn $getter(self) -> bool {
(*self & $value) != 0 let $bitfieldname(this) = self;
(this & $value) != 0
} }
#[inline] #[inline]
pub fn $setter(&mut self, value: bool) { pub fn $setter(&mut self, value: bool) {
*self = $bitfieldname((**self & !$value) | (if value { $value } else { 0 })) let $bitfieldname(this) = *self;
*self = $bitfieldname((this & !$value) | (if value { $value } else { 0 }))
} }
} }
) )

View file

@ -20,9 +20,7 @@ use servo_net::resource_task::ResourceTask;
use servo_util::opts::Opts; use servo_util::opts::Opts;
use servo_util::time::ProfilerChan; use servo_util::time::ProfilerChan;
use std::cell::RefCell; use std::cell::RefCell;
//FIXME: switch to std::rc when we upgrade Rust use std::rc::Rc;
use layers::temp_rc::Rc;
//use std::rc::Rc;
/// A uniquely-identifiable pipeline of script task, layout task, and render task. /// A uniquely-identifiable pipeline of script task, layout task, and render task.
pub struct Pipeline { pub struct Pipeline {
@ -94,7 +92,8 @@ impl Pipeline {
layout_chan: layout_chan.clone(), layout_chan: layout_chan.clone(),
}; };
script_pipeline.borrow().script_chan.send(AttachLayoutMsg(new_layout_info)); let ScriptChan(ref chan) = script_pipeline.borrow().script_chan;
chan.send(AttachLayoutMsg(new_layout_info));
Pipeline::new(id, Pipeline::new(id,
subpage_id, subpage_id,
@ -190,16 +189,17 @@ impl Pipeline {
pub fn load(&self, url: Url) { pub fn load(&self, url: Url) {
self.url.set(Some(url.clone())); self.url.set(Some(url.clone()));
self.script_chan.send(LoadMsg(self.id, url)); let ScriptChan(ref chan) = self.script_chan;
chan.send(LoadMsg(self.id, url));
} }
pub fn grant_paint_permission(&self) { pub fn grant_paint_permission(&self) {
self.render_chan.try_send(PaintPermissionGranted); self.render_chan.chan.try_send(PaintPermissionGranted);
} }
pub fn revoke_paint_permission(&self) { pub fn revoke_paint_permission(&self) {
debug!("pipeline revoking render channel paint permission"); debug!("pipeline revoking render channel paint permission");
self.render_chan.try_send(PaintPermissionRevoked); self.render_chan.chan.try_send(PaintPermissionRevoked);
} }
pub fn reload(&self) { pub fn reload(&self) {
@ -211,7 +211,8 @@ impl Pipeline {
pub fn exit(&self) { pub fn exit(&self) {
// Script task handles shutting down layout, and layout handles shutting down the renderer. // Script task handles shutting down layout, and layout handles shutting down the renderer.
// For now, if the script task has failed, we give up on clean shutdown. // For now, if the script task has failed, we give up on clean shutdown.
if self.script_chan.try_send(script_task::ExitPipelineMsg(self.id)) { let ScriptChan(ref chan) = self.script_chan;
if chan.try_send(script_task::ExitPipelineMsg(self.id)) {
// Wait until all slave tasks have terminated and run destructors // Wait until all slave tasks have terminated and run destructors
// NOTE: We don't wait for script task as we don't always own it // NOTE: We don't wait for script task as we don't always own it
self.render_shutdown_port.recv_opt(); self.render_shutdown_port.recv_opt();

View file

@ -12,11 +12,10 @@ use windowing::RefreshWindowEvent;
use windowing::{Forward, Back}; use windowing::{Forward, Back};
use alert::{Alert, AlertMethods}; use alert::{Alert, AlertMethods};
use extra::time::Timespec; use time;
use extra::time; use time::Timespec;
use std::cell::{Cell, RefCell}; use std::cell::{Cell, RefCell};
use std::libc::{exit, c_int}; use std::libc::{exit, c_int};
use std::local_data;
use std::rc::Rc; use std::rc::Rc;
use geom::point::Point2D; use geom::point::Point2D;
@ -46,13 +45,6 @@ impl ApplicationMethods for Application {
} }
} }
impl Drop for Application {
fn drop(&mut self) {
drop_local_window();
glfw::terminate();
}
}
macro_rules! glfw_callback( macro_rules! glfw_callback(
( (
$callback:path ($($arg:ident: $arg_ty:ty),*) $block:expr $callback:path ($($arg:ident: $arg_ty:ty),*) $block:expr
@ -128,64 +120,14 @@ impl WindowMethods<Application> for Window {
}; };
// Register event handlers. // Register event handlers.
window.glfw_window.set_framebuffer_size_callback( window.glfw_window.set_framebuffer_size_polling(true);
glfw_callback!(glfw::FramebufferSizeCallback(_win: &glfw::Window, width: i32, height: i32) { window.glfw_window.set_refresh_polling(true);
let tmp = local_window(); window.glfw_window.set_key_polling(true);
tmp.borrow().event_queue.with_mut(|queue| queue.push(ResizeWindowEvent(width as uint, height as uint))); window.glfw_window.set_mouse_button_polling(true);
})); window.glfw_window.set_cursor_pos_polling(true);
window.glfw_window.set_refresh_callback( window.glfw_window.set_scroll_polling(true);
glfw_callback!(glfw::WindowRefreshCallback(_win: &glfw::Window) {
let tmp = local_window();
tmp.borrow().event_queue.with_mut(|queue| queue.push(RefreshWindowEvent));
}));
window.glfw_window.set_key_callback(
glfw_callback!(glfw::KeyCallback(_win: &glfw::Window, key: glfw::Key, _scancode: c_int,
action: glfw::Action, mods: glfw::Modifiers) {
if action == glfw::Press {
let tmp = local_window();
tmp.borrow().handle_key(key, mods)
}
}));
window.glfw_window.set_mouse_button_callback(
glfw_callback!(glfw::MouseButtonCallback(win: &glfw::Window, button: glfw::MouseButton,
action: glfw::Action, _mods: glfw::Modifiers) {
let (x, y) = win.get_cursor_pos();
//handle hidpi displays, since GLFW returns non-hi-def coordinates.
let (backing_size, _) = win.get_framebuffer_size();
let (window_size, _) = win.get_size();
let hidpi = (backing_size as f32) / (window_size as f32);
let x = x as f32 * hidpi;
let y = y as f32 * hidpi;
if button == glfw::MouseButtonLeft || button == glfw::MouseButtonRight {
let tmp = local_window();
tmp.borrow().handle_mouse(button, action, x as i32, y as i32);
}
}));
window.glfw_window.set_cursor_pos_callback(
glfw_callback!(glfw::CursorPosCallback(_win: &glfw::Window, xpos: f64, ypos: f64) {
let tmp = local_window();
tmp.borrow().event_queue.with_mut(|queue| queue.push(MouseWindowMoveEventClass(Point2D(xpos as f32, ypos as f32))));
}));
window.glfw_window.set_scroll_callback(
glfw_callback!(glfw::ScrollCallback(win: &glfw::Window, xpos: f64, ypos: f64) {
let dx = (xpos as f32) * 30.0;
let dy = (ypos as f32) * 30.0;
let (x, y) = win.get_cursor_pos(); let wrapped_window = Rc::new(window);
//handle hidpi displays, since GLFW returns non-hi-def coordinates.
let (backing_size, _) = win.get_framebuffer_size();
let (window_size, _) = win.get_size();
let hidpi = (backing_size as f32) / (window_size as f32);
let x = x as f32 * hidpi;
let y = y as f32 * hidpi;
let tmp = local_window();
tmp.borrow().event_queue.with_mut(|queue| queue.push(ScrollWindowEvent(Point2D(dx, dy), Point2D(x as i32, y as i32))));
}));
let wrapped_window = Rc::from_send(window);
install_local_window(wrapped_window.clone());
wrapped_window wrapped_window
} }
@ -203,14 +145,18 @@ impl WindowMethods<Application> for Window {
fn recv(&self) -> WindowEvent { fn recv(&self) -> WindowEvent {
if !self.event_queue.with_mut(|queue| queue.is_empty()) { if !self.event_queue.with_mut(|queue| queue.is_empty()) {
return self.event_queue.with_mut(|queue| queue.shift()) return self.event_queue.with_mut(|queue| queue.shift().unwrap())
} }
glfw::poll_events(); glfw::poll_events();
for (_, event) in self.glfw_window.flush_events() {
self.handle_window_event(&self.glfw_window, event);
}
if self.glfw_window.should_close() { if self.glfw_window.should_close() {
QuitWindowEvent QuitWindowEvent
} else if !self.event_queue.with_mut(|queue| queue.is_empty()) { } else if !self.event_queue.with_mut(|queue| queue.is_empty()) {
self.event_queue.with_mut(|queue| queue.shift()) self.event_queue.with_mut(|queue| queue.shift().unwrap())
} else { } else {
IdleWindowEvent IdleWindowEvent
} }
@ -243,6 +189,52 @@ impl WindowMethods<Application> for Window {
} }
impl Window { impl Window {
fn handle_window_event(&self, window: &glfw::Window, event: glfw::WindowEvent) {
match event {
glfw::KeyEvent(key, _, action, mods) => {
if action == glfw::Press {
self.handle_key(key, mods)
}
},
glfw::FramebufferSizeEvent(width, height) => {
self.event_queue.with_mut(|queue| queue.push(ResizeWindowEvent(width as uint, height as uint)));
},
glfw::RefreshEvent => {
self.event_queue.with_mut(|queue| queue.push(RefreshWindowEvent));
},
glfw::MouseButtonEvent(button, action, _mods) => {
let (x, y) = window.get_cursor_pos();
//handle hidpi displays, since GLFW returns non-hi-def coordinates.
let (backing_size, _) = window.get_framebuffer_size();
let (window_size, _) = window.get_size();
let hidpi = (backing_size as f32) / (window_size as f32);
let x = x as f32 * hidpi;
let y = y as f32 * hidpi;
if button == glfw::MouseButtonLeft || button == glfw::MouseButtonRight {
self.handle_mouse(button, action, x as i32, y as i32);
}
},
glfw::CursorPosEvent(xpos, ypos) => {
self.event_queue.with_mut(|queue| queue.push(MouseWindowMoveEventClass(Point2D(xpos as f32, ypos as f32))));
},
glfw::ScrollEvent(xpos, ypos) => {
let dx = (xpos as f32) * 30.0;
let dy = (ypos as f32) * 30.0;
let (x, y) = window.get_cursor_pos();
//handle hidpi displays, since GLFW returns non-hi-def coordinates.
let (backing_size, _) = window.get_framebuffer_size();
let (window_size, _) = window.get_size();
let hidpi = (backing_size as f32) / (window_size as f32);
let x = x as f32 * hidpi;
let y = y as f32 * hidpi;
self.event_queue.with_mut(|queue| queue.push(ScrollWindowEvent(Point2D(dx, dy), Point2D(x as i32, y as i32))));
},
_ => {}
}
}
/// Helper function to set the window title in accordance with the ready state. /// Helper function to set the window title in accordance with the ready state.
fn update_window_title(&self) { fn update_window_title(&self) {
let now = time::get_time(); let now = time::get_time();
@ -340,17 +332,3 @@ impl Window {
} }
} }
} }
static TLS_KEY: local_data::Key<Rc<Window>> = &local_data::Key;
fn install_local_window(window: Rc<Window>) {
local_data::set(TLS_KEY, window);
}
fn drop_local_window() {
local_data::pop(TLS_KEY);
}
fn local_window() -> Rc<Window> {
local_data::get(TLS_KEY, |v| v.unwrap().clone())
}

View file

@ -8,43 +8,47 @@
#[feature(globs, macro_rules, managed_boxes, thread_local)]; #[feature(globs, macro_rules, managed_boxes, thread_local)];
extern mod alert; extern crate alert;
extern mod azure; extern crate azure;
extern mod geom; extern crate geom;
extern mod gfx; extern crate gfx;
#[cfg(not(target_os="android"))] #[cfg(not(target_os="android"))]
extern mod glfw; extern crate glfw = "glfw-rs";
#[cfg(target_os="android")] #[cfg(target_os="android")]
extern mod glut; extern crate glut;
extern mod js; extern crate js;
extern mod layers; extern crate layers;
extern mod opengles; extern crate opengles;
extern mod png; extern crate png;
#[cfg(target_os="android")] #[cfg(target_os="android")]
extern mod rustuv; extern crate rustuv;
extern mod script; extern crate script;
extern mod servo_net = "net"; extern crate servo_net = "net";
extern mod servo_msg = "msg"; extern crate servo_msg = "msg";
extern mod servo_util = "util"; extern crate servo_util = "util";
extern mod style; extern crate style;
extern mod sharegl; extern crate sharegl;
extern mod stb_image; extern crate stb_image;
extern mod extra; extern crate collections;
extern mod green; extern crate extra;
extern mod native; extern crate green;
extern crate native;
extern crate serialize;
extern crate sync;
extern crate time;
#[cfg(target_os="macos")] #[cfg(target_os="macos")]
extern mod core_graphics; extern crate core_graphics;
#[cfg(target_os="macos")] #[cfg(target_os="macos")]
extern mod core_text; extern crate core_text;
#[cfg(not(test))] #[cfg(not(test))]
use compositing::{CompositorChan, CompositorTask}; use compositing::{CompositorChan, CompositorTask};
#[cfg(not(test))] #[cfg(not(test))]
use constellation::Constellation; use constellation::Constellation;
#[cfg(not(test))] #[cfg(not(test))]
use servo_msg::constellation_msg::InitLoadUrlMsg; use servo_msg::constellation_msg::{ConstellationChan, InitLoadUrlMsg};
#[cfg(not(test))] #[cfg(not(test))]
use servo_net::image_cache_task::{ImageCacheTask, SyncImageCacheTask}; use servo_net::image_cache_task::{ImageCacheTask, SyncImageCacheTask};
@ -175,7 +179,8 @@ fn run(opts: opts::Opts) {
parse_url(*filename, None) parse_url(*filename, None)
}; };
constellation_chan.send(InitLoadUrlMsg(url)); let ConstellationChan(ref chan) = constellation_chan;
chan.send(InitLoadUrlMsg(url));
} }
// Send the constallation Chan as the result // Send the constallation Chan as the result

View file

@ -3,8 +3,8 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use servo_util::task::spawn_named; use servo_util::task::spawn_named;
/*
pub fn spawn_listener<A: Send, S: IntoSendStr>(name: S, f: proc(Port<A>)) -> Chan<A> { pub fn spawn_listener<'a, A: Send, S: IntoMaybeOwned<'a>>(name: S, f: proc(Port<A>)) -> Chan<A> {
let (setup_po, setup_ch) = Chan::new(); let (setup_po, setup_ch) = Chan::new();
spawn_named(name, proc() { spawn_named(name, proc() {
let (po, ch) = Chan::new(); let (po, ch) = Chan::new();
@ -14,10 +14,11 @@ pub fn spawn_listener<A: Send, S: IntoSendStr>(name: S, f: proc(Port<A>)) -> Cha
setup_po.recv() setup_po.recv()
} }
pub fn spawn_conversation<A: Send, B: Send, S: IntoSendStr>(name: S, f: proc(Port<A>, Chan<B>)) -> (Port<B>, Chan<A>) { pub fn spawn_conversation<'a, A: Send, B: Send, S: IntoMaybeOwned<'a>>(name: S, f: proc(Port<A>, Chan<B>)) -> (Port<B>, Chan<A>) {
let (from_child, to_parent) = Chan::new(); let (from_child, to_parent) = Chan::new();
let to_child = do spawn_listener(name) |from_parent| { let to_child = spawn_listener(name, |from_parent| {
f(from_parent, to_parent) f(from_parent, to_parent)
}; });
(from_child, to_child) (from_child, to_child)
} }
*/

View file

@ -11,7 +11,7 @@ use layers::platform::surface::{NativeSurface, NativeSurfaceMethods};
use constellation_msg::PipelineId; use constellation_msg::PipelineId;
use extra::serialize::{Encoder, Encodable}; use serialize::{Encoder, Encodable};
pub struct LayerBuffer { pub struct LayerBuffer {
/// The native surface which can be shared between threads or processes. On Mac this is an /// The native surface which can be shared between threads or processes. On Mac this is an
@ -71,7 +71,8 @@ pub struct Epoch(uint);
impl Epoch { impl Epoch {
pub fn next(&mut self) { pub fn next(&mut self) {
**self += 1; let Epoch(ref mut u) = *self;
*u += 1;
} }
} }
@ -97,7 +98,7 @@ pub trait ScriptListener : Clone {
fn dup(&self) -> ~ScriptListener; fn dup(&self) -> ~ScriptListener;
} }
impl<S: Encoder> Encodable<S> for @ScriptListener { impl<S: Encoder> Encodable<S> for ~ScriptListener {
fn encode(&self, _s: &mut S) { fn encode(&self, _s: &mut S) {
} }
} }
@ -125,7 +126,7 @@ impl Tile for ~LayerBuffer {
self.screen_pos.size.width * self.screen_pos.size.height self.screen_pos.size.width * self.screen_pos.size.height
} }
fn is_valid(&self, scale: f32) -> bool { fn is_valid(&self, scale: f32) -> bool {
self.resolution.approx_eq(&scale) (self.resolution - scale).abs() < 1.0e-6
} }
fn get_size_2d(&self) -> Size2D<uint> { fn get_size_2d(&self) -> Size2D<uint> {
self.screen_pos.size self.screen_pos.size

View file

@ -8,14 +8,14 @@
use extra::url::Url; use extra::url::Url;
use geom::rect::Rect; use geom::rect::Rect;
use geom::size::Size2D; use geom::size::Size2D;
use std::comm::SharedChan; use std::comm::Chan;
#[deriving(Clone)] #[deriving(Clone)]
pub struct ConstellationChan(SharedChan<Msg>); pub struct ConstellationChan(Chan<Msg>);
impl ConstellationChan { impl ConstellationChan {
pub fn new() -> (Port<Msg>, ConstellationChan) { pub fn new() -> (Port<Msg>, ConstellationChan) {
let (port, chan) = SharedChan::new(); let (port, chan) = Chan::new();
(port, ConstellationChan(chan)) (port, ConstellationChan(chan))
} }
} }
@ -48,20 +48,20 @@ pub enum Msg {
} }
/// Represents the two different ways to which a page can be navigated /// Represents the two different ways to which a page can be navigated
#[deriving(Clone, Eq, IterBytes)] #[deriving(Clone, Eq, Hash)]
pub enum NavigationType { pub enum NavigationType {
Load, // entered or clicked on a url Load, // entered or clicked on a url
Navigate, // browser forward/back buttons Navigate, // browser forward/back buttons
} }
#[deriving(Clone, Eq, IterBytes)] #[deriving(Clone, Eq, Hash)]
pub enum NavigationDirection { pub enum NavigationDirection {
Forward, Forward,
Back, Back,
} }
#[deriving(Clone, Eq, IterBytes, Encodable)] #[deriving(Clone, Eq, Hash, Encodable)]
pub struct PipelineId(uint); pub struct PipelineId(uint);
#[deriving(Clone, Eq, IterBytes, Encodable)] #[deriving(Clone, Eq, Hash, Encodable)]
pub struct SubpageId(uint); pub struct SubpageId(uint);

View file

@ -7,16 +7,17 @@
#[feature(managed_boxes)]; #[feature(managed_boxes)];
extern mod azure; extern crate azure;
extern mod extra; extern crate extra;
extern mod geom; extern crate geom;
extern mod layers; extern crate layers;
extern mod std; extern crate serialize;
extern crate std;
#[cfg(target_os="macos")] #[cfg(target_os="macos")]
extern mod core_foundation; extern crate core_foundation;
#[cfg(target_os="macos")] #[cfg(target_os="macos")]
extern mod io_surface; extern crate io_surface;
pub mod compositor_msg; pub mod compositor_msg;
pub mod constellation_msg; pub mod constellation_msg;

View file

@ -5,7 +5,7 @@
use resource_task::{Done, Payload, Metadata, LoadResponse, LoaderTask, start_sending}; use resource_task::{Done, Payload, Metadata, LoadResponse, LoaderTask, start_sending};
use extra::url::Url; use extra::url::Url;
use extra::base64::FromBase64; use serialize::base64::FromBase64;
use http::headers::test_utils::from_stream_with_str; use http::headers::test_utils::from_stream_with_str;
use http::headers::content_type::MediaType; use http::headers::content_type::MediaType;

View file

@ -3,7 +3,6 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use resource_task::{ProgressMsg, Metadata, Payload, Done, LoaderTask, start_sending}; use resource_task::{ProgressMsg, Metadata, Payload, Done, LoaderTask, start_sending};
use servo_util::io::result;
use std::io; use std::io;
use std::io::File; use std::io::File;
@ -11,14 +10,11 @@ use servo_util::task::spawn_named;
static READ_SIZE: uint = 1024; static READ_SIZE: uint = 1024;
fn read_all(reader: &mut io::Stream, progress_chan: &SharedChan<ProgressMsg>) fn read_all(reader: &mut io::Stream, progress_chan: &Chan<ProgressMsg>)
-> Result<(), ()> { -> Result<(), ()> {
loop { loop {
match (result(|| { match (reader.read_bytes(READ_SIZE)) {
let data = reader.read_bytes(READ_SIZE); Ok(data) => progress_chan.send(Payload(data)),
progress_chan.send(Payload(data));
})) {
Ok(()) => (),
Err(e) => match e.kind { Err(e) => match e.kind {
io::EndOfFile => return Ok(()), io::EndOfFile => return Ok(()),
_ => return Err(()), _ => return Err(()),
@ -32,14 +28,12 @@ pub fn factory() -> LoaderTask {
assert!("file" == url.scheme); assert!("file" == url.scheme);
let progress_chan = start_sending(start_chan, Metadata::default(url.clone())); let progress_chan = start_sending(start_chan, Metadata::default(url.clone()));
spawn_named("file_loader", proc() { spawn_named("file_loader", proc() {
// ignore_io_error causes us to get None instead of a task failure.
let _guard = io::ignore_io_error();
match File::open_mode(&Path::new(url.path), io::Open, io::Read) { match File::open_mode(&Path::new(url.path), io::Open, io::Read) {
Some(ref mut reader) => { Ok(ref mut reader) => {
let res = read_all(reader as &mut io::Stream, &progress_chan); let res = read_all(reader as &mut io::Stream, &progress_chan);
progress_chan.send(Done(res)); progress_chan.send(Done(res));
} }
None => { Err(_) => {
progress_chan.send(Done(Err(()))); progress_chan.send(Done(Err(())));
} }
}; };

View file

@ -5,12 +5,13 @@
use resource_task::{Metadata, Payload, Done, LoadResponse, LoaderTask, start_sending}; use resource_task::{Metadata, Payload, Done, LoadResponse, LoaderTask, start_sending};
use std::vec; use std::vec;
use std::hashmap::HashSet; use collections::hashmap::HashSet;
use extra::url::Url; use extra::url::Url;
use http::client::RequestWriter; use http::client::RequestWriter;
use http::method::Get; use http::method::Get;
use http::headers::HeaderEnum; use http::headers::HeaderEnum;
use std::io::Reader; use std::io::Reader;
use std::io::net::tcp::TcpStream;
use servo_util::task::spawn_named; use servo_util::task::spawn_named;
pub fn factory() -> LoaderTask { pub fn factory() -> LoaderTask {
@ -55,8 +56,15 @@ fn load(mut url: Url, start_chan: Chan<LoadResponse>) {
info!("requesting {:s}", url.to_str()); info!("requesting {:s}", url.to_str());
let request = ~RequestWriter::new(Get, url.clone()); let request = RequestWriter::<TcpStream>::new(Get, url.clone());
let mut response = match request.read_response() { let mut writer = match request {
Ok(w) => ~w,
Err(_) => {
send_error(url, start_chan);
return;
}
};
let mut response = match writer.read_response() {
Ok(r) => r, Ok(r) => r,
Err(_) => { Err(_) => {
send_error(url, start_chan); send_error(url, start_chan);
@ -91,11 +99,11 @@ fn load(mut url: Url, start_chan: Chan<LoadResponse>) {
unsafe { buf.set_len(1024); } unsafe { buf.set_len(1024); }
match response.read(buf) { match response.read(buf) {
Some(len) => { Ok(len) => {
unsafe { buf.set_len(len); } unsafe { buf.set_len(len); }
progress_chan.send(Payload(buf)); progress_chan.send(Payload(buf));
} }
None => { Err(_) => {
progress_chan.send(Done(Ok(()))); progress_chan.send(Done(Ok(())));
break; break;
} }

View file

@ -6,10 +6,10 @@ use image::base::Image;
use image_cache_task::{ImageReady, ImageNotReady, ImageFailed}; use image_cache_task::{ImageReady, ImageNotReady, ImageFailed};
use local_image_cache::LocalImageCache; use local_image_cache::LocalImageCache;
use extra::arc::{Arc, MutexArc}; use sync::{Arc, MutexArc};
use extra::url::Url; use extra::url::Url;
use geom::size::Size2D; use geom::size::Size2D;
use std::util; use std::mem;
// FIXME: Nasty coupling here This will be a problem if we want to factor out image handling from // FIXME: Nasty coupling here This will be a problem if we want to factor out image handling from
// the network stack. This should probably be factored out into an interface and use dependency // the network stack. This should probably be factored out into an interface and use dependency
@ -40,12 +40,10 @@ impl ImageHolder {
// but they are intended to be spread out in time. Ideally prefetch // but they are intended to be spread out in time. Ideally prefetch
// should be done as early as possible and decode only once we // should be done as early as possible and decode only once we
// are sure that the image will be used. // are sure that the image will be used.
unsafe { holder.local_image_cache.access(|local_image_cache| {
holder.local_image_cache.unsafe_access(|local_image_cache| { local_image_cache.prefetch(&holder.url);
local_image_cache.prefetch(&holder.url); local_image_cache.decode(&holder.url);
local_image_cache.decode(&holder.url); });
});
}
holder holder
} }
@ -76,11 +74,10 @@ impl ImageHolder {
// If this is the first time we've called this function, load // If this is the first time we've called this function, load
// the image and store it for the future // the image and store it for the future
if self.image.is_none() { if self.image.is_none() {
let port = unsafe { let port =
self.local_image_cache.unsafe_access(|local_image_cache| { self.local_image_cache.access(|local_image_cache| {
local_image_cache.get_image(&self.url) local_image_cache.get_image(&self.url)
}) });
};
match port.recv() { match port.recv() {
ImageReady(image) => { ImageReady(image) => {
self.image = Some(image); self.image = Some(image);
@ -95,9 +92,9 @@ impl ImageHolder {
} }
// Clone isn't pure so we have to swap out the mutable image option // Clone isn't pure so we have to swap out the mutable image option
let image = util::replace(&mut self.image, None); let image = mem::replace(&mut self.image, None);
let result = image.clone(); let result = image.clone();
util::replace(&mut self.image, image); mem::replace(&mut self.image, image);
return result; return result;
} }

View file

@ -7,14 +7,14 @@ use resource_task;
use resource_task::ResourceTask; use resource_task::ResourceTask;
use servo_util::url::{UrlMap, url_map}; use servo_util::url::{UrlMap, url_map};
use std::comm::{Chan, Port, SharedChan}; use std::comm::{Chan, Port};
use std::mem::replace;
use std::task::spawn; use std::task::spawn;
use std::to_str::ToStr; use std::to_str::ToStr;
use std::util::replace;
use std::result; use std::result;
use extra::arc::{Arc,MutexArc}; use sync::{Arc,MutexArc};
use extra::url::Url; use extra::url::Url;
use extra::serialize::{Encoder, Encodable}; use serialize::{Encoder, Encodable};
pub enum Msg { pub enum Msg {
/// Tell the cache that we may need a particular image soon. Must be posted /// Tell the cache that we may need a particular image soon. Must be posted
@ -78,7 +78,7 @@ impl Eq for ImageResponseMsg {
#[deriving(Clone)] #[deriving(Clone)]
pub struct ImageCacheTask { pub struct ImageCacheTask {
chan: SharedChan<Msg>, chan: Chan<Msg>,
} }
impl<S: Encoder> Encodable<S> for ImageCacheTask { impl<S: Encoder> Encodable<S> for ImageCacheTask {
@ -89,7 +89,7 @@ impl<S: Encoder> Encodable<S> for ImageCacheTask {
type DecoderFactory = fn() -> proc(&[u8]) -> Option<Image>; type DecoderFactory = fn() -> proc(&[u8]) -> Option<Image>;
pub fn ImageCacheTask(resource_task: ResourceTask) -> ImageCacheTask { pub fn ImageCacheTask(resource_task: ResourceTask) -> ImageCacheTask {
let (port, chan) = SharedChan::new(); let (port, chan) = Chan::new();
let chan_clone = chan.clone(); let chan_clone = chan.clone();
spawn(proc() { spawn(proc() {
@ -111,7 +111,7 @@ pub fn ImageCacheTask(resource_task: ResourceTask) -> ImageCacheTask {
// FIXME: make this priv after visibility rules change // FIXME: make this priv after visibility rules change
pub fn SyncImageCacheTask(resource_task: ResourceTask) -> ImageCacheTask { pub fn SyncImageCacheTask(resource_task: ResourceTask) -> ImageCacheTask {
let (port, chan) = SharedChan::new(); let (port, chan) = Chan::new();
spawn(proc() { spawn(proc() {
let inner_cache = ImageCacheTask(resource_task.clone()); let inner_cache = ImageCacheTask(resource_task.clone());
@ -143,7 +143,7 @@ struct ImageCache {
/// The port on which we'll receive client requests /// The port on which we'll receive client requests
port: Port<Msg>, port: Port<Msg>,
/// A copy of the shared chan to give to child tasks /// A copy of the shared chan to give to child tasks
chan: SharedChan<Msg>, chan: Chan<Msg>,
/// The state of processsing an image for a URL /// The state of processsing an image for a URL
state_map: UrlMap<ImageState>, state_map: UrlMap<ImageState>,
/// List of clients waiting on a WaitForImage response /// List of clients waiting on a WaitForImage response
@ -375,13 +375,11 @@ impl ImageCache {
fn purge_waiters(&mut self, url: Url, f: || -> ImageResponseMsg) { fn purge_waiters(&mut self, url: Url, f: || -> ImageResponseMsg) {
match self.wait_map.pop(&url) { match self.wait_map.pop(&url) {
Some(waiters) => { Some(waiters) => {
unsafe { waiters.access(|waiters| {
waiters.unsafe_access(|waiters| { for response in waiters.iter() {
for response in waiters.iter() { response.send(f());
response.send(f()); }
} });
});
}
} }
None => () None => ()
} }
@ -409,9 +407,7 @@ impl ImageCache {
if self.wait_map.contains_key(&url) { if self.wait_map.contains_key(&url) {
let waiters = self.wait_map.find_mut(&url).unwrap(); let waiters = self.wait_map.find_mut(&url).unwrap();
let mut response = Some(response); let mut response = Some(response);
unsafe { waiters.access(|waiters| waiters.push(response.take().unwrap()));
waiters.unsafe_access(|waiters| waiters.push(response.take().unwrap()))
}
} else { } else {
self.wait_map.insert(url, MutexArc::new(~[response])); self.wait_map.insert(url, MutexArc::new(~[response]));
} }
@ -430,7 +426,7 @@ impl ImageCache {
} }
trait ImageCacheTaskClient { pub trait ImageCacheTaskClient {
fn exit(&self); fn exit(&self);
} }
@ -495,7 +491,7 @@ mod tests {
use util::spawn_listener; use util::spawn_listener;
use servo_util::url::parse_url; use servo_util::url::parse_url;
fn mock_resource_task(on_load: proc(resource: SharedChan<resource_task::ProgressMsg>)) -> ResourceTask { fn mock_resource_task(on_load: proc(resource: Chan<resource_task::ProgressMsg>)) -> ResourceTask {
spawn_listener("mock_resource_task", proc(port: Port<resource_task::ControlMsg>) { spawn_listener("mock_resource_task", proc(port: Port<resource_task::ControlMsg>) {
loop { loop {
match port.recv() { match port.recv() {

View file

@ -126,11 +126,11 @@ impl LocalImageCache {
assert!(self.on_image_available.is_some()); assert!(self.on_image_available.is_some());
let on_image_available = self.on_image_available.as_ref().unwrap().respond(); let on_image_available = self.on_image_available.as_ref().unwrap().respond();
let url = (*url).clone(); let url = (*url).clone();
do spawn_named("LocalImageCache") { spawn_named("LocalImageCache", proc() {
let (response_port, response_chan) = Chan::new(); let (response_port, response_chan) = Chan::new();
image_cache_task.send(WaitForImage(url.clone(), response_chan)); image_cache_task.send(WaitForImage(url.clone(), response_chan));
on_image_available(response_port.recv()); on_image_available(response_port.recv());
} });
} }
_ => () _ => ()
} }

View file

@ -7,12 +7,15 @@
#[feature(globs, managed_boxes)]; #[feature(globs, managed_boxes)];
extern mod geom; extern crate collections;
extern mod http; extern crate geom;
extern mod servo_util = "util"; extern crate http;
extern mod stb_image; extern crate servo_util = "util";
extern mod extra; extern crate stb_image;
extern mod png; extern crate extra;
extern crate png;
extern crate serialize;
extern crate sync;
/// Image handling. /// Image handling.
/// ///

View file

@ -8,9 +8,10 @@ use file_loader;
use http_loader; use http_loader;
use data_loader; use data_loader;
use std::comm::{Chan, Port, SharedChan}; use std::comm::{Chan, Port};
use std::cast;
use std::task;
use extra::url::Url; use extra::url::Url;
use util::spawn_listener;
use http::headers::content_type::MediaType; use http::headers::content_type::MediaType;
#[cfg(test)] #[cfg(test)]
@ -85,8 +86,8 @@ pub enum ProgressMsg {
/// For use by loaders in responding to a Load message. /// For use by loaders in responding to a Load message.
pub fn start_sending(start_chan: Chan<LoadResponse>, pub fn start_sending(start_chan: Chan<LoadResponse>,
metadata: Metadata) -> SharedChan<ProgressMsg> { metadata: Metadata) -> Chan<ProgressMsg> {
let (progress_port, progress_chan) = SharedChan::new(); let (progress_port, progress_chan) = Chan::new();
start_chan.send(LoadResponse { start_chan.send(LoadResponse {
metadata: metadata, metadata: metadata,
progress_port: progress_port, progress_port: progress_port,
@ -112,7 +113,7 @@ pub fn load_whole_resource(resource_task: &ResourceTask, url: Url)
} }
/// Handle to a resource task /// Handle to a resource task
pub type ResourceTask = SharedChan<ControlMsg>; pub type ResourceTask = Chan<ControlMsg>;
pub type LoaderTask = proc(url: Url, Chan<LoadResponse>); pub type LoaderTask = proc(url: Url, Chan<LoadResponse>);
@ -135,11 +136,26 @@ pub fn ResourceTask() -> ResourceTask {
} }
fn create_resource_task_with_loaders(loaders: ~[(~str, LoaderTaskFactory)]) -> ResourceTask { fn create_resource_task_with_loaders(loaders: ~[(~str, LoaderTaskFactory)]) -> ResourceTask {
let (setup_port, setup_chan) = Chan::new();
let mut builder = task::task().named("ResourceManager");
builder.spawn(proc() {
let (port, chan) = Chan::new();
setup_chan.send(chan);
ResourceManager(port, loaders).start();
});
setup_port.recv()
// FIXME: code cloned from spawn_listener due to:
// error: internal compiler error: cannot relate bound region: ReLateBound(6270, BrNamed(syntax::ast::DefId{krate: 0u32, node: 6294u32}, a)) <= ReInfer(1)
//This message reflects a bug in the Rust compiler.
/*
let chan = spawn_listener("ResourceManager", proc(from_client) { let chan = spawn_listener("ResourceManager", proc(from_client) {
// TODO: change copy to move once we can move out of closures // TODO: change copy to move once we can move out of closures
ResourceManager(from_client, loaders).start() ResourceManager(from_client, loaders).start()
}); });
chan chan
*/
} }
pub struct ResourceManager { pub struct ResourceManager {

View file

@ -5,12 +5,19 @@
use std::comm::{Chan, Port}; use std::comm::{Chan, Port};
use servo_util::task::spawn_named; use servo_util::task::spawn_named;
pub fn spawn_listener<A: Send, S: IntoSendStr>(name: S, f: proc(Port<A>)) -> SharedChan<A> {
// FIXME: code cloned from spawn_listener due to:
// error: internal compiler error: cannot relate bound region: ReLateBound(6270, BrNamed(syntax::ast::DefId{krate: 0u32, node: 6294u32}, a)) <= ReInfer(1)
//This message reflects a bug in the Rust compiler.
/*
pub fn spawn_listener<'a, A: Send, S: IntoMaybeOwned<'a>>(name: S, f: proc(Port<A>)) -> Chan<A> {
let (setup_port, setup_chan) = Chan::new(); let (setup_port, setup_chan) = Chan::new();
do spawn_named(name) { spawn_named(name, proc() {
let (port, chan) = SharedChan::new(); let (port, chan) = Chan::new();
setup_chan.send(chan); setup_chan.send(chan);
f(port); f(port);
} });
setup_port.recv() setup_port.recv()
} }
*/

View file

@ -35,7 +35,7 @@ impl AttrList {
} }
pub fn Item(&self, index: u32) -> Option<JS<Attr>> { pub fn Item(&self, index: u32) -> Option<JS<Attr>> {
self.owner.get().attrs.get_opt(index as uint).map(|x| x.clone()) self.owner.get().attrs.get(index as uint).map(|x| x.clone())
} }
pub fn IndexedGetter(&self, index: u32, found: &mut bool) -> Option<JS<Attr>> { pub fn IndexedGetter(&self, index: u32, found: &mut bool) -> Option<JS<Attr>> {

View file

@ -12,7 +12,7 @@ use std::cast;
use std::libc; use std::libc;
use std::ptr; use std::ptr;
use extra::serialize::{Encodable, Encoder}; use serialize::{Encodable, Encoder};
pub enum ExceptionHandling { pub enum ExceptionHandling {
// Report any exception and don't throw it to the caller code. // Report any exception and don't throw it to the caller code.

View file

@ -370,7 +370,7 @@ class CGMethodCall(CGThing):
overloadCGThings = [] overloadCGThings = []
overloadCGThings.append( overloadCGThings.append(
CGGeneric("let argcount = argc.min(&%d);" % CGGeneric("let argcount = cmp::min(argc,%d);" %
maxArgCount)) maxArgCount))
overloadCGThings.append( overloadCGThings.append(
CGSwitch("argcount", CGSwitch("argcount",
@ -720,7 +720,7 @@ def getJSToNativeConversionTemplate(type, descriptorProvider, failureCode=None,
return handleDefault(conversionCode, return handleDefault(conversionCode,
"${declName}.SetNull()") "${declName}.SetNull()")
value = "str::from_utf8(data).to_owned()" value = "str::from_utf8(data).unwrap().to_owned()"
if type.nullable(): if type.nullable():
value = "Some(%s)" % value value = "Some(%s)" % value
@ -1132,7 +1132,7 @@ def getWrapTemplateForType(type, descriptorProvider, result, successCode,
raise TypeError("We don't support nullable enumerated return types " raise TypeError("We don't support nullable enumerated return types "
"yet") "yet")
return ("""assert!((%(result)s as uint) < %(strings)s.len()); return ("""assert!((%(result)s as uint) < %(strings)s.len());
let %(resultStr)s: *JSString = JS_NewStringCopyN(cx, ptr::to_unsafe_ptr(&%(strings)s[%(result)s as u32].value[0]) as *i8, %(strings)s[%(result)s as u32].length as libc::size_t); let %(resultStr)s: *JSString = JS_NewStringCopyN(cx, &%(strings)s[%(result)s as u32].value[0] as *i8, %(strings)s[%(result)s as u32].length as libc::size_t);
if %(resultStr)s.is_null() { if %(resultStr)s.is_null() {
return 0; return 0;
} }
@ -2066,7 +2066,7 @@ def CreateBindingJSObject(descriptor, parent=None):
let handler = js_info.get().get_ref().dom_static.proxy_handlers.get(&(PrototypeList::id::%s as uint)); let handler = js_info.get().get_ref().dom_static.proxy_handlers.get(&(PrototypeList::id::%s as uint));
""" % descriptor.name """ % descriptor.name
create += handler + """ let obj = NewProxyObject(aCx, *handler, create += handler + """ let obj = NewProxyObject(aCx, *handler,
ptr::to_unsafe_ptr(&PrivateValue(squirrel_away_unique(aObject) as *libc::c_void)), &PrivateValue(squirrel_away_unique(aObject) as *libc::c_void),
proto, %s, proto, %s,
ptr::null(), ptr::null()); ptr::null(), ptr::null());
if obj.is_null() { if obj.is_null() {
@ -2230,7 +2230,7 @@ class CGCreateInterfaceObjectsMethod(CGAbstractMethod):
val = ('%(' + name + ')s') % self.properties.variableNames(False) val = ('%(' + name + ')s') % self.properties.variableNames(False)
if val == "ptr::null()": if val == "ptr::null()":
return val return val
return "ptr::to_unsafe_ptr(&%s[0])" % val return "&%s[0]" % val
call = """return CreateInterfaceObjects2(aCx, aGlobal, aReceiver, parentProto, call = """return CreateInterfaceObjects2(aCx, aGlobal, aReceiver, parentProto,
%s, %s, %d, %s, %s, %d,
@ -2376,7 +2376,7 @@ class CGDefineDOMInterfaceMethod(CGAbstractMethod):
trace: %s trace: %s
}; };
js_info.dom_static.proxy_handlers.insert(PrototypeList::id::%s as uint, js_info.dom_static.proxy_handlers.insert(PrototypeList::id::%s as uint,
CreateProxyHandler(ptr::to_unsafe_ptr(&traps), ptr::to_unsafe_ptr(&Class) as *libc::c_void)); CreateProxyHandler(&traps, cast::transmute(&Class)));
""" % (FINALIZE_HOOK_NAME, """ % (FINALIZE_HOOK_NAME,
('Some(%s)' % TRACE_HOOK_NAME), ('Some(%s)' % TRACE_HOOK_NAME),
@ -3892,7 +3892,7 @@ class CGProxyUnwrap(CGAbstractMethod):
}*/ }*/
//MOZ_ASSERT(IsProxy(obj)); //MOZ_ASSERT(IsProxy(obj));
let box_: *Box<%s> = cast::transmute(GetProxyPrivate(obj).to_private()); let box_: *Box<%s> = cast::transmute(GetProxyPrivate(obj).to_private());
return ptr::to_unsafe_ptr(&(*box_).data);""" % (self.descriptor.concreteType) return cast::transmute(&(*box_).data);""" % (self.descriptor.concreteType)
class CGDOMJSProxyHandler_getOwnPropertyDescriptor(CGAbstractExternMethod): class CGDOMJSProxyHandler_getOwnPropertyDescriptor(CGAbstractExternMethod):
def __init__(self, descriptor): def __init__(self, descriptor):
@ -3913,7 +3913,7 @@ class CGDOMJSProxyHandler_getOwnPropertyDescriptor(CGAbstractExternMethod):
if indexedGetter: if indexedGetter:
readonly = toStringBool(self.descriptor.operations['IndexedSetter'] is None) readonly = toStringBool(self.descriptor.operations['IndexedSetter'] is None)
fillDescriptor = "FillPropertyDescriptor(&mut *desc, proxy, %s);\nreturn 1;" % readonly fillDescriptor = "FillPropertyDescriptor(&mut *desc, proxy, %s);\nreturn 1;" % readonly
templateValues = {'jsvalRef': '(*desc).value', 'jsvalPtr': 'ptr::to_mut_unsafe_ptr(&mut (*desc).value)', templateValues = {'jsvalRef': '(*desc).value', 'jsvalPtr': '&mut (*desc).value',
'obj': 'proxy', 'successCode': fillDescriptor} 'obj': 'proxy', 'successCode': fillDescriptor}
get = ("if index.is_some() {\n" + get = ("if index.is_some() {\n" +
" let index = index.unwrap();\n" + " let index = index.unwrap();\n" +
@ -3955,7 +3955,7 @@ class CGDOMJSProxyHandler_getOwnPropertyDescriptor(CGAbstractExternMethod):
if namedGetter: if namedGetter:
readonly = toStringBool(self.descriptor.operations['NamedSetter'] is None) readonly = toStringBool(self.descriptor.operations['NamedSetter'] is None)
fillDescriptor = "FillPropertyDescriptor(&mut *desc, proxy, %s);\nreturn 1;" % readonly fillDescriptor = "FillPropertyDescriptor(&mut *desc, proxy, %s);\nreturn 1;" % readonly
templateValues = {'jsvalRef': '(*desc).value', 'jsvalPtr': 'ptr::to_unsafe_ptr(&(*desc).value)', templateValues = {'jsvalRef': '(*desc).value', 'jsvalPtr': '&mut(*desc).value',
'obj': 'proxy', 'successCode': fillDescriptor} 'obj': 'proxy', 'successCode': fillDescriptor}
# Once we start supporting OverrideBuiltins we need to make # Once we start supporting OverrideBuiltins we need to make
# ResolveOwnProperty or EnumerateOwnProperties filter out named # ResolveOwnProperty or EnumerateOwnProperties filter out named
@ -4101,7 +4101,7 @@ class CGDOMJSProxyHandler_get(CGAbstractExternMethod):
getFromExpando = """let expando = GetExpandoObject(proxy); getFromExpando = """let expando = GetExpandoObject(proxy);
if expando.is_not_null() { if expando.is_not_null() {
let hasProp = 0; let hasProp = 0;
if JS_HasPropertyById(cx, expando, id, ptr::to_unsafe_ptr(&hasProp)) == 0 { if JS_HasPropertyById(cx, expando, id, &hasProp) == 0 {
return 0; return 0;
} }
@ -4604,15 +4604,15 @@ class CGDictionary(CGThing):
if True: #XXXjdm hack until 'static mut' exists for global jsids if True: #XXXjdm hack until 'static mut' exists for global jsids
propName = member.identifier.name propName = member.identifier.name
propCheck = ('"%s".to_c_str().with_ref(|s| { JS_HasProperty(cx, val.to_object(), s, ptr::to_unsafe_ptr(&found)) })' % propCheck = ('"%s".to_c_str().with_ref(|s| { JS_HasProperty(cx, val.to_object(), s, &found) })' %
propName) propName)
propGet = ('"%s".to_c_str().with_ref(|s| { JS_GetProperty(cx, val.to_object(), s, ptr::to_unsafe_ptr(&temp)) })' % propGet = ('"%s".to_c_str().with_ref(|s| { JS_GetProperty(cx, val.to_object(), s, &temp) })' %
propName) propName)
else: else:
propId = self.makeIdName(member.identifier.name); propId = self.makeIdName(member.identifier.name);
propCheck = ("JS_HasPropertyById(cx, val.to_object(), %s, ptr::to_unsafe_ptr(&found))" % propCheck = ("JS_HasPropertyById(cx, val.to_object(), %s, &found)" %
propId) propId)
propGet = ("JS_GetPropertyById(cx, val.to_object(), %s, ptr::to_unsafe_ptr(&temp))" % propGet = ("JS_GetPropertyById(cx, val.to_object(), %s, &temp)" %
propId) propId)
conversionReplacements = { conversionReplacements = {
@ -4818,12 +4818,14 @@ class CGBindingRoot(CGThing):
'servo_util::str::DOMString', 'servo_util::str::DOMString',
'servo_util::vec::zip_copies', 'servo_util::vec::zip_copies',
'std::cast', 'std::cast',
'std::cmp',
'std::libc', 'std::libc',
'std::ptr', 'std::ptr',
'std::vec', 'std::vec',
'std::str', 'std::str',
'std::num', 'std::num',
'std::unstable::raw::Box', 'std::intrinsics::uninit',
'std::raw::Box',
]) ])
# Add the auto-generated comment. # Add the auto-generated comment.
@ -5767,7 +5769,7 @@ class GlobalGenRoots():
CGGeneric("use dom::types::*;\n"), CGGeneric("use dom::types::*;\n"),
CGGeneric("use dom::bindings::js::JS;\n"), CGGeneric("use dom::bindings::js::JS;\n"),
CGGeneric("use dom::bindings::trace::Traceable;\n"), CGGeneric("use dom::bindings::trace::Traceable;\n"),
CGGeneric("use extra::serialize::{Encodable, Encoder};\n"), CGGeneric("use serialize::{Encodable, Encoder};\n"),
CGGeneric("use js::jsapi::JSTracer;\n\n")] CGGeneric("use js::jsapi::JSTracer;\n\n")]
for descriptor in descriptors: for descriptor in descriptors:
name = descriptor.name name = descriptor.name

View file

@ -7,7 +7,7 @@ use js::jsapi::{JS_IsExceptionPending};
use js::glue::{ReportError}; use js::glue::{ReportError};
#[deriving(ToStr)] #[deriving(Show)]
pub enum Error { pub enum Error {
FailureUnknown, FailureUnknown,
NotFound, NotFound,

View file

@ -9,7 +9,7 @@ use layout_interface::TrustedNodeAddress;
use std::cast; use std::cast;
use std::cell::RefCell; use std::cell::RefCell;
use std::unstable::raw::Box; use std::raw::Box;
pub struct JS<T> { pub struct JS<T> {
priv ptr: RefCell<*mut T> priv ptr: RefCell<*mut T>

View file

@ -11,7 +11,7 @@ use std::cast;
use std::libc; use std::libc;
use std::ptr; use std::ptr;
use std::ptr::null; use std::ptr::null;
use extra::serialize::{Encodable, Encoder}; use serialize::{Encodable, Encoder};
// IMPORTANT: We rely on the fact that we never attempt to encode DOM objects using // IMPORTANT: We rely on the fact that we never attempt to encode DOM objects using
// any encoder but JSTracer. Since we derive trace hooks automatically, // any encoder but JSTracer. Since we derive trace hooks automatically,

View file

@ -8,16 +8,16 @@ use dom::bindings::js::JS;
use dom::window; use dom::window;
use servo_util::str::DOMString; use servo_util::str::DOMString;
use collections::hashmap::HashMap;
use std::libc::c_uint; use std::libc::c_uint;
use std::cast; use std::cast;
use std::cmp::Eq; use std::cmp::Eq;
use std::hashmap::HashMap;
use std::libc; use std::libc;
use std::ptr; use std::ptr;
use std::ptr::null; use std::ptr::null;
use std::str; use std::str;
use std::vec; use std::vec;
use std::unstable::raw::Box; use std::raw::Box;
use js::glue::*; use js::glue::*;
use js::glue::{js_IsObjectProxyClass, js_IsFunctionProxyClass, IsProxyHandlerFamily}; use js::glue::{js_IsObjectProxyClass, js_IsFunctionProxyClass, IsProxyHandlerFamily};
use js::jsapi::{JS_AlreadyHasOwnProperty, JS_NewFunction}; use js::jsapi::{JS_AlreadyHasOwnProperty, JS_NewFunction};
@ -149,7 +149,7 @@ pub fn jsstring_to_str(cx: *JSContext, s: *JSString) -> DOMString {
let length = 0; let length = 0;
let chars = JS_GetStringCharsAndLength(cx, s, &length); let chars = JS_GetStringCharsAndLength(cx, s, &length);
vec::raw::buf_as_slice(chars, length as uint, |char_vec| { vec::raw::buf_as_slice(chars, length as uint, |char_vec| {
str::from_utf16(char_vec) str::from_utf16(char_vec).unwrap()
}) })
} }
} }
@ -470,7 +470,7 @@ pub fn GetPropertyOnPrototype(cx: *JSContext, proxy: *JSObject, id: jsid, found:
return true; return true;
} }
let hasProp = 0; let hasProp = 0;
if JS_HasPropertyById(cx, proto, id, ptr::to_unsafe_ptr(&hasProp)) == 0 { if JS_HasPropertyById(cx, proto, id, &hasProp) == 0 {
return false; return false;
} }
*found = hasProp != 0; *found = hasProp != 0;

View file

@ -38,12 +38,12 @@ use layout_interface::{DocumentDamageLevel, ContentChangedDocumentDamage};
use servo_util::namespace::{Namespace, Null}; use servo_util::namespace::{Namespace, Null};
use servo_util::str::DOMString; use servo_util::str::DOMString;
use collections::hashmap::HashMap;
use extra::url::{Url, from_str}; use extra::url::{Url, from_str};
use js::jsapi::{JSObject, JSContext}; use js::jsapi::{JSObject, JSContext};
use std::ascii::StrAsciiExt; use std::ascii::StrAsciiExt;
use std::hashmap::HashMap;
use extra::serialize::{Encoder, Encodable}; use serialize::{Encoder, Encodable};
#[deriving(Eq,Encodable)] #[deriving(Eq,Encodable)]
pub enum IsHTMLDocument { pub enum IsHTMLDocument {
@ -435,7 +435,7 @@ impl Document {
} }
let element: JS<Element> = ElementCast::to(node); let element: JS<Element> = ElementCast::to(node);
element.get().get_attribute(Null, "name").map_default(false, |attr| { element.get().get_attribute(Null, "name").map_or(false, |attr| {
attr.get().value_ref() == name attr.get().value_ref() == name
}) })
}) })

View file

@ -10,7 +10,7 @@ use dom::window::Window;
use servo_util::str::DOMString; use servo_util::str::DOMString;
#[repr(uint)] #[repr(uint)]
#[deriving(ToStr, Encodable)] #[deriving(Show, Encodable)]
enum DOMErrorName { enum DOMErrorName {
IndexSizeError = DOMExceptionConstants::INDEX_SIZE_ERR, IndexSizeError = DOMExceptionConstants::INDEX_SIZE_ERR,
HierarchyRequestError = DOMExceptionConstants::HIERARCHY_REQUEST_ERR, HierarchyRequestError = DOMExceptionConstants::HIERARCHY_REQUEST_ERR,

View file

@ -11,7 +11,7 @@ use dom::eventdispatcher::dispatch_event;
use dom::node::NodeTypeId; use dom::node::NodeTypeId;
use servo_util::str::DOMString; use servo_util::str::DOMString;
use std::hashmap::HashMap; use collections::hashmap::HashMap;
#[deriving(Eq,Encodable)] #[deriving(Eq,Encodable)]
pub enum ListenerPhase { pub enum ListenerPhase {

View file

@ -11,7 +11,7 @@ use dom::htmlformelement::HTMLFormElement;
use dom::window::Window; use dom::window::Window;
use servo_util::str::DOMString; use servo_util::str::DOMString;
use std::hashmap::HashMap; use collections::hashmap::HashMap;
#[deriving(Encodable)] #[deriving(Encodable)]
enum FormDatum { enum FormDatum {

View file

@ -15,9 +15,9 @@ use dom::windowproxy::WindowProxy;
use servo_util::str::DOMString; use servo_util::str::DOMString;
use extra::url::Url; use extra::url::Url;
use serialize::{Encoder, Encodable};
use servo_msg::constellation_msg::{PipelineId, SubpageId}; use servo_msg::constellation_msg::{PipelineId, SubpageId};
use std::ascii::StrAsciiExt; use std::ascii::StrAsciiExt;
use extra::serialize::{Encoder, Encodable};
enum SandboxAllowance { enum SandboxAllowance {
AllowNothing = 0x00, AllowNothing = 0x00,

View file

@ -19,7 +19,7 @@ use servo_net::image_cache_task;
use servo_util::url::parse_url; use servo_util::url::parse_url;
use servo_util::str::DOMString; use servo_util::str::DOMString;
use extra::serialize::{Encoder, Encodable}; use serialize::{Encoder, Encodable};
#[deriving(Encodable)] #[deriving(Encodable)]
pub struct HTMLImageElement { pub struct HTMLImageElement {

View file

@ -25,7 +25,7 @@ pub fn serialize(iterator: &mut NodeIterator) -> ~str {
for node in *iterator { for node in *iterator {
while open_elements.len() > iterator.depth { while open_elements.len() > iterator.depth {
html.push_str(~"</" + open_elements.pop() + ">"); html.push_str(~"</" + open_elements.pop().unwrap().as_slice() + ">");
} }
html.push_str( html.push_str(
match node.type_id() { match node.type_id() {
@ -59,7 +59,7 @@ pub fn serialize(iterator: &mut NodeIterator) -> ~str {
); );
} }
while open_elements.len() > 0 { while open_elements.len() > 0 {
html.push_str(~"</" + open_elements.pop() + ">"); html.push_str(~"</" + open_elements.pop().unwrap().as_slice() + ">");
} }
html html
} }

View file

@ -12,7 +12,7 @@ use servo_util::str::DOMString;
use script_task::{Page}; use script_task::{Page};
use std::rc::Rc; use std::rc::Rc;
use extra::serialize::{Encoder, Encodable}; use serialize::{Encoder, Encodable};
#[deriving(Encodable)] #[deriving(Encodable)]

View file

@ -36,12 +36,11 @@ use std::cast::transmute;
use std::cast; use std::cast;
use std::cell::{RefCell, Ref, RefMut}; use std::cell::{RefCell, Ref, RefMut};
use std::iter::{Map, Filter}; use std::iter::{Map, Filter};
use std::libc::uintptr_t; use std::libc::{c_void, uintptr_t};
use std::ptr; use std::mem;
use std::unstable::raw::Box; use std::raw::Box;
use std::util;
use extra::serialize::{Encoder, Encodable}; use serialize::{Encoder, Encodable};
// //
// The basic Node structure // The basic Node structure
@ -806,11 +805,14 @@ impl Node {
/// Sends layout data, if any, back to the script task to be destroyed. /// Sends layout data, if any, back to the script task to be destroyed.
pub unsafe fn reap_layout_data(&mut self) { pub unsafe fn reap_layout_data(&mut self) {
if self.layout_data.is_present() { if self.layout_data.is_present() {
let layout_data = util::replace(&mut self.layout_data, LayoutDataRef::new()); let layout_data = mem::replace(&mut self.layout_data, LayoutDataRef::new());
let layout_chan = layout_data.take_chan(); let layout_chan = layout_data.take_chan();
match layout_chan { match layout_chan {
None => {} None => {}
Some(chan) => chan.send(ReapLayoutDataMsg(layout_data)), Some(chan) => {
let LayoutChan(chan) = chan;
chan.send(ReapLayoutDataMsg(layout_data))
},
} }
} }
} }
@ -1268,7 +1270,7 @@ impl Node {
// http://dom.spec.whatwg.org/#concept-node-remove // http://dom.spec.whatwg.org/#concept-node-remove
fn remove(node: &mut JS<Node>, parent: &mut JS<Node>, suppress_observers: SuppressObserver) { fn remove(node: &mut JS<Node>, parent: &mut JS<Node>, suppress_observers: SuppressObserver) {
assert!(node.parent_node().map_default(false, |ref node_parent| node_parent == parent)); assert!(node.parent_node().map_or(false, |ref node_parent| node_parent == parent));
// Step 1-5: ranges. // Step 1-5: ranges.
// Step 6-7: mutation observers. // Step 6-7: mutation observers.
@ -1685,15 +1687,20 @@ impl Node {
} }
if lastself != lastother { if lastself != lastother {
let random = if ptr::to_unsafe_ptr(abstract_self.get()) < ptr::to_unsafe_ptr(other.get()) { unsafe {
NodeConstants::DOCUMENT_POSITION_FOLLOWING let abstract_uint: uintptr_t = cast::transmute(abstract_self.get());
} else { let other_uint: uintptr_t = cast::transmute(other.get());
NodeConstants::DOCUMENT_POSITION_PRECEDING
}; let random = if (abstract_uint < other_uint) {
// step 3. NodeConstants::DOCUMENT_POSITION_FOLLOWING
return random + } else {
NodeConstants::DOCUMENT_POSITION_DISCONNECTED + NodeConstants::DOCUMENT_POSITION_PRECEDING
NodeConstants::DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC; };
// step 3.
return random +
NodeConstants::DOCUMENT_POSITION_DISCONNECTED +
NodeConstants::DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC;
}
} }
for child in lastself.traverse_preorder() { for child in lastself.traverse_preorder() {

View file

@ -25,16 +25,16 @@ use js::jsval::JSVal;
use js::jsval::{NullValue, ObjectValue}; use js::jsval::{NullValue, ObjectValue};
use js::JSPROP_ENUMERATE; use js::JSPROP_ENUMERATE;
use collections::hashmap::HashSet;
use std::cast; use std::cast;
use std::comm::SharedChan; use std::cmp;
use std::comm::Chan;
use std::comm::Select; use std::comm::Select;
use std::hashmap::HashSet; use std::hash::{Hash, sip};
use std::io::timer::Timer; use std::io::timer::Timer;
use std::num;
use std::rc::Rc; use std::rc::Rc;
use std::to_bytes::Cb;
use extra::serialize::{Encoder, Encodable}; use serialize::{Encoder, Encodable};
use extra::url::{Url}; use extra::url::{Url};
pub enum TimerControlMsg { pub enum TimerControlMsg {
@ -53,9 +53,9 @@ impl<S: Encoder> Encodable<S> for TimerHandle {
} }
} }
impl IterBytes for TimerHandle { impl Hash for TimerHandle {
fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool { fn hash(&self, state: &mut sip::SipState) {
self.handle.iter_bytes(lsb0, f) self.handle.hash(state);
} }
} }
@ -87,7 +87,7 @@ pub struct Window {
struct Untraceable { struct Untraceable {
page: Rc<Page>, page: Rc<Page>,
compositor: ~ScriptListener, compositor: ~ScriptListener,
timer_chan: SharedChan<TimerControlMsg>, timer_chan: Chan<TimerControlMsg>,
} }
impl<S: Encoder> Encodable<S> for Untraceable { impl<S: Encoder> Encodable<S> for Untraceable {
@ -134,7 +134,7 @@ pub struct TimerData {
impl Window { impl Window {
pub fn Alert(&self, s: DOMString) { pub fn Alert(&self, s: DOMString) {
// Right now, just print to the console // Right now, just print to the console
println(format!("ALERT: {:s}", s)); println!("ALERT: {:s}", s);
} }
pub fn Close(&self) { pub fn Close(&self) {
@ -226,7 +226,7 @@ impl Reflectable for Window {
impl Window { impl Window {
pub fn SetTimeout(&mut self, _cx: *JSContext, callback: JSVal, timeout: i32) -> i32 { pub fn SetTimeout(&mut self, _cx: *JSContext, callback: JSVal, timeout: i32) -> i32 {
let timeout = num::max(0, timeout) as u64; let timeout = cmp::max(0, timeout) as u64;
let handle = self.next_timer_handle; let handle = self.next_timer_handle;
self.next_timer_handle += 1; self.next_timer_handle += 1;
@ -241,10 +241,12 @@ impl Window {
let mut cancel_port = cancel_port; let mut cancel_port = cancel_port;
let select = Select::new(); let select = Select::new();
let timeout_handle = select.add(&mut timeout_port); let mut timeout_handle = select.handle(&timeout_port);
let _cancel_handle = select.add(&mut cancel_port); unsafe { timeout_handle.add() };
let mut _cancel_handle = select.handle(&cancel_port);
unsafe { _cancel_handle.add() };
let id = select.wait(); let id = select.wait();
if id == timeout_handle.id { if id == timeout_handle.id() {
chan.send(TimerMessage_Fire(~TimerData { chan.send(TimerMessage_Fire(~TimerData {
handle: handle, handle: handle,
funval: callback, funval: callback,
@ -290,9 +292,10 @@ impl Window {
compositor: compositor, compositor: compositor,
page: page.clone(), page: page.clone(),
timer_chan: { timer_chan: {
let (timer_port, timer_chan): (Port<TimerControlMsg>, SharedChan<TimerControlMsg>) = SharedChan::new(); let (timer_port, timer_chan): (Port<TimerControlMsg>, Chan<TimerControlMsg>) = Chan::new();
let id = page.borrow().id.clone(); let id = page.borrow().id.clone();
spawn_named("timer controller", proc() { spawn_named("timer controller", proc() {
let ScriptChan(script_chan) = script_chan;
loop { loop {
match timer_port.recv() { match timer_port.recv() {
TimerMessage_Close => break, TimerMessage_Close => break,

View file

@ -34,10 +34,11 @@ pub fn spawn_css_parser(provenance: StylesheetProvenance,
resource_task.send(Load(url, input_chan)); resource_task.send(Load(url, input_chan));
let LoadResponse { metadata: metadata, progress_port: progress_port } let LoadResponse { metadata: metadata, progress_port: progress_port }
= input_port.recv(); = input_port.recv();
let final_url = &metadata.final_url;
let protocol_encoding_label = metadata.charset.as_ref().map(|s| s.as_slice()); let protocol_encoding_label = metadata.charset.as_ref().map(|s| s.as_slice());
let iter = ProgressMsgPortIterator { progress_port: progress_port }; let iter = ProgressMsgPortIterator { progress_port: progress_port };
Stylesheet::from_bytes_iter( Stylesheet::from_bytes_iter(
iter, metadata.final_url, iter, final_url.clone(),
protocol_encoding_label, Some(environment_encoding)) protocol_encoding_label, Some(environment_encoding))
} }
InlineProvenance(base_url, data) => { InlineProvenance(base_url, data) => {

View file

@ -28,7 +28,7 @@ use servo_util::url::parse_url;
use std::ascii::StrAsciiExt; use std::ascii::StrAsciiExt;
use std::cast; use std::cast;
use std::cell::RefCell; use std::cell::RefCell;
use std::comm::{Port, SharedChan}; use std::comm::{Port, Chan};
use std::str; use std::str;
use style::Stylesheet; use style::Stylesheet;
@ -103,7 +103,7 @@ spawned, collates them, and sends them to the given result channel.
* `from_parent` - A port on which to receive new links. * `from_parent` - A port on which to receive new links.
*/ */
fn css_link_listener(to_parent: SharedChan<HtmlDiscoveryMessage>, fn css_link_listener(to_parent: Chan<HtmlDiscoveryMessage>,
from_parent: Port<CSSMessage>, from_parent: Port<CSSMessage>,
resource_task: ResourceTask) { resource_task: ResourceTask) {
let mut result_vec = ~[]; let mut result_vec = ~[];
@ -126,7 +126,7 @@ fn css_link_listener(to_parent: SharedChan<HtmlDiscoveryMessage>,
} }
} }
fn js_script_listener(to_parent: SharedChan<HtmlDiscoveryMessage>, fn js_script_listener(to_parent: Chan<HtmlDiscoveryMessage>,
from_parent: Port<JSMessage>, from_parent: Port<JSMessage>,
resource_task: ResourceTask) { resource_task: ResourceTask) {
let mut result_vec = ~[]; let mut result_vec = ~[];
@ -140,7 +140,7 @@ fn js_script_listener(to_parent: SharedChan<HtmlDiscoveryMessage>,
} }
Ok((metadata, bytes)) => { Ok((metadata, bytes)) => {
result_vec.push(JSFile { result_vec.push(JSFile {
data: str::from_utf8(bytes).to_owned(), data: str::from_utf8(bytes).unwrap().to_owned(),
url: metadata.final_url, url: metadata.final_url,
}); });
} }
@ -256,9 +256,9 @@ pub fn parse_html(page: &Page,
// Spawn a CSS parser to receive links to CSS style sheets. // Spawn a CSS parser to receive links to CSS style sheets.
let resource_task2 = resource_task.clone(); let resource_task2 = resource_task.clone();
let (discovery_port, discovery_chan) = SharedChan::new(); let (discovery_port, discovery_chan) = Chan::new();
let stylesheet_chan = discovery_chan.clone(); let stylesheet_chan = discovery_chan.clone();
let (css_msg_port, css_chan) = SharedChan::new(); let (css_msg_port, css_chan) = Chan::new();
spawn_named("parse_html:css", proc() { spawn_named("parse_html:css", proc() {
css_link_listener(stylesheet_chan, css_msg_port, resource_task2.clone()); css_link_listener(stylesheet_chan, css_msg_port, resource_task2.clone());
}); });
@ -266,7 +266,7 @@ pub fn parse_html(page: &Page,
// Spawn a JS parser to receive JavaScript. // Spawn a JS parser to receive JavaScript.
let resource_task2 = resource_task.clone(); let resource_task2 = resource_task.clone();
let js_result_chan = discovery_chan.clone(); let js_result_chan = discovery_chan.clone();
let (js_msg_port, js_chan) = SharedChan::new(); let (js_msg_port, js_chan) = Chan::new();
spawn_named("parse_html:js", proc() { spawn_named("parse_html:js", proc() {
js_script_listener(js_result_chan, js_msg_port, resource_task2.clone()); js_script_listener(js_result_chan, js_msg_port, resource_task2.clone());
}); });
@ -303,11 +303,16 @@ pub fn parse_html(page: &Page,
let next_subpage_id = RefCell::new(next_subpage_id); let next_subpage_id = RefCell::new(next_subpage_id);
let doc_cell = RefCell::new(document);
let tree_handler = hubbub::TreeHandler { let tree_handler = hubbub::TreeHandler {
create_comment: |data: ~str| { create_comment: |data: ~str| {
debug!("create comment"); debug!("create comment");
let comment: JS<Node> = NodeCast::from(&Comment::new(data, document)); // NOTE: tmp vars are workaround for lifetime issues. Both required.
unsafe { comment.to_hubbub_node() } let tmp_borrow = doc_cell.borrow();
let tmp = tmp_borrow.get();
let comment: JS<Node> = NodeCast::from(&Comment::new(data, *tmp));
unsafe { comment.to_hubbub_node() }
}, },
create_doctype: |doctype: ~hubbub::Doctype| { create_doctype: |doctype: ~hubbub::Doctype| {
debug!("create doctype"); debug!("create doctype");
@ -315,14 +320,20 @@ pub fn parse_html(page: &Page,
public_id: public_id, public_id: public_id,
system_id: system_id, system_id: system_id,
force_quirks: _ } = doctype; force_quirks: _ } = doctype;
let doctype_node = DocumentType::new(name, public_id, system_id, document); // NOTE: tmp vars are workaround for lifetime issues. Both required.
let tmp_borrow = doc_cell.borrow();
let tmp = tmp_borrow.get();
let doctype_node = DocumentType::new(name, public_id, system_id, *tmp);
unsafe { unsafe {
doctype_node.to_hubbub_node() doctype_node.to_hubbub_node()
} }
}, },
create_element: |tag: ~hubbub::Tag| { create_element: |tag: ~hubbub::Tag| {
debug!("create element"); debug!("create element");
let mut element = build_element_from_tag(tag.name.clone(), document); // NOTE: tmp vars are workaround for lifetime issues. Both required.
let tmp_borrow = doc_cell.borrow();
let tmp = tmp_borrow.get();
let mut element = build_element_from_tag(tag.name.clone(), *tmp);
debug!("-- attach attrs"); debug!("-- attach attrs");
for attr in tag.attributes.iter() { for attr in tag.attributes.iter() {
@ -366,7 +377,8 @@ pub fn parse_html(page: &Page,
// Subpage Id // Subpage Id
let subpage_id = next_subpage_id.get(); let subpage_id = next_subpage_id.get();
next_subpage_id.set(SubpageId(*subpage_id + 1)); let SubpageId(id_num) = subpage_id;
next_subpage_id.set(SubpageId(id_num + 1));
iframe_element.get_mut().size = Some(IFrameSize { iframe_element.get_mut().size = Some(IFrameSize {
pipeline_id: pipeline_id, pipeline_id: pipeline_id,
@ -384,7 +396,10 @@ pub fn parse_html(page: &Page,
}, },
create_text: |data: ~str| { create_text: |data: ~str| {
debug!("create text"); debug!("create text");
let text = Text::new(data, document); // NOTE: tmp vars are workaround for lifetime issues. Both required.
let tmp_borrow = doc_cell.borrow();
let tmp = tmp_borrow.get();
let text = Text::new(data, *tmp);
unsafe { text.to_hubbub_node() } unsafe { text.to_hubbub_node() }
}, },
ref_node: |_| {}, ref_node: |_| {},
@ -431,11 +446,17 @@ pub fn parse_html(page: &Page,
}, },
set_quirks_mode: |mode| { set_quirks_mode: |mode| {
debug!("set quirks mode"); debug!("set quirks mode");
document.get_mut().set_quirks_mode(mode); // NOTE: tmp vars are workaround for lifetime issues. Both required.
let mut tmp_borrow = doc_cell.borrow_mut();
let mut tmp = tmp_borrow.get();
tmp.get_mut().set_quirks_mode(mode);
}, },
encoding_change: |encname| { encoding_change: |encname| {
debug!("encoding change"); debug!("encoding change");
document.get_mut().set_encoding_name(encname); // NOTE: tmp vars are workaround for lifetime issues. Both required.
let mut tmp_borrow = doc_cell.borrow_mut();
let mut tmp = tmp_borrow.get();
tmp.get_mut().set_encoding_name(encname);
}, },
complete_script: |script| { complete_script: |script| {
unsafe { unsafe {

View file

@ -15,7 +15,7 @@ use geom::size::Size2D;
use script_task::{ScriptChan}; use script_task::{ScriptChan};
use servo_util::geometry::Au; use servo_util::geometry::Au;
use std::cmp; use std::cmp;
use std::comm::{Chan, SharedChan}; use std::comm::Chan;
use std::libc::c_void; use std::libc::c_void;
use style::Stylesheet; use style::Stylesheet;
@ -132,11 +132,11 @@ pub struct Reflow {
/// Encapsulates a channel to the layout task. /// Encapsulates a channel to the layout task.
#[deriving(Clone)] #[deriving(Clone)]
pub struct LayoutChan(SharedChan<Msg>); pub struct LayoutChan(Chan<Msg>);
impl LayoutChan { impl LayoutChan {
pub fn new() -> (Port<Msg>, LayoutChan) { pub fn new() -> (Port<Msg>, LayoutChan) {
let (port, chan) = SharedChan::new(); let (port, chan) = Chan::new();
(port, LayoutChan(chan)) (port, LayoutChan(chan))
} }
} }

View file

@ -9,12 +9,14 @@ macro_rules! bitfield(
impl $bitfieldname { impl $bitfieldname {
#[inline] #[inline]
pub fn $getter(self) -> bool { pub fn $getter(self) -> bool {
(*self & $value) != 0 let $bitfieldname(s) = self;
(s & $value) != 0
} }
#[inline] #[inline]
pub fn $setter(&mut self, value: bool) { pub fn $setter(&mut self, value: bool) {
*self = $bitfieldname((**self & !$value) | (if value { $value } else { 0 })) let $bitfieldname(s) = *self;
*self = $bitfieldname((s & !$value) | (if value { $value } else { 0 }))
} }
} }
) )

View file

@ -10,16 +10,18 @@
#[feature(globs, macro_rules, struct_variant, managed_boxes)]; #[feature(globs, macro_rules, struct_variant, managed_boxes)];
extern mod geom; extern crate collections;
extern mod hubbub; extern crate geom;
extern mod encoding; extern crate hubbub;
extern mod js; extern crate encoding;
extern mod servo_net = "net"; extern crate js;
extern mod servo_util = "util"; extern crate serialize;
extern mod style; extern crate servo_net = "net";
extern mod servo_msg = "msg"; extern crate servo_util = "util";
extern mod extra; extern crate style;
extern mod native; extern crate servo_msg = "msg";
extern crate extra;
extern crate native;
// Macros // Macros
mod macros; mod macros;

View file

@ -50,13 +50,13 @@ use servo_util::task::send_on_failure;
use servo_util::namespace::Null; use servo_util::namespace::Null;
use std::cast; use std::cast;
use std::cell::{RefCell, Ref, RefMut}; use std::cell::{RefCell, Ref, RefMut};
use std::comm::{Port, SharedChan}; use std::comm::{Port, Chan, Empty, Disconnected, Data};
use std::mem::replace;
use std::ptr; use std::ptr;
use std::rc::Rc; use std::rc::Rc;
use std::task; use std::task;
use std::util::replace;
use extra::serialize::{Encoder, Encodable}; use serialize::{Encoder, Encodable};
/// Messages used to control the script task. /// Messages used to control the script task.
pub enum ScriptMsg { pub enum ScriptMsg {
@ -90,7 +90,7 @@ pub struct NewLayoutInfo {
/// Encapsulates external communication with the script task. /// Encapsulates external communication with the script task.
#[deriving(Clone)] #[deriving(Clone)]
pub struct ScriptChan(SharedChan<ScriptMsg>); pub struct ScriptChan(Chan<ScriptMsg>);
impl<S: Encoder> Encodable<S> for ScriptChan { impl<S: Encoder> Encodable<S> for ScriptChan {
fn encode(&self, _s: &mut S) { fn encode(&self, _s: &mut S) {
@ -100,7 +100,7 @@ impl<S: Encoder> Encodable<S> for ScriptChan {
impl ScriptChan { impl ScriptChan {
/// Creates a new script chan. /// Creates a new script chan.
pub fn new() -> (Port<ScriptMsg>, ScriptChan) { pub fn new() -> (Port<ScriptMsg>, ScriptChan) {
let (port, chan) = SharedChan::new(); let (port, chan) = Chan::new();
(port, ScriptChan(chan)) (port, ScriptChan(chan))
} }
} }
@ -164,7 +164,7 @@ pub struct PageTreeIterator<'a> {
impl PageTree { impl PageTree {
fn new(id: PipelineId, layout_chan: LayoutChan, window_size: Size2D<uint>) -> PageTree { fn new(id: PipelineId, layout_chan: LayoutChan, window_size: Size2D<uint>) -> PageTree {
PageTree { PageTree {
page: unsafe { Rc::new_unchecked(Page { page: unsafe { Rc::new(Page {
id: id, id: id,
frame: RefCell::new(None), frame: RefCell::new(None),
layout_chan: layout_chan, layout_chan: layout_chan,
@ -220,7 +220,7 @@ impl PageTree {
.map(|(idx, _)| idx) .map(|(idx, _)| idx)
}; };
match remove_idx { match remove_idx {
Some(idx) => return Some(self.inner.remove(idx)), Some(idx) => return Some(self.inner.remove(idx).unwrap()),
None => { None => {
for page_tree in self.inner.mut_iter() { for page_tree in self.inner.mut_iter() {
match page_tree.remove(id) { match page_tree.remove(id) {
@ -237,11 +237,9 @@ impl PageTree {
impl<'a> Iterator<Rc<Page>> for PageTreeIterator<'a> { impl<'a> Iterator<Rc<Page>> for PageTreeIterator<'a> {
fn next(&mut self) -> Option<Rc<Page>> { fn next(&mut self) -> Option<Rc<Page>> {
if !self.stack.is_empty() { if !self.stack.is_empty() {
let next = self.stack.pop(); let mut next = self.stack.pop().unwrap();
{ for child in next.inner.mut_iter() {
for child in next.inner.mut_iter() { self.stack.push(child);
self.stack.push(child);
}
} }
Some(next.page.clone()) Some(next.page.clone())
} else { } else {
@ -307,7 +305,7 @@ impl Page {
pub fn get_url(&self) -> Url { pub fn get_url(&self) -> Url {
let url = self.url(); let url = self.url();
url.get().get_ref().first().clone() url.get().get_ref().ref0().clone()
} }
/// Sends a ping to layout and waits for the response. The response will arrive when the /// Sends a ping to layout and waits for the response. The response will arrive when the
@ -319,11 +317,14 @@ impl Page {
match join_port { match join_port {
Some(ref join_port) => { Some(ref join_port) => {
match join_port.try_recv() { match join_port.try_recv() {
None => { Empty => {
info!("script: waiting on layout"); info!("script: waiting on layout");
join_port.recv(); join_port.recv();
} }
Some(_) => {} Data(_) => {}
Disconnected => {
fail!("Layout task failed while script was waiting for a result.");
}
} }
debug!("script: layout joined") debug!("script: layout joined")
@ -339,7 +340,8 @@ impl Page {
response_port: Port<T>) response_port: Port<T>)
-> T { -> T {
self.join_layout(); self.join_layout();
self.layout_chan.send(QueryMsg(query)); let LayoutChan(ref chan) = self.layout_chan;
chan.send(QueryMsg(query));
response_port.recv() response_port.recv()
} }
@ -397,7 +399,8 @@ impl Page {
id: *last_reflow_id.get(), id: *last_reflow_id.get(),
}; };
self.layout_chan.send(ReflowMsg(reflow)); let LayoutChan(ref chan) = self.layout_chan;
chan.send(ReflowMsg(reflow));
debug!("script: layout forked") debug!("script: layout forked")
} }
@ -494,7 +497,7 @@ impl ScriptTask {
let js_runtime = js::rust::rt(); let js_runtime = js::rust::rt();
unsafe { unsafe {
Rc::new_unchecked(ScriptTask { Rc::new(ScriptTask {
page_tree: RefCell::new(PageTree::new(id, layout_chan, window_size)), page_tree: RefCell::new(PageTree::new(id, layout_chan, window_size)),
image_cache_task: img_cache_task, image_cache_task: img_cache_task,
@ -530,9 +533,9 @@ impl ScriptTask {
resource_task: ResourceTask, resource_task: ResourceTask,
image_cache_task: ImageCacheTask, image_cache_task: ImageCacheTask,
window_size: Size2D<uint>) { window_size: Size2D<uint>) {
let mut builder = task::task(); let mut builder = task::task().named("ScriptTask");
send_on_failure(&mut builder, FailureMsg(failure_msg), (*constellation_chan).clone()); let ConstellationChan(const_chan) = constellation_chan.clone();
builder.name("ScriptTask"); send_on_failure(&mut builder, FailureMsg(failure_msg), const_chan);
builder.spawn(proc() { builder.spawn(proc() {
let script_task = ScriptTask::new(id, let script_task = ScriptTask::new(id,
compositor as ~ScriptListener, compositor as ~ScriptListener,
@ -593,8 +596,8 @@ impl ScriptTask {
} }
match self.port.try_recv() { match self.port.try_recv() {
None => break, Empty | Disconnected => break,
Some(ev) => event = ev, Data(ev) => event = ev,
} }
} }
@ -683,7 +686,8 @@ impl ScriptTask {
/// Handles a navigate forward or backward message. /// Handles a navigate forward or backward message.
/// TODO(tkuehn): is it ever possible to navigate only on a subframe? /// TODO(tkuehn): is it ever possible to navigate only on a subframe?
fn handle_navigate_msg(&self, direction: NavigationDirection) { fn handle_navigate_msg(&self, direction: NavigationDirection) {
self.constellation_chan.send(constellation_msg::NavigateMsg(direction)); let ConstellationChan(ref chan) = self.constellation_chan;
chan.send(constellation_msg::NavigateMsg(direction));
} }
/// Window was resized, but this script was not active, so don't reflow yet /// Window was resized, but this script was not active, so don't reflow yet
@ -696,7 +700,7 @@ impl ScriptTask {
let mut page_url = page.mut_url(); let mut page_url = page.mut_url();
let last_loaded_url = replace(page_url.get(), None); let last_loaded_url = replace(page_url.get(), None);
for url in last_loaded_url.iter() { for url in last_loaded_url.iter() {
*page_url.get() = Some((url.first(), true)); *page_url.get() = Some((url.ref0().clone(), true));
} }
} }
@ -823,19 +827,22 @@ impl ScriptTask {
js_scripts = Some(scripts); js_scripts = Some(scripts);
} }
Some(HtmlDiscoveredStyle(sheet)) => { Some(HtmlDiscoveredStyle(sheet)) => {
page.layout_chan.send(AddStylesheetMsg(sheet)); let LayoutChan(ref chan) = page.layout_chan;
chan.send(AddStylesheetMsg(sheet));
} }
Some(HtmlDiscoveredIFrame((iframe_url, subpage_id, sandboxed))) => { Some(HtmlDiscoveredIFrame((iframe_url, subpage_id, sandboxed))) => {
page.next_subpage_id.set(SubpageId(*subpage_id + 1)); let SubpageId(num) = subpage_id;
page.next_subpage_id.set(SubpageId(num + 1));
let sandboxed = if sandboxed { let sandboxed = if sandboxed {
IFrameSandboxed IFrameSandboxed
} else { } else {
IFrameUnsandboxed IFrameUnsandboxed
}; };
self.constellation_chan.send(LoadIframeUrlMsg(iframe_url, let ConstellationChan(ref chan) = self.constellation_chan;
pipeline_id, chan.send(LoadIframeUrlMsg(iframe_url,
subpage_id, pipeline_id,
sandboxed)); subpage_id,
sandboxed));
} }
None => break None => break
} }
@ -893,9 +900,10 @@ impl ScriptTask {
wintarget.get_mut().dispatch_event_with_target(&winclone, Some(doctarget), &mut event); wintarget.get_mut().dispatch_event_with_target(&winclone, Some(doctarget), &mut event);
let mut fragment_node = page.fragment_node.borrow_mut(); let mut fragment_node = page.fragment_node.borrow_mut();
*fragment_node.get() = fragment.map_default(None, |fragid| self.find_fragment_node(page, fragid)); *fragment_node.get() = fragment.map_or(None, |fragid| self.find_fragment_node(page, fragid));
self.constellation_chan.send(LoadCompleteMsg(page.id, url)); let ConstellationChan(ref chan) = self.constellation_chan;
chan.send(LoadCompleteMsg(page.id, url));
} }
fn find_fragment_node(&self, page: &Page, fragid: ~str) -> Option<JS<Element>> { fn find_fragment_node(&self, page: &Page, fragid: ~str) -> Option<JS<Element>> {
@ -908,7 +916,7 @@ impl ScriptTask {
let mut anchors = doc_node.traverse_preorder().filter(|node| node.is_anchor_element()); let mut anchors = doc_node.traverse_preorder().filter(|node| node.is_anchor_element());
anchors.find(|node| { anchors.find(|node| {
let elem: JS<Element> = ElementCast::to(node); let elem: JS<Element> = ElementCast::to(node);
elem.get().get_attribute(Null, "name").map_default(false, |attr| { elem.get().get_attribute(Null, "name").map_or(false, |attr| {
attr.get().value_ref() == fragid attr.get().value_ref() == fragid
}) })
}).map(|node| ElementCast::to(&node)) }).map(|node| ElementCast::to(&node))
@ -1121,7 +1129,8 @@ impl ScriptTask {
None => {} None => {}
} }
} else { } else {
self.constellation_chan.send(LoadUrlMsg(page.id, url)); let ConstellationChan(ref chan) = self.constellation_chan;
chan.send(LoadUrlMsg(page.id, url));
} }
} }
} }
@ -1133,7 +1142,8 @@ fn shut_down_layout(page: &Page) {
// Tell the layout task to begin shutting down. // Tell the layout task to begin shutting down.
let (response_port, response_chan) = Chan::new(); let (response_port, response_chan) = Chan::new();
page.layout_chan.send(layout_interface::PrepareToExitMsg(response_chan)); let LayoutChan(ref chan) = page.layout_chan;
chan.send(layout_interface::PrepareToExitMsg(response_chan));
response_port.recv(); response_port.recv();
// Destroy all nodes. Setting frame and js_info to None will trigger our // Destroy all nodes. Setting frame and js_info to None will trigger our
@ -1149,5 +1159,5 @@ fn shut_down_layout(page: &Page) {
*js_info.get() = None; *js_info.get() = None;
// Destroy the layout task. If there were node leaks, layout will now crash safely. // Destroy the layout task. If there were node leaks, layout will now crash safely.
page.layout_chan.send(layout_interface::ExitNowMsg); chan.send(layout_interface::ExitNowMsg);
} }

View file

@ -10,14 +10,16 @@ pub struct ErrorLoggerIterator<I>(I);
impl<T, I: Iterator<Result<T, SyntaxError>>> Iterator<T> for ErrorLoggerIterator<I> { impl<T, I: Iterator<Result<T, SyntaxError>>> Iterator<T> for ErrorLoggerIterator<I> {
fn next(&mut self) -> Option<T> { fn next(&mut self) -> Option<T> {
for result in **self { let ErrorLoggerIterator(ref mut this) = *self;
match result { while true {
Ok(v) => return Some(v), match this.next() {
Err(error) => log_css_error(error.location, format!("{:?}", error.reason)) Some(Ok(v)) => return Some(v),
Some(Err(error)) => log_css_error(error.location, format!("{:?}", error.reason)),
None => return None,
} }
} }
None None
} }
} }

View file

@ -2,8 +2,8 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use std::hashmap::HashMap;
use cssparser::ast::*; use cssparser::ast::*;
use collections::hashmap::HashMap;
use servo_util::namespace::Namespace; use servo_util::namespace::Namespace;
use errors::log_css_error; use errors::log_css_error;

View file

@ -4,9 +4,10 @@
// This file is a Mako template: http://www.makotemplates.org/ // This file is a Mako template: http://www.makotemplates.org/
use std::ascii;
use std::ascii::StrAsciiExt; use std::ascii::StrAsciiExt;
pub use servo_util::url::parse_url; pub use servo_util::url::parse_url;
pub use extra::arc::Arc; use sync::Arc;
pub use extra::url::Url; pub use extra::url::Url;
use servo_util::cowarc::CowArc; use servo_util::cowarc::CowArc;
@ -18,7 +19,7 @@ pub use parsing_utils::*;
pub use self::common_types::*; pub use self::common_types::*;
use selector_matching::MatchedProperty; use selector_matching::MatchedProperty;
use extra::serialize::{Encodable, Encoder}; use serialize::{Encodable, Encoder};
pub mod common_types; pub mod common_types;
@ -218,12 +219,15 @@ pub mod longhands {
match component_value { match component_value {
&Ident(ref value) => { &Ident(ref value) => {
// FIXME: Workaround for https://github.com/mozilla/rust/issues/10683 // FIXME: Workaround for https://github.com/mozilla/rust/issues/10683
let value_lower = value.to_ascii_lower(); unsafe {
match value_lower.as_slice() { let tmp_for_lifetime = value.to_ascii_nocheck().to_lower();
"thin" => Some(specified::Length::from_px(1.)), let value_lower = tmp_for_lifetime.as_str_ascii();
"medium" => Some(specified::Length::from_px(3.)), match value_lower.as_slice() {
"thick" => Some(specified::Length::from_px(5.)), "thin" => Some(specified::Length::from_px(1.)),
_ => None "medium" => Some(specified::Length::from_px(3.)),
"thick" => Some(specified::Length::from_px(5.)),
_ => None
}
} }
}, },
_ => specified::Length::parse_non_negative(component_value) _ => specified::Length::parse_non_negative(component_value)
@ -335,7 +339,7 @@ pub mod longhands {
&Dimension(ref value, ref unit) if value.value >= 0. &Dimension(ref value, ref unit) if value.value >= 0.
=> specified::Length::parse_dimension(value.value, unit.as_slice()) => specified::Length::parse_dimension(value.value, unit.as_slice())
.map(SpecifiedLength), .map(SpecifiedLength),
&Ident(ref value) if value.eq_ignore_ascii_case("normal") &Ident(ref value) if unsafe { value.to_ascii_nocheck().to_lower().eq_ignore_case("normal".to_ascii_nocheck())}
=> Some(SpecifiedNormal), => Some(SpecifiedNormal),
_ => None, _ => None,
} }
@ -381,12 +385,15 @@ pub mod longhands {
match input { match input {
&Ident(ref value) => { &Ident(ref value) => {
// FIXME: Workaround for https://github.com/mozilla/rust/issues/10683 // FIXME: Workaround for https://github.com/mozilla/rust/issues/10683
let value_lower = value.to_ascii_lower(); unsafe {
match value_lower.as_slice() { let tmp_for_lifetime = value.to_ascii_nocheck().to_lower();
% for keyword in vertical_align_keywords: let value_lower = tmp_for_lifetime.as_str_ascii();
"${keyword}" => Some(Specified_${to_rust_ident(keyword)}), match value_lower.as_slice() {
% endfor % for keyword in vertical_align_keywords:
_ => None, "${keyword}" => Some(Specified_${to_rust_ident(keyword)}),
% endfor
_ => None,
}
} }
}, },
_ => specified::LengthOrPercentage::parse_non_negative(input) _ => specified::LengthOrPercentage::parse_non_negative(input)
@ -456,10 +463,17 @@ pub mod longhands {
// TODO: <uri>, <counter>, attr(<identifier>), open-quote, close-quote, no-open-quote, no-close-quote // TODO: <uri>, <counter>, attr(<identifier>), open-quote, close-quote, no-open-quote, no-close-quote
pub fn parse(input: &[ComponentValue], _base_url: &Url) -> Option<SpecifiedValue> { pub fn parse(input: &[ComponentValue], _base_url: &Url) -> Option<SpecifiedValue> {
match one_component_value(input) { match one_component_value(input) {
Some(&Ident(ref keyword)) => match keyword.to_ascii_lower().as_slice() { Some(&Ident(ref keyword)) => {
"normal" => return Some(normal), unsafe {
"none" => return Some(none), let tmp_for_lifetime = keyword.to_ascii_nocheck().to_lower();
_ => () let keyword_lower = tmp_for_lifetime.as_str_ascii();
match keyword_lower.as_slice() {
"normal" => return Some(normal),
"none" => return Some(none),
_ => ()
}
}
}, },
_ => () _ => ()
} }
@ -557,12 +571,12 @@ pub mod longhands {
pub fn from_iter<'a>(mut iter: SkipWhitespaceIterator<'a>) -> Option<SpecifiedValue> { pub fn from_iter<'a>(mut iter: SkipWhitespaceIterator<'a>) -> Option<SpecifiedValue> {
let mut result = ~[]; let mut result = ~[];
macro_rules! add( macro_rules! add(
($value: expr) => { ($value: expr, $b: expr) => {
{ {
result.push($value); result.push($value);
match iter.next() { match iter.next() {
Some(&Comma) => (), Some(&Comma) => (),
None => break 'outer, None => $b,
_ => return None, _ => return None,
} }
} }
@ -571,17 +585,19 @@ pub mod longhands {
'outer: loop { 'outer: loop {
match iter.next() { match iter.next() {
// TODO: avoid copying strings? // TODO: avoid copying strings?
Some(&String(ref value)) => add!(FamilyName(value.to_owned())), Some(&String(ref value)) => add!(FamilyName(value.to_owned()), break 'outer),
Some(&Ident(ref value)) => { Some(&Ident(ref value)) => {
// FIXME: Workaround for https://github.com/mozilla/rust/issues/10683 // FIXME: Workaround for https://github.com/mozilla/rust/issues/10683
let value = value.as_slice(); let value = value.as_slice();
let value_lower = value.to_ascii_lower(); unsafe {
let tmp_for_lifetime = value.to_ascii_nocheck().to_lower();
let value_lower = tmp_for_lifetime.as_str_ascii();
match value_lower.as_slice() { match value_lower.as_slice() {
// "serif" => add!(Serif), // "serif" => add!(Serif, break 'outer),
// "sans-serif" => add!(SansSerif), // "sans-serif" => add!(SansSerif, break 'outer),
// "cursive" => add!(Cursive), // "cursive" => add!(Cursive, break 'outer),
// "fantasy" => add!(Fantasy), // "fantasy" => add!(Fantasy, break 'outer),
// "monospace" => add!(Monospace), // "monospace" => add!(Monospace, break 'outer),
_ => { _ => {
let mut idents = ~[value]; let mut idents = ~[value];
loop { loop {
@ -599,7 +615,7 @@ pub mod longhands {
} }
} }
} }
} }}
} }
_ => return None, _ => return None,
} }
@ -627,13 +643,16 @@ pub mod longhands {
match input { match input {
&Ident(ref value) => { &Ident(ref value) => {
// FIXME: Workaround for https://github.com/mozilla/rust/issues/10683 // FIXME: Workaround for https://github.com/mozilla/rust/issues/10683
let value_lower = value.to_ascii_lower(); unsafe {
match value_lower.as_slice() { let tmp_for_lifetime = value.to_ascii_nocheck().to_lower();
"bold" => Some(SpecifiedWeight700), let value_lower = tmp_for_lifetime.as_str_ascii();
"normal" => Some(SpecifiedWeight400), match value_lower.as_slice() {
"bolder" => Some(Bolder), "bold" => Some(SpecifiedWeight700),
"lighter" => Some(Lighter), "normal" => Some(SpecifiedWeight400),
_ => None, "bolder" => Some(Bolder),
"lighter" => Some(Lighter),
_ => None,
}
} }
}, },
&Number(ref value) => match value.int_value { &Number(ref value) => match value.int_value {
@ -805,7 +824,7 @@ pub mod shorthands {
%> %>
pub mod ${shorthand.ident} { pub mod ${shorthand.ident} {
use super::*; use super::*;
struct Longhands { pub struct Longhands {
% for sub_property in shorthand.sub_properties: % for sub_property in shorthand.sub_properties:
${sub_property.ident}: Option<${sub_property.ident}::SpecifiedValue>, ${sub_property.ident}: Option<${sub_property.ident}::SpecifiedValue>,
% endfor % endfor
@ -958,7 +977,7 @@ pub mod shorthands {
// font-style, font-weight and font-variant. // font-style, font-weight and font-variant.
// Leaves the values to None, 'normal' is the initial value for each of them. // Leaves the values to None, 'normal' is the initial value for each of them.
if get_ident_lower(component_value).filtered( if get_ident_lower(component_value).filtered(
|v| v.eq_ignore_ascii_case("normal")).is_some() { |v| unsafe { v.to_ascii_nocheck() }.to_lower().eq_ignore_case(unsafe {"normal".to_ascii_nocheck()})).is_some() {
nb_normals += 1; nb_normals += 1;
continue; continue;
} }

View file

@ -2,10 +2,12 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use extra::arc::Arc; use collections::hashmap::HashMap;
use std::ascii::StrAsciiExt; use std::ascii::StrAsciiExt;
use std::hashmap::HashMap; use std::hash::Hash;
use std::to_bytes; use std::hash::sip::SipState;
use num::div_rem;
use sync::Arc;
use servo_util::namespace; use servo_util::namespace;
use servo_util::smallvec::SmallVec; use servo_util::smallvec::SmallVec;
@ -38,22 +40,21 @@ impl<'a> Equiv<DOMString> for LowercaseAsciiString<'a> {
} }
} }
impl<'a> IterBytes for LowercaseAsciiString<'a> { impl<'a> Hash for LowercaseAsciiString<'a> {
#[inline] #[inline]
fn iter_bytes(&self, _: bool, f: to_bytes::Cb) -> bool { fn hash(&self, state: &mut SipState) {
for b in self.bytes() { let LowercaseAsciiString(this) = *self;
for b in this.bytes() {
// FIXME(pcwalton): This is a nasty hack for performance. We temporarily violate the // FIXME(pcwalton): This is a nasty hack for performance. We temporarily violate the
// `Ascii` type's invariants by using `to_ascii_nocheck`, but it's OK as we simply // `Ascii` type's invariants by using `to_ascii_nocheck`, but it's OK as we simply
// convert to a byte afterward. // convert to a byte afterward.
unsafe { unsafe {
if !f([ b.to_ascii_nocheck().to_lower().to_byte() ]) { state.write_u8(b.to_ascii_nocheck().to_lower().to_byte())
return false };
}
}
} }
// Terminate the string with a non-UTF-8 character, to match what the built-in string // Terminate the string with a non-UTF-8 character, to match what the built-in string
// `ToBytes` implementation does. (See `libstd/to_bytes.rs`.) // `ToBytes` implementation does. (See `libstd/to_bytes.rs`.)
f([ 0xff ]) state.write_u8(0xff);
} }
} }
@ -338,6 +339,7 @@ impl Stylist {
&mut self.after_map.user, &mut self.after_map.user,
), ),
}; };
let mut rules_source_order = self.rules_source_order;
// Take apart the StyleRule into individual Rules and insert // Take apart the StyleRule into individual Rules and insert
// them into the SelectorMap of that priority. // them into the SelectorMap of that priority.
@ -355,7 +357,7 @@ impl Stylist {
property: MatchedProperty { property: MatchedProperty {
specificity: selector.specificity, specificity: selector.specificity,
declarations: style_rule.declarations.$priority.clone(), declarations: style_rule.declarations.$priority.clone(),
source_order: self.rules_source_order, source_order: rules_source_order,
}, },
}); });
} }
@ -367,8 +369,9 @@ impl Stylist {
iter_style_rules(stylesheet.rules.as_slice(), device, |style_rule| { iter_style_rules(stylesheet.rules.as_slice(), device, |style_rule| {
append!(normal); append!(normal);
append!(important); append!(important);
self.rules_source_order += 1; rules_source_order += 1;
}); });
self.rules_source_order = rules_source_order;
} }
/// Returns the applicable CSS declarations for the given element. This corresponds to /// Returns the applicable CSS declarations for the given element. This corresponds to
@ -596,7 +599,7 @@ fn matches_simple_selector<E:TElement,
*shareable = false; *shareable = false;
element.with_element(|element: &E| { element.with_element(|element: &E| {
element.get_attr(&namespace::Null, "id") element.get_attr(&namespace::Null, "id")
.map_default(false, |attr| { .map_or(false, |attr| {
attr == *id attr == *id
}) })
}) })
@ -605,7 +608,7 @@ fn matches_simple_selector<E:TElement,
ClassSelector(ref class) => { ClassSelector(ref class) => {
element.with_element(|element: &E| { element.with_element(|element: &E| {
element.get_attr(&namespace::Null, "class") element.get_attr(&namespace::Null, "class")
.map_default(false, |attr| { .map_or(false, |attr| {
// TODO: case-sensitivity depends on the document type and quirks mode // TODO: case-sensitivity depends on the document type and quirks mode
attr.split(SELECTOR_WHITESPACE).any(|c| c == class.as_slice()) attr.split(SELECTOR_WHITESPACE).any(|c| c == class.as_slice())
}) })
@ -807,7 +810,7 @@ fn matches_generic_nth_child<'a,
return b == index; return b == index;
} }
let (n, r) = (index - b).div_rem(&a); let (n, r) = div_rem(index - b, a);
n >= 0 && r == 0 n >= 0 && r == 0
} }

View file

@ -2,9 +2,9 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use std::{vec, iter}; use std::{cmp, vec, iter};
use std::ascii::StrAsciiExt; use std::ascii::StrAsciiExt;
use extra::arc::Arc; use sync::Arc;
use cssparser::ast::*; use cssparser::ast::*;
use cssparser::parse_nth; use cssparser::parse_nth;
@ -103,7 +103,7 @@ pub enum NamespaceConstraint {
} }
type Iter = iter::Peekable<ComponentValue, vec::MoveIterator<ComponentValue>>; type Iter = iter::Peekable<ComponentValue, vec::MoveItems<ComponentValue>>;
/// Parse a comma-separated list of Selectors. /// Parse a comma-separated list of Selectors.
@ -231,9 +231,9 @@ fn compute_specificity(mut selector: &CompoundSelector,
} }
static MAX_10BIT: u32 = (1u32 << 10) - 1; static MAX_10BIT: u32 = (1u32 << 10) - 1;
specificity.id_selectors.min(&MAX_10BIT) << 20 cmp::min(specificity.id_selectors, MAX_10BIT) << 20
| specificity.class_like_selectors.min(&MAX_10BIT) << 10 | cmp::min(specificity.class_like_selectors, MAX_10BIT) << 10
| specificity.element_selectors.min(&MAX_10BIT) | cmp::min(specificity.element_selectors, MAX_10BIT)
} }

View file

@ -10,10 +10,14 @@
#[feature(globs, macro_rules, managed_boxes)]; #[feature(globs, macro_rules, managed_boxes)];
extern mod extra; extern crate cssparser;
extern mod cssparser; extern crate collections;
extern mod encoding; extern crate encoding;
extern mod servo_util = "util"; extern crate extra;
extern crate num;
extern crate serialize;
extern crate servo_util = "util";
extern crate sync;
// Public API // Public API

View file

@ -2,10 +2,11 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use std::hashmap::HashMap; use collections::HashMap;
use std::hash::{Hash, sip};
use std::rand::Rng; use std::rand::Rng;
use std::rand; use std::rand;
use std::vec::VecIterator; use std::vec::Items;
use std::vec; use std::vec;
pub trait Cache<K: Eq, V: Clone> { pub trait Cache<K: Eq, V: Clone> {
@ -56,8 +57,8 @@ impl<K: Clone + Eq, V: Clone> Cache<K,V> for MonoCache<K,V> {
#[test] #[test]
fn test_monocache() { fn test_monocache() {
let mut cache = MonoCache::new(10); let mut cache = MonoCache::new(10);
let one = @"one"; let one = ~"one";
let two = @"two"; let two = ~"two";
cache.insert(1, one); cache.insert(1, one);
assert!(cache.find(&1).is_some()); assert!(cache.find(&1).is_some());
@ -103,8 +104,8 @@ impl<K: Clone + Eq + Hash, V: Clone> Cache<K,V> for HashCache<K,V> {
#[test] #[test]
fn test_hashcache() { fn test_hashcache() {
let mut cache = HashCache::new(); let mut cache = HashCache::new();
let one = @"one"; let one = ~"one";
let two = @"two"; let two = ~"two";
cache.insert(1, one); cache.insert(1, one);
assert!(cache.find(&1).is_some()); assert!(cache.find(&1).is_some());
@ -133,12 +134,12 @@ impl<K: Clone + Eq, V: Clone> LRUCache<K,V> {
let last_index = self.entries.len() - 1; let last_index = self.entries.len() - 1;
if pos != last_index { if pos != last_index {
let entry = self.entries.remove(pos); let entry = self.entries.remove(pos);
self.entries.push(entry); self.entries.push(entry.unwrap());
} }
self.entries[last_index].second_ref().clone() self.entries[last_index].ref1().clone()
} }
pub fn iter<'a>(&'a self) -> VecIterator<'a,(K,V)> { pub fn iter<'a>(&'a self) -> Items<'a,(K,V)> {
self.entries.iter() self.entries.iter()
} }
} }
@ -197,7 +198,7 @@ impl<K:Clone+Eq+Hash,V:Clone> SimpleHashCache<K,V> {
#[inline] #[inline]
fn bucket_for_key<Q:Hash>(&self, key: &Q) -> uint { fn bucket_for_key<Q:Hash>(&self, key: &Q) -> uint {
self.to_bucket(key.hash_keyed(self.k0, self.k1) as uint) self.to_bucket(sip::hash_with_keys(self.k0, self.k1, key) as uint)
} }
#[inline] #[inline]
@ -243,10 +244,10 @@ impl<K:Clone+Eq+Hash,V:Clone> Cache<K,V> for SimpleHashCache<K,V> {
#[test] #[test]
fn test_lru_cache() { fn test_lru_cache() {
let one = @"one"; let one = ~"one";
let two = @"two"; let two = ~"two";
let three = @"three"; let three = ~"three";
let four = @"four"; let four = ~"four";
// Test normal insertion. // Test normal insertion.
let mut cache = LRUCache::new(2); // (_, _) (cache is empty) let mut cache = LRUCache::new(2); // (_, _) (cache is empty)

View file

@ -5,12 +5,13 @@
//! A Doug Lea-style concurrent hash map using striped locks. //! A Doug Lea-style concurrent hash map using striped locks.
use std::cast; use std::cast;
use std::hash::{Hash, sip};
use std::ptr; use std::ptr;
use std::rand::Rng; use std::rand::Rng;
use std::rand; use std::rand;
use std::sync::atomics::{AtomicUint, Relaxed, SeqCst}; use std::sync::atomics::{AtomicUint, Relaxed, SeqCst};
use std::unstable::mutex::Mutex; use std::unstable::mutex::StaticNativeMutex;
use std::util; use std::mem;
use std::vec; use std::vec;
/// When the size exceeds (number of buckets * LOAD_NUMERATOR/LOAD_DENOMINATOR), the hash table /// When the size exceeds (number of buckets * LOAD_NUMERATOR/LOAD_DENOMINATOR), the hash table
@ -37,7 +38,7 @@ pub struct ConcurrentHashMap<K,V> {
/// The number of elements in this hash table. /// The number of elements in this hash table.
priv size: AtomicUint, priv size: AtomicUint,
/// The striped locks. /// The striped locks.
priv locks: ~[Mutex], priv locks: ~[StaticNativeMutex],
/// The buckets. /// The buckets.
priv buckets: ~[Option<Bucket<K,V>>], priv buckets: ~[Option<Bucket<K,V>>],
} }
@ -58,7 +59,7 @@ impl<K:Hash + Eq,V> ConcurrentHashMap<K,V> {
size: AtomicUint::new(0), size: AtomicUint::new(0),
locks: vec::from_fn(lock_count, |_| { locks: vec::from_fn(lock_count, |_| {
unsafe { unsafe {
Mutex::new() StaticNativeMutex::new()
} }
}), }),
buckets: vec::from_fn(lock_count * buckets_per_lock, |_| None), buckets: vec::from_fn(lock_count * buckets_per_lock, |_| None),
@ -74,7 +75,7 @@ impl<K:Hash + Eq,V> ConcurrentHashMap<K,V> {
loop { loop {
let (bucket_index, lock_index) = self.bucket_and_lock_indices(&key); let (bucket_index, lock_index) = self.bucket_and_lock_indices(&key);
if this.overloaded() { if this.overloaded() {
this.locks[lock_index].unlock(); this.locks[lock_index].unlock_noguard();
this.try_resize(self.buckets_per_lock() * 2); this.try_resize(self.buckets_per_lock() * 2);
// Have to retry because the bucket and lock indices will have shifted. // Have to retry because the bucket and lock indices will have shifted.
@ -82,7 +83,7 @@ impl<K:Hash + Eq,V> ConcurrentHashMap<K,V> {
} }
this.insert_unlocked(key, value, Some(bucket_index)); this.insert_unlocked(key, value, Some(bucket_index));
this.locks[lock_index].unlock(); this.locks[lock_index].unlock_noguard();
break break
} }
} }
@ -118,7 +119,7 @@ impl<K:Hash + Eq,V> ConcurrentHashMap<K,V> {
match (*bucket).next { match (*bucket).next {
None => {} None => {}
Some(ref mut next_bucket) => { Some(ref mut next_bucket) => {
bucket = ptr::to_mut_unsafe_ptr(&mut **next_bucket); bucket = &mut **next_bucket as *mut Bucket<K,V>;
continue continue
} }
} }
@ -150,7 +151,7 @@ impl<K:Hash + Eq,V> ConcurrentHashMap<K,V> {
Some(ref mut bucket) if bucket.key == *key => { Some(ref mut bucket) if bucket.key == *key => {
// Common case (assuming a sparse table): If the key is the first one in the // Common case (assuming a sparse table): If the key is the first one in the
// chain, just copy the next fields over. // chain, just copy the next fields over.
let next_opt = util::replace(&mut bucket.next, None); let next_opt = mem::replace(&mut bucket.next, None);
match next_opt { match next_opt {
None => nuke_bucket = true, None => nuke_bucket = true,
Some(~next) => *bucket = next, Some(~next) => *bucket = next,
@ -168,7 +169,7 @@ impl<K:Hash + Eq,V> ConcurrentHashMap<K,V> {
Some(ref mut bucket) => { Some(ref mut bucket) => {
// Continue the search. // Continue the search.
if bucket.key != *key { if bucket.key != *key {
prev = ptr::to_mut_unsafe_ptr(&mut **bucket); prev = &mut **bucket as *mut Bucket<K,V>;
continue continue
} }
} }
@ -191,7 +192,7 @@ impl<K:Hash + Eq,V> ConcurrentHashMap<K,V> {
} }
unsafe { unsafe {
this.locks[lock_index].unlock() this.locks[lock_index].unlock_noguard()
} }
} }
@ -235,7 +236,7 @@ impl<K:Hash + Eq,V> ConcurrentHashMap<K,V> {
} }
unsafe { unsafe {
this.locks[lock_index].unlock() this.locks[lock_index].unlock_noguard()
} }
result result
@ -255,7 +256,7 @@ impl<K:Hash + Eq,V> ConcurrentHashMap<K,V> {
stripe_index += 1; stripe_index += 1;
if stripe_index == buckets_per_lock { if stripe_index == buckets_per_lock {
unsafe { unsafe {
this.locks[lock_index].unlock(); this.locks[lock_index].unlock_noguard();
} }
stripe_index = 0; stripe_index = 0;
@ -263,7 +264,7 @@ impl<K:Hash + Eq,V> ConcurrentHashMap<K,V> {
} }
if stripe_index == 0 { if stripe_index == 0 {
unsafe { unsafe {
this.locks[lock_index].lock() this.locks[lock_index].lock_noguard()
} }
} }
@ -284,7 +285,7 @@ impl<K:Hash + Eq,V> ConcurrentHashMap<K,V> {
// Take a lock on all buckets. // Take a lock on all buckets.
for lock in this.locks.mut_iter() { for lock in this.locks.mut_iter() {
unsafe { unsafe {
lock.lock() lock.lock_noguard()
} }
} }
@ -295,7 +296,7 @@ impl<K:Hash + Eq,V> ConcurrentHashMap<K,V> {
if new_bucket_count > this.buckets.len() { if new_bucket_count > this.buckets.len() {
// Create a new set of buckets. // Create a new set of buckets.
let mut buckets = vec::from_fn(new_bucket_count, |_| None); let mut buckets = vec::from_fn(new_bucket_count, |_| None);
util::swap(&mut this.buckets, &mut buckets); mem::swap(&mut this.buckets, &mut buckets);
this.size.store(0, Relaxed); this.size.store(0, Relaxed);
// Go through all the old buckets and insert the new data. // Go through all the old buckets and insert the new data.
@ -335,7 +336,7 @@ impl<K:Hash + Eq,V> ConcurrentHashMap<K,V> {
// Release all our locks. // Release all our locks.
for lock in this.locks.mut_iter() { for lock in this.locks.mut_iter() {
unsafe { unsafe {
lock.unlock() lock.unlock_noguard()
} }
} }
} }
@ -346,10 +347,10 @@ impl<K:Hash + Eq,V> ConcurrentHashMap<K,V> {
#[inline] #[inline]
fn bucket_and_lock_indices(&self, key: &K) -> (uint, uint) { fn bucket_and_lock_indices(&self, key: &K) -> (uint, uint) {
let this: &mut ConcurrentHashMap<K,V> = unsafe { let this: &mut ConcurrentHashMap<K,V> = unsafe {
cast::transmute_mut(self) cast::transmute_mut(cast::transmute_region(self))
}; };
let hash = key.hash_keyed(self.k0, self.k1); let hash = sip::hash_with_keys(self.k0, self.k1, key);
let lock_count = this.locks.len(); let lock_count = this.locks.len();
let mut bucket_index; let mut bucket_index;
let mut lock_index; let mut lock_index;
@ -359,7 +360,7 @@ impl<K:Hash + Eq,V> ConcurrentHashMap<K,V> {
bucket_index = hash as uint % bucket_count; bucket_index = hash as uint % bucket_count;
lock_index = bucket_index / buckets_per_lock; lock_index = bucket_index / buckets_per_lock;
unsafe { unsafe {
this.locks[lock_index].lock(); this.locks[lock_index].lock_noguard();
} }
let new_bucket_count = this.buckets.len(); let new_bucket_count = this.buckets.len();
if bucket_count == new_bucket_count { if bucket_count == new_bucket_count {
@ -368,7 +369,7 @@ impl<K:Hash + Eq,V> ConcurrentHashMap<K,V> {
// If we got here, the hash table resized from under us: try again. // If we got here, the hash table resized from under us: try again.
unsafe { unsafe {
this.locks[lock_index].unlock() this.locks[lock_index].unlock_noguard()
} }
} }
@ -379,7 +380,7 @@ impl<K:Hash + Eq,V> ConcurrentHashMap<K,V> {
/// function! /// function!
#[inline] #[inline]
unsafe fn bucket_index_unlocked(&self, key: &K) -> uint { unsafe fn bucket_index_unlocked(&self, key: &K) -> uint {
let hash = key.hash_keyed(self.k0, self.k1); let hash = sip::hash_with_keys(self.k0, self.k1, key);
hash as uint % self.buckets.len() hash as uint % self.buckets.len()
} }
@ -446,12 +447,12 @@ impl<'a,K,V> Iterator<(&'a K, &'a V)> for ConcurrentHashMapIterator<'a,K,V> {
// necessary and acquire the new one, if necessary. // necessary and acquire the new one, if necessary.
if bucket_index != -1 { if bucket_index != -1 {
unsafe { unsafe {
map.locks[lock_index].unlock() map.locks[lock_index].unlock_noguard()
} }
} }
if bucket_index != (bucket_count as int) - 1 { if bucket_index != (bucket_count as int) - 1 {
unsafe { unsafe {
map.locks[lock_index + 1].lock() map.locks[lock_index + 1].lock_noguard()
} }
} }
} }

View file

@ -15,8 +15,8 @@ fn hexdump_slice(buf: &[u8]) {
let output = format!("{:02X} ", v as uint); let output = format!("{:02X} ", v as uint);
stderr.write(output.as_bytes()); stderr.write(output.as_bytes());
match i % 16 { match i % 16 {
15 => stderr.write(bytes!("\n ")), 15 => { stderr.write(bytes!("\n ")); },
7 => stderr.write(bytes!(" ")), 7 => { stderr.write(bytes!(" ")); },
_ => () _ => ()
} }
stderr.flush(); stderr.flush();

View file

@ -18,67 +18,111 @@ pub struct Au(i32);
impl Clone for Au { impl Clone for Au {
#[inline] #[inline]
fn clone(&self) -> Au { fn clone(&self) -> Au {
Au(**self) let Au(i) = *self;
Au(i)
} }
} }
impl fmt::Default for Au { impl fmt::Show for Au {
fn fmt(obj: &Au, f: &mut fmt::Formatter) { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let Au(n) = *obj; let Au(n) = *self;
write!(f.buf, "Au({})", n); write!(f.buf, "Au({})", n)
} }}
}
impl Eq for Au { impl Eq for Au {
#[inline] #[inline]
fn eq(&self, other: &Au) -> bool { fn eq(&self, other: &Au) -> bool {
**self == **other let Au(s) = *self;
let Au(o) = *other;
s==o
} }
#[inline] #[inline]
fn ne(&self, other: &Au) -> bool { fn ne(&self, other: &Au) -> bool {
**self != **other let Au(s) = *self;
let Au(o) = *other;
s!=o
} }
} }
impl Add<Au,Au> for Au { impl Add<Au,Au> for Au {
#[inline] #[inline]
fn add(&self, other: &Au) -> Au { Au(**self + **other) } fn add(&self, other: &Au) -> Au {
let Au(s) = *self;
let Au(o) = *other;
Au(s+o)
}
} }
impl Sub<Au,Au> for Au { impl Sub<Au,Au> for Au {
#[inline] #[inline]
fn sub(&self, other: &Au) -> Au { Au(**self - **other) } fn sub(&self, other: &Au) -> Au {
let Au(s) = *self;
let Au(o) = *other;
Au(s-o)
}
} }
impl Mul<Au,Au> for Au { impl Mul<Au,Au> for Au {
#[inline] #[inline]
fn mul(&self, other: &Au) -> Au { Au(**self * **other) } fn mul(&self, other: &Au) -> Au {
let Au(s) = *self;
let Au(o) = *other;
Au(s*o)
}
} }
impl Div<Au,Au> for Au { impl Div<Au,Au> for Au {
#[inline] #[inline]
fn div(&self, other: &Au) -> Au { Au(**self / **other) } fn div(&self, other: &Au) -> Au {
let Au(s) = *self;
let Au(o) = *other;
Au(s/o)
}
} }
impl Rem<Au,Au> for Au { impl Rem<Au,Au> for Au {
#[inline] #[inline]
fn rem(&self, other: &Au) -> Au { Au(**self % **other) } fn rem(&self, other: &Au) -> Au {
let Au(s) = *self;
let Au(o) = *other;
Au(s%o)
}
} }
impl Neg<Au> for Au { impl Neg<Au> for Au {
#[inline] #[inline]
fn neg(&self) -> Au { Au(-**self) } fn neg(&self) -> Au {
let Au(s) = *self;
Au(-s)
}
} }
impl Ord for Au { impl Ord for Au {
#[inline] #[inline]
fn lt(&self, other: &Au) -> bool { **self < **other } fn lt(&self, other: &Au) -> bool {
let Au(s) = *self;
let Au(o) = *other;
s<o
}
#[inline] #[inline]
fn le(&self, other: &Au) -> bool { **self <= **other } fn le(&self, other: &Au) -> bool {
let Au(s) = *self;
let Au(o) = *other;
s<=o
}
#[inline] #[inline]
fn ge(&self, other: &Au) -> bool { **self >= **other } fn ge(&self, other: &Au) -> bool {
let Au(s) = *self;
let Au(o) = *other;
s>=o
}
#[inline] #[inline]
fn gt(&self, other: &Au) -> bool { **self > **other } fn gt(&self, other: &Au) -> bool {
let Au(s) = *self;
let Au(o) = *other;
s>o
}
} }
impl One for Au { impl One for Au {
@ -90,7 +134,10 @@ impl Zero for Au {
#[inline] #[inline]
fn zero() -> Au { Au(0) } fn zero() -> Au { Au(0) }
#[inline] #[inline]
fn is_zero(&self) -> bool { **self == 0 } fn is_zero(&self) -> bool {
let Au(s) = *self;
s==0
}
} }
impl Num for Au {} impl Num for Au {}
@ -110,22 +157,26 @@ impl NumCast for Au {
impl ToPrimitive for Au { impl ToPrimitive for Au {
#[inline] #[inline]
fn to_i64(&self) -> Option<i64> { fn to_i64(&self) -> Option<i64> {
Some(**self as i64) let Au(s) = *self;
Some(s as i64)
} }
#[inline] #[inline]
fn to_u64(&self) -> Option<u64> { fn to_u64(&self) -> Option<u64> {
Some(**self as u64) let Au(s) = *self;
Some(s as u64)
} }
#[inline] #[inline]
fn to_f32(&self) -> Option<f32> { fn to_f32(&self) -> Option<f32> {
(**self).to_f32() let Au(s) = *self;
s.to_f32()
} }
#[inline] #[inline]
fn to_f64(&self) -> Option<f64> { fn to_f64(&self) -> Option<f64> {
(**self).to_f64() let Au(s) = *self;
s.to_f64()
} }
} }
@ -138,7 +189,8 @@ impl Au {
#[inline] #[inline]
pub fn scale_by(self, factor: f64) -> Au { pub fn scale_by(self, factor: f64) -> Au {
Au(((*self as f64) * factor) as i32) let Au(s) = self;
Au(((s as f64) * factor) as i32)
} }
#[inline] #[inline]
@ -148,14 +200,16 @@ impl Au {
#[inline] #[inline]
pub fn to_nearest_px(&self) -> int { pub fn to_nearest_px(&self) -> int {
((**self as f64) / 60f64).round() as int let Au(s) = *self;
((s as f64) / 60f64).round() as int
} }
#[inline] #[inline]
pub fn to_snapped(&self) -> Au { pub fn to_snapped(&self) -> Au {
let res = **self % 60i32; let Au(s) = *self;
return if res >= 30i32 { return Au(**self - res + 60i32) } let res = s % 60i32;
else { return Au(**self - res) }; return if res >= 30i32 { return Au(s - res + 60i32) }
else { return Au(s - res) };
} }
#[inline] #[inline]
@ -180,9 +234,18 @@ impl Au {
} }
#[inline] #[inline]
pub fn min(x: Au, y: Au) -> Au { if *x < *y { x } else { y } } pub fn min(x: Au, y: Au) -> Au {
let Au(xi) = x;
let Au(yi) = y;
if xi < yi { x } else { y }
}
#[inline] #[inline]
pub fn max(x: Au, y: Au) -> Au { if *x > *y { x } else { y } } pub fn max(x: Au, y: Au) -> Au {
let Au(xi) = x;
let Au(yi) = y;
if xi > yi { x } else { y }
}
} }
// assumes 72 points per inch, and 96 px per inch // assumes 72 points per inch, and 96 px per inch
@ -217,11 +280,13 @@ pub fn from_px(px: int) -> Au {
} }
pub fn to_px(au: Au) -> int { pub fn to_px(au: Au) -> int {
(*au / 60) as int let Au(a) = au;
(a / 60) as int
} }
pub fn to_frac_px(au: Au) -> f64 { pub fn to_frac_px(au: Au) -> f64 {
(*au as f64) / 60f64 let Au(a) = au;
(a as f64) / 60f64
} }
// assumes 72 points per inch, and 96 px per inch // assumes 72 points per inch, and 96 px per inch
@ -231,6 +296,7 @@ pub fn from_pt(pt: f64) -> Au {
// assumes 72 points per inch, and 96 px per inch // assumes 72 points per inch, and 96 px per inch
pub fn to_pt(au: Au) -> f64 { pub fn to_pt(au: Au) -> f64 {
(*au as f64) / 60f64 * 72f64 / 96f64 let Au(a) = au;
(a as f64) / 60f64 * 72f64 / 96f64
} }

View file

@ -1,20 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use std::io::{io_error, IoError};
/// Helper for catching an I/O error and wrapping it in a Result object. The
/// return result will be the last I/O error that happened or the result of the
/// closure if no error occurred.
///
/// FIXME: This is a copy of std::rt::io::result which doesn't exist yet in our
/// version of Rust. We should switch after the next Rust upgrade.
pub fn result<T>(cb: || -> T) -> Result<T, IoError> {
let mut err = None;
let ret = io_error::cond.trap(|e| err = Some(e)).inside(cb);
match err {
Some(e) => Err(e),
None => Ok(ret),
}
}

View file

@ -7,8 +7,8 @@
use azure::azure_hl::{BackendType, CairoBackend, CoreGraphicsBackend}; use azure::azure_hl::{BackendType, CairoBackend, CoreGraphicsBackend};
use azure::azure_hl::{CoreGraphicsAcceleratedBackend, Direct2DBackend, SkiaBackend}; use azure::azure_hl::{CoreGraphicsAcceleratedBackend, Direct2DBackend, SkiaBackend};
use extra::getopts::groups; use getopts;
use std::num; use std::cmp;
use std::rt; use std::rt;
use std::io; use std::io;
use std::os; use std::os;
@ -56,9 +56,9 @@ pub struct Opts {
bubble_widths_separately: bool, bubble_widths_separately: bool,
} }
fn print_usage(app: &str, opts: &[groups::OptGroup]) { fn print_usage(app: &str, opts: &[getopts::OptGroup]) {
let message = format!("Usage: {} [ options ... ] [URL]\n\twhere options include", app); let message = format!("Usage: {} [ options ... ] [URL]\n\twhere options include", app);
println(groups::usage(message, opts)); println!("{}", getopts::usage(message, opts));
} }
fn args_fail(msg: &str) { fn args_fail(msg: &str) {
@ -71,21 +71,21 @@ pub fn from_cmdline_args(args: &[~str]) -> Option<Opts> {
let args = args.tail(); let args = args.tail();
let opts = ~[ let opts = ~[
groups::optflag("c", "cpu", "CPU rendering"), getopts::optflag("c", "cpu", "CPU rendering"),
groups::optopt("o", "output", "Output file", "output.png"), getopts::optopt("o", "output", "Output file", "output.png"),
groups::optopt("r", "rendering", "Rendering backend", "direct2d|core-graphics|core-graphics-accelerated|cairo|skia."), getopts::optopt("r", "rendering", "Rendering backend", "direct2d|core-graphics|core-graphics-accelerated|cairo|skia."),
groups::optopt("s", "size", "Size of tiles", "512"), getopts::optopt("s", "size", "Size of tiles", "512"),
groups::optopt("t", "threads", "Number of render threads", "1"), getopts::optopt("t", "threads", "Number of render threads", "1"),
groups::optflagopt("p", "profile", "Profiler flag and output interval", "10"), getopts::optflagopt("p", "profile", "Profiler flag and output interval", "10"),
groups::optflag("x", "exit", "Exit after load flag"), getopts::optflag("x", "exit", "Exit after load flag"),
groups::optopt("y", "layout-threads", "Number of threads to use for layout", "1"), getopts::optopt("y", "layout-threads", "Number of threads to use for layout", "1"),
groups::optflag("z", "headless", "Headless mode"), getopts::optflag("z", "headless", "Headless mode"),
groups::optflag("f", "hard-fail", "Exit on task failure instead of displaying about:failure"), getopts::optflag("f", "hard-fail", "Exit on task failure instead of displaying about:failure"),
groups::optflag("b", "bubble-widths", "Bubble intrinsic widths separately like other engines"), getopts::optflag("b", "bubble-widths", "Bubble intrinsic widths separately like other engines"),
groups::optflag("h", "help", "Print this message") getopts::optflag("h", "help", "Print this message")
]; ];
let opt_match = match groups::getopts(args, opts) { let opt_match = match getopts::getopts(args, opts) {
Ok(m) => m, Ok(m) => m,
Err(f) => { Err(f) => {
args_fail(f.to_err_msg()); args_fail(f.to_err_msg());
@ -144,7 +144,7 @@ pub fn from_cmdline_args(args: &[~str]) -> Option<Opts> {
let layout_threads: uint = match opt_match.opt_str("y") { let layout_threads: uint = match opt_match.opt_str("y") {
Some(layout_threads_str) => from_str(layout_threads_str).unwrap(), Some(layout_threads_str) => from_str(layout_threads_str).unwrap(),
None => num::max(rt::default_sched_threads() * 3 / 4, 1), None => cmp::max(rt::default_sched_threads() * 3 / 4, 1),
}; };
Some(Opts { Some(Opts {

View file

@ -22,9 +22,9 @@ pub struct Range {
priv len: uint priv len: uint
} }
impl fmt::Default for Range { impl fmt::Show for Range {
fn fmt(obj: &Range, f: &mut fmt::Formatter) { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f.buf, "[{} .. {})", obj.begin(), obj.end()); write!(f.buf, "[{} .. {})", self.begin(), self.end())
} }
} }

View file

@ -5,17 +5,16 @@
//! Small vectors in various sizes. These store a certain number of elements inline and fall back //! Small vectors in various sizes. These store a certain number of elements inline and fall back
//! to the heap for larger allocations. //! to the heap for larger allocations.
use i = std::unstable::intrinsics::init; use i = std::mem::init;
use std::cast; use std::cast;
use std::cmp;
use std::intrinsics;
use std::libc::c_char; use std::libc::c_char;
use std::mem; use std::mem;
use std::num;
use std::ptr; use std::ptr;
use std::rt::global_heap; use std::rt::global_heap;
use std::rt::local_heap; use std::rt::local_heap;
use std::unstable::intrinsics; use std::raw::Slice;
use std::unstable::raw::Slice;
use std::util;
// Generic code for all small vectors // Generic code for all small vectors
@ -86,11 +85,11 @@ pub trait SmallVec<T> : SmallVecPrivate<T> {
fn push(&mut self, value: T) { fn push(&mut self, value: T) {
let cap = self.cap(); let cap = self.cap();
if self.len() == cap { if self.len() == cap {
self.grow(num::max(cap * 2, 1)) self.grow(cmp::max(cap * 2, 1))
} }
unsafe { unsafe {
let end: &mut T = cast::transmute(self.end()); let end: &mut T = cast::transmute(self.end());
intrinsics::move_val_init(end, value); mem::move_val_init(end, value);
let len = self.len(); let len = self.len();
self.set_len(len + 1) self.set_len(len + 1)
} }
@ -104,9 +103,9 @@ pub trait SmallVec<T> : SmallVecPrivate<T> {
if self.spilled() { if self.spilled() {
if intrinsics::owns_managed::<T>() { if intrinsics::owns_managed::<T>() {
local_heap::local_free(self.ptr() as *u8 as *c_char) local_heap::local_free(self.ptr() as *u8)
} else { } else {
global_heap::exchange_free(self.ptr() as *u8 as *c_char) global_heap::exchange_free(self.ptr() as *u8)
} }
} else { } else {
let mut_begin: *mut T = cast::transmute(self.begin()); let mut_begin: *mut T = cast::transmute(self.begin());
@ -211,7 +210,7 @@ impl<'a,T> Iterator<T> for SmallVecMoveIterator<'a,T> {
Some(reference) => { Some(reference) => {
// Zero out the values as we go so they don't get double-freed. // Zero out the values as we go so they don't get double-freed.
let reference: &mut T = cast::transmute(reference); let reference: &mut T = cast::transmute(reference);
Some(util::replace(reference, intrinsics::init())) Some(mem::replace(reference, mem::init()))
} }
} }
} }
@ -229,9 +228,9 @@ impl<'a,T> Drop for SmallVecMoveIterator<'a,T> {
Some(allocation) => { Some(allocation) => {
unsafe { unsafe {
if intrinsics::owns_managed::<T>() { if intrinsics::owns_managed::<T>() {
local_heap::local_free(allocation as *u8 as *c_char) local_heap::local_free(allocation as *u8)
} else { } else {
global_heap::exchange_free(allocation as *u8 as *c_char) global_heap::exchange_free(allocation as *u8)
} }
} }
} }
@ -310,13 +309,13 @@ macro_rules! def_small_vector_drop_impl(
unsafe { unsafe {
let ptr = self.mut_ptr(); let ptr = self.mut_ptr();
for i in range(0, self.len()) { for i in range(0, self.len()) {
*ptr.offset(i as int) = intrinsics::uninit(); *ptr.offset(i as int) = mem::uninit();
} }
if intrinsics::owns_managed::<T>() { if intrinsics::owns_managed::<T>() {
local_heap::local_free(self.ptr() as *u8 as *c_char) local_heap::local_free(self.ptr() as *u8)
} else { } else {
global_heap::exchange_free(self.ptr() as *u8 as *c_char) global_heap::exchange_free(self.ptr() as *u8)
} }
} }
} }
@ -348,7 +347,7 @@ macro_rules! def_small_vector_impl(
len: 0, len: 0,
cap: $size, cap: $size,
ptr: ptr::null(), ptr: ptr::null(),
data: intrinsics::init(), data: mem::init(),
} }
} }
} }

View file

@ -2,24 +2,24 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use std::str::IntoMaybeOwned;
use std::task; use std::task;
use std::comm::SharedChan; use std::comm::Chan;
use std::task::TaskBuilder; use std::task::TaskBuilder;
pub fn spawn_named<S: IntoSendStr>(name: S, f: proc()) { pub fn spawn_named<S: IntoMaybeOwned<'static>>(name: S, f: proc()) {
let mut builder = task::task(); let mut builder = task::task().named(name);
builder.name(name);
builder.spawn(f); builder.spawn(f);
} }
/// Arrange to send a particular message to a channel if the task built by /// Arrange to send a particular message to a channel if the task built by
/// this `TaskBuilder` fails. /// this `TaskBuilder` fails.
pub fn send_on_failure<T: Send>(builder: &mut TaskBuilder, msg: T, dest: SharedChan<T>) { pub fn send_on_failure<T: Send>(builder: &mut TaskBuilder, msg: T, dest: Chan<T>) {
let port = builder.future_result(); let port = builder.future_result();
do spawn { spawn(proc() {
match port.recv() { match port.recv() {
Ok(()) => (), Ok(()) => (),
Err(..) => dest.send(msg), Err(..) => dest.send(msg),
} }
} })
} }

Some files were not shown because too many files have changed in this diff Show more