auto merge of #546 : brson/servo/master, r=metajack

This commit is contained in:
bors-servo 2013-06-26 15:36:53 -07:00
commit bc520e0143
109 changed files with 1182 additions and 988 deletions

@ -1 +1 @@
Subproject commit 1b883365bc0813f5775c8207e414b7973e947a76 Subproject commit f348465283d6cd85b69bcdc1711d14985d154c39

View file

@ -19,11 +19,11 @@ use geometry::Au;
use render_context::RenderContext; use render_context::RenderContext;
use text::SendableTextRun; use text::SendableTextRun;
use core::cast::transmute_region; use std::cast::transmute_region;
use geom::{Point2D, Rect, Size2D}; use geom::{Point2D, Rect, Size2D};
use servo_net::image::base::Image; use servo_net::image::base::Image;
use servo_util::range::Range; use servo_util::range::Range;
use std::arc::ARC; use extra::arc::ARC;
/// A list of rendering operations to be performed. /// A list of rendering operations to be performed.
pub struct DisplayList<E> { pub struct DisplayList<E> {

View file

@ -9,6 +9,11 @@ use platform::font_context::FontContextHandle;
use platform::font::{FontHandle, FontTable}; use platform::font::{FontHandle, FontTable};
use render_context::RenderContext; use render_context::RenderContext;
use servo_util::range::Range; use servo_util::range::Range;
use std::cast;
use std::result;
use std::ptr;
use std::str;
use std::vec;
use text::glyph::{GlyphStore, GlyphIndex}; use text::glyph::{GlyphStore, GlyphIndex};
use text::shaping::ShaperMethods; use text::shaping::ShaperMethods;
use text::{Shaper, TextRun}; use text::{Shaper, TextRun};
@ -94,7 +99,7 @@ pub enum CSSFontWeight {
FontWeight900, FontWeight900,
} }
pub impl CSSFontWeight { impl CSSFontWeight {
pub fn is_bold(self) -> bool { pub fn is_bold(self) -> bool {
match self { match self {
FontWeight900 | FontWeight800 | FontWeight700 | FontWeight600 => true, FontWeight900 | FontWeight800 | FontWeight700 | FontWeight600 => true,
@ -140,8 +145,8 @@ pub struct FontDescriptor {
selector: FontSelector, selector: FontSelector,
} }
pub impl FontDescriptor { impl FontDescriptor {
fn new(style: UsedFontStyle, selector: FontSelector) -> FontDescriptor { pub fn new(style: UsedFontStyle, selector: FontSelector) -> FontDescriptor {
FontDescriptor { FontDescriptor {
style: style, style: style,
selector: selector, selector: selector,
@ -170,8 +175,8 @@ pub struct FontGroup {
fonts: ~[@mut Font], fonts: ~[@mut Font],
} }
pub impl FontGroup { impl FontGroup {
fn new(families: @str, style: &UsedFontStyle, fonts: ~[@mut Font]) -> FontGroup { pub fn new(families: @str, style: &UsedFontStyle, fonts: ~[@mut Font]) -> FontGroup {
FontGroup { FontGroup {
families: families, families: families,
style: copy *style, style: copy *style,
@ -179,11 +184,11 @@ pub impl FontGroup {
} }
} }
fn teardown(&mut self) { pub fn teardown(&mut self) {
self.fonts = ~[]; self.fonts = ~[];
} }
fn create_textrun(&self, text: ~str, underline: bool) -> TextRun { pub fn create_textrun(&self, text: ~str, underline: bool) -> TextRun {
assert!(self.fonts.len() > 0); assert!(self.fonts.len() > 0);
// TODO(Issue #177): Actually fall back through the FontGroup when a font is unsuitable. // TODO(Issue #177): Actually fall back through the FontGroup when a font is unsuitable.
@ -215,8 +220,8 @@ pub struct Font {
profiler_chan: ProfilerChan, profiler_chan: ProfilerChan,
} }
pub impl Font { impl Font {
fn new_from_buffer(ctx: &FontContext, pub fn new_from_buffer(ctx: &FontContext,
buffer: ~[u8], buffer: ~[u8],
style: &SpecifiedFontStyle, style: &SpecifiedFontStyle,
backend: BackendType, backend: BackendType,
@ -243,7 +248,7 @@ pub impl Font {
}); });
} }
fn new_from_adopted_handle(_fctx: &FontContext, handle: FontHandle, pub fn new_from_adopted_handle(_fctx: &FontContext, handle: FontHandle,
style: &SpecifiedFontStyle, backend: BackendType, style: &SpecifiedFontStyle, backend: BackendType,
profiler_chan: ProfilerChan) -> @mut Font { profiler_chan: ProfilerChan) -> @mut Font {
let metrics = handle.get_metrics(); let metrics = handle.get_metrics();
@ -259,7 +264,7 @@ pub impl Font {
} }
} }
fn new_from_existing_handle(fctx: &FontContext, handle: &FontHandle, pub fn new_from_existing_handle(fctx: &FontContext, handle: &FontHandle,
style: &SpecifiedFontStyle, backend: BackendType, style: &SpecifiedFontStyle, backend: BackendType,
profiler_chan: ProfilerChan) -> Result<@mut Font,()> { profiler_chan: ProfilerChan) -> Result<@mut Font,()> {
@ -284,7 +289,7 @@ pub impl Font {
shaper shaper
} }
fn get_table_for_tag(&self, tag: FontTableTag) -> Option<FontTable> { pub fn get_table_for_tag(&self, tag: FontTableTag) -> Option<FontTable> {
let result = self.handle.get_table_for_tag(tag); let result = self.handle.get_table_for_tag(tag);
let status = if result.is_some() { "Found" } else { "Didn't find" }; let status = if result.is_some() { "Found" } else { "Didn't find" };
@ -295,7 +300,7 @@ pub impl Font {
return result; return result;
} }
fn teardown(&mut self) { pub fn teardown(&mut self) {
self.shaper = None; self.shaper = None;
self.azure_font = None; self.azure_font = None;
} }
@ -332,19 +337,19 @@ pub impl Font {
} }
pub impl Font { impl Font {
fn draw_text_into_context(&mut self, pub fn draw_text_into_context(&mut self,
rctx: &RenderContext, rctx: &RenderContext,
run: &TextRun, run: &TextRun,
range: &Range, range: &Range,
baseline_origin: Point2D<Au>, baseline_origin: Point2D<Au>,
color: Color) { color: Color) {
use core::libc::types::common::c99::{uint16_t, uint32_t}; use std::libc::types::common::c99::{uint16_t, uint32_t};
use azure::{struct__AzDrawOptions, use azure::{struct__AzDrawOptions,
struct__AzGlyph, struct__AzGlyph,
struct__AzGlyphBuffer, struct__AzGlyphBuffer,
struct__AzPoint}; struct__AzPoint};
use azure::azure::bindgen::{AzDrawTargetFillGlyphs}; use azure::azure::{AzDrawTargetFillGlyphs};
let target = rctx.get_draw_target(); let target = rctx.get_draw_target();
let azfontref = self.get_azure_font(); let azfontref = self.get_azure_font();
@ -362,7 +367,7 @@ pub impl Font {
vec::reserve(&mut azglyphs, range.length()); vec::reserve(&mut azglyphs, range.length());
for run.glyphs.iter_glyphs_for_char_range(range) |_i, glyph| { for run.glyphs.iter_glyphs_for_char_range(range) |_i, glyph| {
let glyph_advance = glyph.advance(); let glyph_advance = glyph.advance_();
let glyph_offset = glyph.offset().get_or_default(Au::zero_point()); let glyph_offset = glyph.offset().get_or_default(Au::zero_point());
let azglyph = struct__AzGlyph { let azglyph = struct__AzGlyph {
@ -379,13 +384,12 @@ pub impl Font {
let azglyph_buf_len = azglyphs.len(); let azglyph_buf_len = azglyphs.len();
if azglyph_buf_len == 0 { return; } // Otherwise the Quartz backend will assert. if azglyph_buf_len == 0 { return; } // Otherwise the Quartz backend will assert.
let glyphbuf = unsafe { let glyphbuf = struct__AzGlyphBuffer {
struct__AzGlyphBuffer {
mGlyphs: vec::raw::to_ptr(azglyphs), mGlyphs: vec::raw::to_ptr(azglyphs),
mNumGlyphs: azglyph_buf_len as uint32_t mNumGlyphs: azglyph_buf_len as uint32_t
}
}; };
unsafe {
// 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,
@ -394,13 +398,14 @@ pub impl Font {
ptr::to_unsafe_ptr(&options), ptr::to_unsafe_ptr(&options),
ptr::null()); ptr::null());
} }
}
fn measure_text(&self, run: &TextRun, range: &Range) -> RunMetrics { pub fn measure_text(&self, run: &TextRun, range: &Range) -> RunMetrics {
// TODO(Issue #199): alter advance direction for RTL // TODO(Issue #199): alter advance direction for RTL
// TODO(Issue #98): using inter-char and inter-word spacing settings when measuring text // TODO(Issue #98): using inter-char and inter-word spacing settings when measuring text
let mut advance = Au(0); let mut advance = Au(0);
for run.glyphs.iter_glyphs_for_char_range(range) |_i, glyph| { for run.glyphs.iter_glyphs_for_char_range(range) |_i, glyph| {
advance += glyph.advance(); advance += glyph.advance_();
} }
let bounds = Rect(Point2D(Au(0), -self.metrics.ascent), let bounds = Rect(Point2D(Au(0), -self.metrics.ascent),
Size2D(advance, self.metrics.ascent + self.metrics.descent)); Size2D(advance, self.metrics.ascent + self.metrics.descent));
@ -417,22 +422,22 @@ pub impl Font {
} }
} }
fn shape_text(@mut self, text: &str, store: &mut GlyphStore) { pub fn shape_text(@mut self, text: &str, store: &mut GlyphStore) {
// TODO(Issue #229): use a more efficient strategy for repetitive shaping. // TODO(Issue #229): use a more efficient strategy for repetitive shaping.
// For example, Gecko uses a per-"word" hashtable of shaper results. // For example, Gecko uses a per-"word" hashtable of shaper results.
let shaper = self.get_shaper(); let shaper = self.get_shaper();
shaper.shape_text(text, store); shaper.shape_text(text, store);
} }
fn get_descriptor(&self) -> FontDescriptor { pub fn get_descriptor(&self) -> FontDescriptor {
FontDescriptor::new(copy self.style, SelectorPlatformIdentifier(self.handle.face_identifier())) FontDescriptor::new(copy self.style, SelectorPlatformIdentifier(self.handle.face_identifier()))
} }
fn glyph_index(&self, codepoint: char) -> Option<GlyphIndex> { pub fn glyph_index(&self, codepoint: char) -> Option<GlyphIndex> {
self.handle.glyph_index(codepoint) self.handle.glyph_index(codepoint)
} }
fn glyph_h_advance(&self, glyph: GlyphIndex) -> FractionalPixel { pub fn glyph_h_advance(&self, glyph: GlyphIndex) -> FractionalPixel {
match self.handle.glyph_h_advance(glyph) { match self.handle.glyph_h_advance(glyph) {
Some(adv) => adv, Some(adv) => adv,
None => /* FIXME: Need fallback strategy */ 10f as FractionalPixel None => /* FIXME: Need fallback strategy */ 10f as FractionalPixel

View file

@ -14,7 +14,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 core::hashmap::HashMap; use std::hashmap::HashMap;
use std::str;
use std::result;
// TODO(Rust #3934): creating lots of new dummy styles is a workaround // TODO(Rust #3934): creating lots of new dummy styles is a workaround
// for not being able to store symbolic enums in top-level constants. // for not being able to store symbolic enums in top-level constants.
@ -46,8 +48,8 @@ pub struct FontContext {
} }
#[allow(non_implicitly_copyable_typarams)] #[allow(non_implicitly_copyable_typarams)]
pub impl<'self> FontContext { impl<'self> FontContext {
fn new(backend: BackendType, pub fn new(backend: BackendType,
needs_font_list: bool, needs_font_list: bool,
profiler_chan: ProfilerChan) profiler_chan: ProfilerChan)
-> FontContext { -> FontContext {
@ -79,7 +81,7 @@ pub impl<'self> FontContext {
self.font_list.get_ref() self.font_list.get_ref()
} }
fn get_resolved_font_for_style(&mut self, style: &SpecifiedFontStyle) -> @FontGroup { pub fn get_resolved_font_for_style(&mut self, style: &SpecifiedFontStyle) -> @FontGroup {
match self.group_cache.find(style) { match self.group_cache.find(style) {
Some(fg) => { Some(fg) => {
debug!("font group cache hit"); debug!("font group cache hit");
@ -94,7 +96,7 @@ pub impl<'self> FontContext {
} }
} }
fn get_font_by_descriptor(&mut self, desc: &FontDescriptor) -> Result<@mut Font, ()> { pub fn get_font_by_descriptor(&mut self, desc: &FontDescriptor) -> Result<@mut Font, ()> {
match self.instance_cache.find(desc) { match self.instance_cache.find(desc) {
Some(f) => { Some(f) => {
debug!("font cache hit"); debug!("font cache hit");
@ -129,8 +131,8 @@ pub impl<'self> FontContext {
debug!("(create font group) --- starting ---"); debug!("(create font group) --- starting ---");
// TODO(Issue #193): make iteration over 'font-family' more robust. // TODO(Issue #193): make iteration over 'font-family' more robust.
for str::each_split_char(style.families, ',') |family| { for style.families.split_iter(',').advance |family| {
let family_name = str::trim(family); let family_name = family.trim();
let transformed_family_name = self.transform_family(family_name); let transformed_family_name = self.transform_family(family_name);
debug!("(create font group) transformed family is `%s`", transformed_family_name); debug!("(create font group) transformed family is `%s`", transformed_family_name);
@ -142,7 +144,7 @@ pub impl<'self> FontContext {
}; };
let mut found = false; let mut found = false;
for result.each |font_entry| { for result.iter().advance |font_entry| {
found = true; found = true;
let font_id = let font_id =
@ -161,7 +163,7 @@ pub impl<'self> FontContext {
let last_resort = FontList::get_last_resort_font_families(); let last_resort = FontList::get_last_resort_font_families();
for last_resort.each |family| { for last_resort.iter().advance |family| {
let result = match self.font_list { let result = match self.font_list {
Some(ref fl) => { Some(ref fl) => {
fl.find_font_in_family(*family, style) fl.find_font_in_family(*family, style)
@ -169,7 +171,7 @@ pub impl<'self> FontContext {
None => None, None => None,
}; };
for result.each |font_entry| { for result.iter().advance |font_entry| {
let font_id = let font_id =
SelectorPlatformIdentifier(font_entry.handle.face_identifier()); SelectorPlatformIdentifier(font_entry.handle.face_identifier());
let font_desc = FontDescriptor::new(copy *style, font_id); let font_desc = FontDescriptor::new(copy *style, font_id);

View file

@ -8,11 +8,10 @@ use platform::font::FontHandle;
use platform::font_context::FontContextHandle; use platform::font_context::FontContextHandle;
use platform::font_list::FontListHandle; use platform::font_list::FontListHandle;
use servo_util::time; use servo_util::time;
use servo_util::time::time;
use servo_util::time::profile; use servo_util::time::profile;
use servo_util::time::ProfilerChan; use servo_util::time::ProfilerChan;
use core::hashmap::HashMap; use std::hashmap::HashMap;
pub type FontFamilyMap = HashMap<~str, @mut FontFamily>; pub type FontFamilyMap = HashMap<~str, @mut FontFamily>;
@ -29,8 +28,8 @@ pub struct FontList {
prof_chan: ProfilerChan, prof_chan: ProfilerChan,
} }
pub impl FontList { impl FontList {
fn new(fctx: &FontContextHandle, pub fn new(fctx: &FontContextHandle,
prof_chan: ProfilerChan) prof_chan: ProfilerChan)
-> FontList { -> FontList {
let handle = FontListHandle::new(fctx); let handle = FontListHandle::new(fctx);
@ -53,7 +52,7 @@ pub impl FontList {
} }
} }
fn find_font_in_family(&self, pub fn find_font_in_family(&self,
family_name: &str, family_name: &str,
style: &SpecifiedFontStyle) -> Option<@FontEntry> { style: &SpecifiedFontStyle) -> Option<@FontEntry> {
let family = self.find_family(family_name); let family = self.find_family(family_name);
@ -62,7 +61,7 @@ pub impl FontList {
// if such family exists, try to match style to a font // if such family exists, try to match style to a font
let mut result: Option<@FontEntry> = None; let mut result: Option<@FontEntry> = None;
for family.each |fam| { for family.iter().advance |fam| {
result = fam.find_font_for_style(&self.handle, style); result = fam.find_font_for_style(&self.handle, style);
} }

View file

@ -6,8 +6,9 @@ use geom::point::Point2D;
use geom::rect::Rect; use geom::rect::Rect;
use geom::size::Size2D; use geom::size::Size2D;
use core::num::{NumCast, One, Zero}; use std::num::{NumCast, One, Zero};
#[deriving(Clone)]
pub struct Au(i32); pub struct Au(i32);
impl Add<Au,Au> for Au { impl Add<Au,Au> for Au {
@ -34,14 +35,14 @@ impl Neg<Au> for Au {
fn neg(&self) -> Au { Au(-**self) } fn neg(&self) -> Au { Au(-**self) }
} }
impl cmp::Ord for Au { impl Ord for Au {
fn lt(&self, other: &Au) -> bool { **self < **other } fn lt(&self, other: &Au) -> bool { **self < **other }
fn le(&self, other: &Au) -> bool { **self <= **other } fn le(&self, other: &Au) -> bool { **self <= **other }
fn ge(&self, other: &Au) -> bool { **self >= **other } fn ge(&self, other: &Au) -> bool { **self >= **other }
fn gt(&self, other: &Au) -> bool { **self > **other } fn gt(&self, other: &Au) -> bool { **self > **other }
} }
impl cmp::Eq for Au { impl Eq for Au {
fn eq(&self, other: &Au) -> bool { **self == **other } fn eq(&self, other: &Au) -> bool { **self == **other }
fn ne(&self, other: &Au) -> bool { **self != **other } fn ne(&self, other: &Au) -> bool { **self != **other }
} }
@ -80,11 +81,11 @@ impl NumCast for Au {
fn to_float(&self) -> float { (**self).to_float() } fn to_float(&self) -> float { (**self).to_float() }
} }
pub fn box<T:Copy + Ord + Add<T,T> + Sub<T,T>>(x: T, y: T, w: T, h: T) -> Rect<T> { pub fn box<T:Clone + Ord + Add<T,T> + Sub<T,T>>(x: T, y: T, w: T, h: T) -> Rect<T> {
Rect(Point2D(x, y), Size2D(w, h)) Rect(Point2D(x, y), Size2D(w, h))
} }
pub impl Au { impl Au {
pub fn scale_by(self, factor: float) -> Au { pub fn scale_by(self, factor: float) -> Au {
Au(((*self as float) * factor) as i32) Au(((*self as float) * factor) as i32)
} }

View file

@ -12,7 +12,7 @@ extern mod azure;
extern mod geom; extern mod geom;
extern mod http_client; extern mod http_client;
extern mod stb_image; extern mod stb_image;
extern mod std; extern mod extra;
extern mod servo_net (name = "net"); extern mod servo_net (name = "net");
extern mod servo_util (name = "util"); extern mod servo_util (name = "util");
extern mod servo_msg (name = "msg"); extern mod servo_msg (name = "msg");

View file

@ -8,6 +8,10 @@
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 std::f64;
use std::result;
use std::uint;
pub struct Opts { pub struct Opts {
urls: ~[~str], urls: ~[~str],
render_backend: BackendType, render_backend: BackendType,
@ -22,17 +26,17 @@ pub struct Opts {
#[allow(non_implicitly_copyable_typarams)] #[allow(non_implicitly_copyable_typarams)]
pub fn from_cmdline_args(args: &[~str]) -> Opts { pub fn from_cmdline_args(args: &[~str]) -> Opts {
use std::getopts; use extra::getopts;
let args = args.tail(); let args = args.tail();
let opts = ~[ let opts = ~[
getopts::optopt(~"o"), // output file getopts::optopt("o"), // output file
getopts::optopt(~"r"), // rendering backend getopts::optopt("r"), // rendering backend
getopts::optopt(~"s"), // size of tiles getopts::optopt("s"), // size of tiles
getopts::optopt(~"t"), // threads to render with getopts::optopt("t"), // threads to render with
getopts::optflagopt(~"p"), // profiler flag and output interval getopts::optflagopt("p"), // profiler flag and output interval
getopts::optopt(~"z"), // zoom level getopts::optopt("z"), // zoom level
]; ];
let opt_match = match getopts::getopts(args, opts) { let opt_match = match getopts::getopts(args, opts) {
@ -45,11 +49,11 @@ pub fn from_cmdline_args(args: &[~str]) -> Opts {
copy opt_match.free copy opt_match.free
}; };
if getopts::opt_present(&opt_match, ~"o") { if getopts::opt_present(&opt_match, "o") {
fail!(~"servo cannot treat 'o' option now.") fail!(~"servo cannot treat 'o' option now.")
} }
let render_backend = match getopts::opt_maybe_str(&opt_match, ~"r") { let render_backend = match getopts::opt_maybe_str(&opt_match, "r") {
Some(backend_str) => { Some(backend_str) => {
if backend_str == ~"direct2d" { if backend_str == ~"direct2d" {
Direct2DBackend Direct2DBackend
@ -68,24 +72,24 @@ pub fn from_cmdline_args(args: &[~str]) -> Opts {
None => SkiaBackend None => SkiaBackend
}; };
let tile_size: uint = match getopts::opt_maybe_str(&opt_match, ~"s") { let tile_size: uint = match getopts::opt_maybe_str(&opt_match, "s") {
Some(tile_size_str) => uint::from_str(tile_size_str).get(), Some(tile_size_str) => uint::from_str(tile_size_str).get(),
None => 512, None => 512,
}; };
let n_render_threads: uint = match getopts::opt_maybe_str(&opt_match, ~"t") { let n_render_threads: uint = match getopts::opt_maybe_str(&opt_match, "t") {
Some(n_render_threads_str) => uint::from_str(n_render_threads_str).get(), Some(n_render_threads_str) => uint::from_str(n_render_threads_str).get(),
None => 1, // FIXME: Number of cores. None => 1, // FIXME: Number of cores.
}; };
let profiler_period: Option<f64> = let profiler_period: Option<f64> =
// if only flag is present, default to 5 second period // if only flag is present, default to 5 second period
match getopts::opt_default(&opt_match, ~"p", ~"5") { match getopts::opt_default(&opt_match, "p", "5") {
Some(period) => Some(f64::from_str(period).get()), Some(period) => Some(f64::from_str(period).get()),
None => None, None => None,
}; };
let zoom: uint = match getopts::opt_maybe_str(&opt_match, ~"z") { let zoom: uint = match getopts::opt_maybe_str(&opt_match, "z") {
Some(zoom_str) => uint::from_str(zoom_str).get(), Some(zoom_str) => uint::from_str(zoom_str).get(),
None => 1, None => 1,
}; };

View file

@ -14,10 +14,10 @@ use platform::font_context::FontContextHandle;
use text::glyph::GlyphIndex; use text::glyph::GlyphIndex;
use text::util::{float_to_fixed, fixed_to_float}; use text::util::{float_to_fixed, fixed_to_float};
use freetype::freetype::bindgen::{FT_Get_Char_Index, FT_Get_Postscript_Name}; use freetype::freetype::{FT_Get_Char_Index, FT_Get_Postscript_Name};
use freetype::freetype::bindgen::{FT_Load_Glyph, FT_Set_Char_Size}; use freetype::freetype::{FT_Load_Glyph, FT_Set_Char_Size};
use freetype::freetype::bindgen::{FT_New_Face, FT_Get_Sfnt_Table}; use freetype::freetype::{FT_New_Face, FT_Get_Sfnt_Table};
use freetype::freetype::bindgen::{FT_New_Memory_Face, FT_Done_Face}; use freetype::freetype::{FT_New_Memory_Face, FT_Done_Face};
use freetype::freetype::{FTErrorMethods, FT_F26Dot6, FT_Face, FT_FaceRec}; use freetype::freetype::{FTErrorMethods, FT_F26Dot6, FT_Face, FT_FaceRec};
use freetype::freetype::{FT_GlyphSlot, FT_Library, FT_Long, FT_ULong}; use freetype::freetype::{FT_GlyphSlot, FT_Library, FT_Long, FT_ULong};
use freetype::freetype::{FT_STYLE_FLAG_ITALIC, FT_STYLE_FLAG_BOLD}; use freetype::freetype::{FT_STYLE_FLAG_ITALIC, FT_STYLE_FLAG_BOLD};
@ -25,6 +25,11 @@ use freetype::freetype::{FT_SizeRec, FT_UInt, FT_Size_Metrics};
use freetype::freetype::{ft_sfnt_os2}; use freetype::freetype::{ft_sfnt_os2};
use freetype::tt_os2::TT_OS2; use freetype::tt_os2::TT_OS2;
use std::cast;
use std::ptr;
use std::str;
use std::vec;
fn float_to_fixed_ft(f: float) -> i32 { fn float_to_fixed_ft(f: float) -> i32 {
float_to_fixed(6, f) float_to_fixed(6, f)
} }
@ -60,10 +65,12 @@ pub struct FontHandle {
impl Drop for FontHandle { impl Drop for FontHandle {
fn finalize(&self) { fn finalize(&self) {
assert!(self.face.is_not_null()); assert!(self.face.is_not_null());
unsafe {
if !FT_Done_Face(self.face).succeeded() { if !FT_Done_Face(self.face).succeeded() {
fail!(~"FT_Done_Face failed"); fail!(~"FT_Done_Face failed");
} }
} }
}
} }
impl FontHandleMethods for FontHandle { impl FontHandleMethods for FontHandle {
@ -97,6 +104,7 @@ impl FontHandleMethods for FontHandle {
cbuf: *u8, cbuflen: uint, pt_size: float) cbuf: *u8, cbuflen: uint, pt_size: float)
-> Result<FT_Face, ()> { -> Result<FT_Face, ()> {
unsafe {
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,
@ -112,6 +120,7 @@ impl FontHandleMethods for FontHandle {
} }
} }
} }
}
// an identifier usable by FontContextHandle to recreate this FontHandle. // an identifier usable by FontContextHandle to recreate this FontHandle.
fn face_identifier(&self) -> ~str { fn face_identifier(&self) -> ~str {
@ -133,10 +142,11 @@ impl FontHandleMethods for FontHandle {
if unsafe { (*self.face).style_flags & FT_STYLE_FLAG_BOLD == 0 } { if unsafe { (*self.face).style_flags & FT_STYLE_FLAG_BOLD == 0 } {
default_weight default_weight
} else { } else {
unsafe {
let os2 = FT_Get_Sfnt_Table(self.face, ft_sfnt_os2) as *TT_OS2; let os2 = FT_Get_Sfnt_Table(self.face, ft_sfnt_os2) as *TT_OS2;
let valid = os2.is_not_null() && unsafe { (*os2).version != 0xffff }; let valid = os2.is_not_null() && (*os2).version != 0xffff;
if valid { if valid {
let weight = unsafe { (*os2).usWeightClass }; let weight =(*os2).usWeightClass;
match weight { match weight {
1 | 100..199 => FontWeight100, 1 | 100..199 => FontWeight100,
2 | 200..299 => FontWeight200, 2 | 200..299 => FontWeight200,
@ -154,6 +164,7 @@ impl FontHandleMethods for FontHandle {
} }
} }
} }
}
fn clone_with_style(&self, fn clone_with_style(&self,
fctx: &FontContextHandle, fctx: &FontContextHandle,
@ -162,8 +173,8 @@ impl FontHandleMethods for FontHandle {
FontSourceMem(ref buf) => { FontSourceMem(ref buf) => {
FontHandleMethods::new_from_buffer(fctx, buf.clone(), style) FontHandleMethods::new_from_buffer(fctx, buf.clone(), style)
} }
FontSourceFile(copy file) => { FontSourceFile(ref file) => {
FontHandle::new_from_file(fctx, file, style) FontHandle::new_from_file(fctx, copy *file, style)
} }
} }
} }
@ -171,6 +182,7 @@ impl FontHandleMethods for FontHandle {
pub fn glyph_index(&self, pub fn glyph_index(&self,
codepoint: char) -> Option<GlyphIndex> { codepoint: char) -> Option<GlyphIndex> {
assert!(self.face.is_not_null()); assert!(self.face.is_not_null());
unsafe {
let idx = FT_Get_Char_Index(self.face, codepoint as FT_ULong); let idx = FT_Get_Char_Index(self.face, codepoint as FT_ULong);
return if idx != 0 as FT_UInt { return if idx != 0 as FT_UInt {
Some(idx as GlyphIndex) Some(idx as GlyphIndex)
@ -179,13 +191,14 @@ impl FontHandleMethods for FontHandle {
None None
}; };
} }
}
pub fn glyph_h_advance(&self, pub fn glyph_h_advance(&self,
glyph: GlyphIndex) -> Option<FractionalPixel> { glyph: GlyphIndex) -> Option<FractionalPixel> {
assert!(self.face.is_not_null()); assert!(self.face.is_not_null());
unsafe {
let res = FT_Load_Glyph(self.face, glyph as FT_UInt, 0); let res = FT_Load_Glyph(self.face, glyph as FT_UInt, 0);
if res.succeeded() { if res.succeeded() {
unsafe {
let void_glyph = (*self.face).glyph; let void_glyph = (*self.face).glyph;
let slot: FT_GlyphSlot = cast::transmute(void_glyph); let slot: FT_GlyphSlot = cast::transmute(void_glyph);
assert!(slot.is_not_null()); assert!(slot.is_not_null());
@ -194,12 +207,12 @@ impl FontHandleMethods for FontHandle {
debug!("h_advance for %? is %?", glyph, advance); debug!("h_advance for %? is %?", glyph, advance);
let advance = advance as i32; let advance = advance as i32;
return Some(fixed_to_float_ft(advance) as FractionalPixel); return Some(fixed_to_float_ft(advance) as FractionalPixel);
}
} else { } else {
debug!("Unable to load glyph %?. reason: %?", glyph, res); debug!("Unable to load glyph %?. reason: %?", glyph, res);
return None; return None;
} }
} }
}
pub fn get_metrics(&self) -> FontMetrics { pub fn get_metrics(&self) -> FontMetrics {
/* TODO(Issue #76): complete me */ /* TODO(Issue #76): complete me */
@ -229,19 +242,22 @@ impl FontHandleMethods for FontHandle {
} }
} }
pub impl<'self> FontHandle { impl<'self> FontHandle {
priv fn set_char_size(face: FT_Face, pt_size: float) -> Result<(), ()>{ priv fn set_char_size(face: FT_Face, pt_size: float) -> Result<(), ()>{
let char_width = float_to_fixed_ft(pt_size) as FT_F26Dot6; let char_width = float_to_fixed_ft(pt_size) as FT_F26Dot6;
let char_height = float_to_fixed_ft(pt_size) as FT_F26Dot6; let char_height = float_to_fixed_ft(pt_size) as FT_F26Dot6;
let h_dpi = 72; let h_dpi = 72;
let v_dpi = 72; let v_dpi = 72;
unsafe {
let result = FT_Set_Char_Size(face, char_width, char_height, h_dpi, v_dpi); let result = FT_Set_Char_Size(face, char_width, char_height, h_dpi, v_dpi);
if result.succeeded() { Ok(()) } else { Err(()) } if result.succeeded() { Ok(()) } else { Err(()) }
} }
}
pub fn new_from_file(fctx: &FontContextHandle, file: ~str, pub fn new_from_file(fctx: &FontContextHandle, file: ~str,
style: &SpecifiedFontStyle) -> Result<FontHandle, ()> { style: &SpecifiedFontStyle) -> Result<FontHandle, ()> {
unsafe {
let ft_ctx: FT_Library = fctx.ctx.ctx; let ft_ctx: FT_Library = fctx.ctx.ctx;
if ft_ctx.is_null() { return Err(()); } if ft_ctx.is_null() { return Err(()); }
@ -264,9 +280,11 @@ pub impl<'self> FontHandle {
Err(()) Err(())
} }
} }
}
pub fn new_from_file_unstyled(fctx: &FontContextHandle, file: ~str) pub fn new_from_file_unstyled(fctx: &FontContextHandle, file: ~str)
-> Result<FontHandle, ()> { -> Result<FontHandle, ()> {
unsafe {
let ft_ctx: FT_Library = fctx.ctx.ctx; let ft_ctx: FT_Library = fctx.ctx.ctx;
if ft_ctx.is_null() { return Err(()); } if ft_ctx.is_null() { return Err(()); }
@ -286,6 +304,7 @@ pub impl<'self> FontHandle {
handle: *fctx handle: *fctx
}) })
} }
}
priv fn get_face_rec(&'self self) -> &'self FT_FaceRec { priv fn get_face_rec(&'self self) -> &'self FT_FaceRec {
unsafe { unsafe {

View file

@ -8,8 +8,9 @@ use font_context::FontContextHandleMethods;
use platform::font_list::path_from_identifier; use platform::font_list::path_from_identifier;
use freetype::freetype::{FTErrorMethods, FT_Library}; use freetype::freetype::{FTErrorMethods, FT_Library};
use freetype::freetype::bindgen::{FT_Done_FreeType, FT_Init_FreeType}; use freetype::freetype::{FT_Done_FreeType, FT_Init_FreeType};
use std::ptr;
struct FreeTypeLibraryHandle { struct FreeTypeLibraryHandle {
ctx: FT_Library, ctx: FT_Library,
@ -18,16 +19,19 @@ struct FreeTypeLibraryHandle {
impl Drop for FreeTypeLibraryHandle { impl Drop for FreeTypeLibraryHandle {
fn finalize(&self) { fn finalize(&self) {
assert!(self.ctx.is_not_null()); assert!(self.ctx.is_not_null());
unsafe {
FT_Done_FreeType(self.ctx); FT_Done_FreeType(self.ctx);
} }
}
} }
pub struct FontContextHandle { pub struct FontContextHandle {
ctx: @FreeTypeLibraryHandle, ctx: @FreeTypeLibraryHandle,
} }
pub impl FontContextHandle { impl FontContextHandle {
pub fn new() -> FontContextHandle { pub fn new() -> FontContextHandle {
unsafe {
let ctx: FT_Library = ptr::null(); let ctx: FT_Library = ptr::null();
let result = FT_Init_FreeType(ptr::to_unsafe_ptr(&ctx)); let result = FT_Init_FreeType(ptr::to_unsafe_ptr(&ctx));
if !result.succeeded() { fail!(); } if !result.succeeded() { fail!(); }
@ -36,6 +40,7 @@ pub impl FontContextHandle {
ctx: @FreeTypeLibraryHandle { ctx: ctx }, ctx: @FreeTypeLibraryHandle { ctx: ctx },
} }
} }
}
} }
impl FontContextHandleMethods for FontContextHandle { impl FontContextHandleMethods for FontContextHandle {

View file

@ -9,7 +9,7 @@ use fontconfig::fontconfig::{
FcChar8, FcResultMatch, FcSetSystem, FcPattern, FcChar8, FcResultMatch, FcSetSystem, FcPattern,
FcResultNoMatch, FcMatchPattern, FC_SLANT_ITALIC, FC_WEIGHT_BOLD FcResultNoMatch, FcMatchPattern, FC_SLANT_ITALIC, FC_WEIGHT_BOLD
}; };
use fontconfig::fontconfig::bindgen::{ use fontconfig::fontconfig::{
FcConfigGetCurrent, FcConfigGetFonts, FcPatternGetString, FcConfigGetCurrent, FcConfigGetFonts, FcPatternGetString,
FcPatternDestroy, FcFontSetDestroy, FcConfigSubstitute, FcPatternDestroy, FcFontSetDestroy, FcConfigSubstitute,
FcDefaultSubstitute, FcPatternCreate, FcPatternAddString, FcPatternAddInteger, FcDefaultSubstitute, FcPatternCreate, FcPatternAddString, FcPatternAddInteger,
@ -24,20 +24,23 @@ 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 core::hashmap::HashMap; use std::hashmap::HashMap;
use core::libc::c_int; use std::libc;
use core::ptr::Ptr; use std::libc::c_int;
use std::ptr;
use std::str;
use std::uint;
pub struct FontListHandle { pub struct FontListHandle {
fctx: FontContextHandle, fctx: FontContextHandle,
} }
pub impl FontListHandle { impl FontListHandle {
pub fn new(fctx: &FontContextHandle) -> FontListHandle { pub fn new(fctx: &FontContextHandle) -> FontListHandle {
FontListHandle { fctx: fctx.clone() } FontListHandle { fctx: fctx.clone() }
} }
fn get_available_families(&self) -> FontFamilyMap { pub fn get_available_families(&self) -> FontFamilyMap {
let mut family_map : FontFamilyMap = HashMap::new(); let mut family_map : FontFamilyMap = HashMap::new();
unsafe { unsafe {
let config = FcConfigGetCurrent(); let config = FcConfigGetCurrent();
@ -60,12 +63,12 @@ pub impl FontListHandle {
return family_map; return family_map;
} }
fn load_variations_for_family(&self, family: @mut FontFamily) { pub fn load_variations_for_family(&self, family: @mut FontFamily) {
debug!("getting variations for %?", family); debug!("getting variations for %?", family);
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 = ptr::to_unsafe_ptr(&font_set);
unsafe {
let pattern = FcPatternCreate(); let pattern = FcPatternCreate();
assert!(pattern.is_not_null()); assert!(pattern.is_not_null());
do str::as_c_str("family") |FC_FAMILY| { do str::as_c_str("family") |FC_FAMILY| {
@ -126,7 +129,7 @@ pub impl FontListHandle {
} }
} }
fn get_last_resort_font_families() -> ~[~str] { pub fn get_last_resort_font_families() -> ~[~str] {
~[~"Arial"] ~[~"Arial"]
} }
} }
@ -137,8 +140,10 @@ struct AutoPattern {
impl Drop for AutoPattern { impl Drop for AutoPattern {
fn finalize(&self) { fn finalize(&self) {
unsafe {
FcPatternDestroy(self.pattern); FcPatternDestroy(self.pattern);
} }
}
} }
pub fn path_from_identifier(name: ~str, style: &UsedFontStyle) -> Result<~str, ()> { pub fn path_from_identifier(name: ~str, style: &UsedFontStyle) -> Result<~str, ()> {

View file

@ -28,6 +28,9 @@ use core_text::font_descriptor::{SymbolicTraitAccessors, TraitAccessors};
use core_text::font_descriptor::{kCTFontDefaultOrientation}; use core_text::font_descriptor::{kCTFontDefaultOrientation};
use core_text; use core_text;
use std::ptr;
use std::vec;
pub struct FontTable { pub struct FontTable {
data: CFData, data: CFData,
} }
@ -37,8 +40,8 @@ impl Drop for FontTable {
fn finalize(&self) {} fn finalize(&self) {}
} }
pub impl FontTable { impl FontTable {
fn wrap(data: CFData) -> FontTable { pub fn wrap(data: CFData) -> FontTable {
FontTable { data: data } FontTable { data: data }
} }
} }
@ -54,15 +57,15 @@ pub struct FontHandle {
ctfont: CTFont, ctfont: CTFont,
} }
pub impl FontHandle { impl FontHandle {
fn new_from_CTFont(_: &FontContextHandle, ctfont: CTFont) -> Result<FontHandle, ()> { pub fn new_from_CTFont(_: &FontContextHandle, ctfont: CTFont) -> Result<FontHandle, ()> {
Ok(FontHandle { Ok(FontHandle {
mut cgfont: None, cgfont: None,
ctfont: ctfont, ctfont: ctfont,
}) })
} }
fn get_CGFont(&mut self) -> CGFont { pub fn get_CGFont(&mut self) -> CGFont {
match self.cgfont { match self.cgfont {
Some(ref font) => font.clone(), Some(ref font) => font.clone(),
None => { None => {

View file

@ -8,11 +8,13 @@ use platform::macos::font::FontHandle;
use core_text; use core_text;
use std::result;
pub struct FontContextHandle { pub struct FontContextHandle {
ctx: () ctx: ()
} }
pub impl FontContextHandle { impl FontContextHandle {
// this is a placeholder until NSFontManager or whatever is bound in here. // this is a placeholder until NSFontManager or whatever is bound in here.
pub fn new() -> FontContextHandle { pub fn new() -> FontContextHandle {
FontContextHandle { ctx: () } FontContextHandle { ctx: () }

View file

@ -15,20 +15,21 @@ use core_text::font_collection::CTFontCollectionMethods;
use core_text::font_descriptor::CTFontDescriptorRef; use core_text::font_descriptor::CTFontDescriptorRef;
use core_text; use core_text;
use core::hashmap::HashMap; use std::hashmap::HashMap;
use std::result;
pub struct FontListHandle { pub struct FontListHandle {
fctx: FontContextHandle, fctx: FontContextHandle,
} }
pub impl FontListHandle { impl FontListHandle {
fn new(fctx: &FontContextHandle) -> FontListHandle { pub fn new(fctx: &FontContextHandle) -> FontListHandle {
FontListHandle { FontListHandle {
fctx: fctx.clone() fctx: fctx.clone()
} }
} }
fn get_available_families(&self) -> FontFamilyMap { pub fn get_available_families(&self) -> FontFamilyMap {
let family_names: CFArray<CFStringRef> = core_text::font_collection::get_family_names(); let family_names: CFArray<CFStringRef> = core_text::font_collection::get_family_names();
let mut family_map: FontFamilyMap = HashMap::new(); let mut family_map: FontFamilyMap = HashMap::new();
for family_names.each |&strref: &CFStringRef| { for family_names.each |&strref: &CFStringRef| {
@ -41,7 +42,7 @@ pub impl FontListHandle {
return family_map; return family_map;
} }
fn load_variations_for_family(&self, family: @mut FontFamily) { pub fn load_variations_for_family(&self, family: @mut FontFamily) {
debug!("Looking for faces of family: %s", family.family_name); debug!("Looking for faces of family: %s", family.family_name);
let family_collection = core_text::font_collection::create_for_family(family.family_name); let family_collection = core_text::font_collection::create_for_family(family.family_name);
@ -56,7 +57,7 @@ pub impl FontListHandle {
} }
} }
fn get_last_resort_font_families() -> ~[~str] { pub fn get_last_resort_font_families() -> ~[~str] {
~[~"Arial Unicode MS",~"Arial"] ~[~"Arial Unicode MS",~"Arial"]
} }
} }

View file

@ -10,13 +10,12 @@ use opts::Opts;
use azure::azure_hl::{B8G8R8A8, Color, ColorPattern, DrawOptions}; 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::AzFloat; use azure::AzFloat;
use core::libc::types::common::c99::uint16_t; use std::libc::types::common::c99::uint16_t;
use geom::point::Point2D; use geom::point::Point2D;
use geom::rect::Rect; use geom::rect::Rect;
use geom::size::Size2D; use geom::size::Size2D;
use servo_net::image::base::Image; use servo_net::image::base::Image;
use std::arc; use extra::arc::ARC;
use std::arc::ARC;
pub struct RenderContext<'self> { pub struct RenderContext<'self> {
canvas: &'self LayerBuffer, canvas: &'self LayerBuffer,
@ -24,7 +23,7 @@ pub struct RenderContext<'self> {
opts: &'self Opts opts: &'self Opts
} }
pub impl<'self> RenderContext<'self> { impl<'self> RenderContext<'self> {
pub fn get_draw_target(&self) -> &'self DrawTarget { pub fn get_draw_target(&self) -> &'self DrawTarget {
&self.canvas.draw_target &self.canvas.draw_target
} }
@ -52,7 +51,7 @@ pub impl<'self> RenderContext<'self> {
} }
pub fn draw_image(&self, bounds: Rect<Au>, image: ARC<~Image>) { pub fn draw_image(&self, bounds: Rect<Au>, image: ARC<~Image>) {
let image = arc::get(&image); let image = image.get();
let size = Size2D(image.width as i32, image.height as i32); let size = Size2D(image.width as i32, image.height as i32);
let stride = image.width * 4; let stride = image.width * 4;
@ -72,7 +71,7 @@ pub impl<'self> RenderContext<'self> {
draw_options); draw_options);
} }
fn clear(&self) { pub fn clear(&self) {
let pattern = ColorPattern(Color(1.0, 1.0, 1.0, 1.0)); let pattern = ColorPattern(Color(1.0, 1.0, 1.0, 1.0));
let rect = Rect(Point2D(self.canvas.rect.origin.x as AzFloat, let rect = Rect(Point2D(self.canvas.rect.origin.x as AzFloat,
self.canvas.rect.origin.y as AzFloat), self.canvas.rect.origin.y as AzFloat),
@ -84,12 +83,12 @@ pub impl<'self> RenderContext<'self> {
} }
trait to_float { trait to_float {
fn to_float(self) -> float; fn to_float(&self) -> float;
} }
impl to_float for u8 { impl to_float for u8 {
fn to_float(self) -> float { fn to_float(&self) -> float {
(self as float) / 255f (*self as float) / 255f
} }
} }

View file

@ -17,8 +17,9 @@ use geom::rect::Rect;
use opts::Opts; use opts::Opts;
use render_context::RenderContext; use render_context::RenderContext;
use core::cell::Cell; use std::cell::Cell;
use core::comm::{Chan, Port, SharedChan}; use std::comm::{Chan, Port, SharedChan};
use std::uint;
use servo_util::time::{ProfilerChan, profile}; use servo_util::time::{ProfilerChan, profile};
use servo_util::time; use servo_util::time;
@ -62,9 +63,9 @@ pub fn create_render_task<C: RenderListener + Owned>(port: Port<Msg<C>>,
compositor: C, compositor: C,
opts: Opts, opts: Opts,
profiler_chan: ProfilerChan) { profiler_chan: ProfilerChan) {
let compositor_cell = Cell(compositor); let compositor_cell = Cell::new(compositor);
let opts_cell = Cell(opts); let opts_cell = Cell::new(opts);
let port = Cell(port); let port = Cell::new(port);
do spawn { do spawn {
let compositor = compositor_cell.take(); let compositor = compositor_cell.take();

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 std::vec;
use geom::size::Size2D; use geom::size::Size2D;
#[deriving(Eq)] #[deriving(Eq)]

View file

@ -2,19 +2,20 @@
* 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 servo_util::range::Range;
use servo_util::vec::*; use servo_util::vec::*;
use servo_util::range::Range; use servo_util::range::Range;
use geometry::Au; use geometry::Au;
use geometry; use geometry;
use core::cmp::{Ord, Eq}; use std::cmp::{Ord, Eq};
use core::num::NumCast; use std::num::NumCast;
use core::u16; use std::u16;
use core; use std::vec;
use std::uint;
use std::util;
use geom::point::Point2D; use geom::point::Point2D;
use std::sort; use extra::sort;
/// GlyphEntry is a port of Gecko's CompressedGlyph scheme for storing glyph data compactly. /// GlyphEntry is a port of Gecko's CompressedGlyph scheme for storing glyph data compactly.
/// ///
@ -403,11 +404,11 @@ impl<'self> 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] = ~[];
core::util::swap(&mut self.detail_lookup, &mut unsorted_records); util::swap(&mut self.detail_lookup, &mut unsorted_records);
let mut mut_records : ~[DetailedGlyphRecord] = unsorted_records; let mut mut_records : ~[DetailedGlyphRecord] = unsorted_records;
sort::quick_sort3(mut_records); sort::quick_sort3(mut_records);
let mut sorted_records = mut_records; let mut sorted_records = mut_records;
core::util::swap(&mut self.detail_lookup, &mut sorted_records); util::swap(&mut self.detail_lookup, &mut sorted_records);
self.lookup_is_sorted = true; self.lookup_is_sorted = true;
} }
@ -468,7 +469,8 @@ impl<'self> GlyphInfo<'self> {
} }
#[inline(always)] #[inline(always)]
fn advance(self) -> Au { // FIXME: Resolution conflicts with IteratorUtil trait so adding trailing _
fn advance_(self) -> Au {
match self { match self {
SimpleGlyphInfo(store, entry_i) => store.entry_buffer[entry_i].advance(), SimpleGlyphInfo(store, entry_i) => store.entry_buffer[entry_i].advance(),
DetailGlyphInfo(store, entry_i, detail_j) => { DetailGlyphInfo(store, entry_i, detail_j) => {
@ -507,10 +509,10 @@ pub struct GlyphStore {
detail_store: DetailedGlyphStore, detail_store: DetailedGlyphStore,
} }
pub impl<'self> GlyphStore { impl<'self> GlyphStore {
// Initializes the glyph store, but doesn't actually shape anything. // Initializes the glyph store, but doesn't actually shape anything.
// Use the set_glyph, set_glyphs() methods to store glyph data. // Use the set_glyph, set_glyphs() methods to store glyph data.
fn new(length: uint) -> GlyphStore { pub fn new(length: uint) -> GlyphStore {
assert!(length > 0); assert!(length > 0);
GlyphStore { GlyphStore {
@ -519,11 +521,11 @@ pub impl<'self> GlyphStore {
} }
} }
fn finalize_changes(&mut self) { pub fn finalize_changes(&mut self) {
self.detail_store.ensure_sorted(); self.detail_store.ensure_sorted();
} }
fn add_glyph_for_char_index(&mut self, i: uint, data: &GlyphData) { pub fn add_glyph_for_char_index(&mut self, i: uint, data: &GlyphData) {
fn glyph_is_compressible(data: &GlyphData) -> bool { fn glyph_is_compressible(data: &GlyphData) -> bool {
is_simple_glyph_id(data.index) is_simple_glyph_id(data.index)
&& is_simple_advance(data.advance) && is_simple_advance(data.advance)
@ -547,7 +549,7 @@ pub impl<'self> GlyphStore {
self.entry_buffer[i] = entry; self.entry_buffer[i] = entry;
} }
fn add_glyphs_for_char_index(&mut self, i: uint, data_for_glyphs: &[GlyphData]) { pub fn add_glyphs_for_char_index(&mut self, i: uint, data_for_glyphs: &[GlyphData]) {
assert!(i < self.entry_buffer.len()); assert!(i < self.entry_buffer.len());
assert!(data_for_glyphs.len() > 0); assert!(data_for_glyphs.len() > 0);
@ -576,7 +578,7 @@ pub impl<'self> GlyphStore {
} }
// used when a character index has no associated glyph---for example, a ligature continuation. // used when a character index has no associated glyph---for example, a ligature continuation.
fn add_nonglyph_for_char_index(&mut self, i: uint, cluster_start: bool, ligature_start: bool) { pub fn add_nonglyph_for_char_index(&mut self, i: uint, cluster_start: bool, ligature_start: bool) {
assert!(i < self.entry_buffer.len()); assert!(i < self.entry_buffer.len());
let entry = GlyphEntry::complex(cluster_start, ligature_start, 0); let entry = GlyphEntry::complex(cluster_start, ligature_start, 0);
@ -585,7 +587,7 @@ pub impl<'self> GlyphStore {
self.entry_buffer[i] = entry; self.entry_buffer[i] = entry;
} }
fn iter_glyphs_for_char_index(&'self self, pub fn iter_glyphs_for_char_index(&'self self,
i: uint, i: uint,
cb: &fn(uint, &GlyphInfo<'self>) -> bool) cb: &fn(uint, &GlyphInfo<'self>) -> bool)
-> bool { -> bool {
@ -609,7 +611,7 @@ pub impl<'self> GlyphStore {
true true
} }
fn iter_glyphs_for_char_range(&'self self, pub fn iter_glyphs_for_char_range(&'self self,
range: &Range, range: &Range,
callback: &fn(uint, &GlyphInfo<'self>) -> bool) callback: &fn(uint, &GlyphInfo<'self>) -> bool)
-> bool { -> bool {
@ -631,7 +633,7 @@ pub impl<'self> GlyphStore {
true true
} }
fn iter_all_glyphs(&'self self, cb: &fn(uint, &GlyphInfo<'self>) -> bool) -> bool { pub fn iter_all_glyphs(&'self self, cb: &fn(uint, &GlyphInfo<'self>) -> bool) -> bool {
for uint::range(0, self.entry_buffer.len()) |i| { for uint::range(0, self.entry_buffer.len()) |i| {
if !self.iter_glyphs_for_char_index(i, cb) { if !self.iter_glyphs_for_char_index(i, cb) {
break; break;
@ -642,56 +644,56 @@ pub impl<'self> GlyphStore {
} }
// getter methods // getter methods
fn char_is_space(&self, i: uint) -> bool { pub fn char_is_space(&self, i: uint) -> bool {
assert!(i < self.entry_buffer.len()); assert!(i < self.entry_buffer.len());
self.entry_buffer[i].char_is_space() self.entry_buffer[i].char_is_space()
} }
fn char_is_tab(&self, i: uint) -> bool { pub fn char_is_tab(&self, i: uint) -> bool {
assert!(i < self.entry_buffer.len()); assert!(i < self.entry_buffer.len());
self.entry_buffer[i].char_is_tab() self.entry_buffer[i].char_is_tab()
} }
fn char_is_newline(&self, i: uint) -> bool { pub fn char_is_newline(&self, i: uint) -> bool {
assert!(i < self.entry_buffer.len()); assert!(i < self.entry_buffer.len());
self.entry_buffer[i].char_is_newline() self.entry_buffer[i].char_is_newline()
} }
fn is_ligature_start(&self, i: uint) -> bool { pub fn is_ligature_start(&self, i: uint) -> bool {
assert!(i < self.entry_buffer.len()); assert!(i < self.entry_buffer.len());
self.entry_buffer[i].is_ligature_start() self.entry_buffer[i].is_ligature_start()
} }
fn is_cluster_start(&self, i: uint) -> bool { pub fn is_cluster_start(&self, i: uint) -> bool {
assert!(i < self.entry_buffer.len()); assert!(i < self.entry_buffer.len());
self.entry_buffer[i].is_cluster_start() self.entry_buffer[i].is_cluster_start()
} }
fn can_break_before(&self, i: uint) -> BreakType { pub fn can_break_before(&self, i: uint) -> BreakType {
assert!(i < self.entry_buffer.len()); assert!(i < self.entry_buffer.len());
self.entry_buffer[i].can_break_before() self.entry_buffer[i].can_break_before()
} }
// setter methods // setter methods
fn set_char_is_space(&mut self, i: uint) { pub fn set_char_is_space(&mut self, i: uint) {
assert!(i < self.entry_buffer.len()); assert!(i < self.entry_buffer.len());
let entry = self.entry_buffer[i]; let entry = self.entry_buffer[i];
self.entry_buffer[i] = entry.set_char_is_space(); self.entry_buffer[i] = entry.set_char_is_space();
} }
fn set_char_is_tab(&mut self, i: uint) { pub fn set_char_is_tab(&mut self, i: uint) {
assert!(i < self.entry_buffer.len()); assert!(i < self.entry_buffer.len());
let entry = self.entry_buffer[i]; let entry = self.entry_buffer[i];
self.entry_buffer[i] = entry.set_char_is_tab(); self.entry_buffer[i] = entry.set_char_is_tab();
} }
fn set_char_is_newline(&mut self, i: uint) { pub fn set_char_is_newline(&mut self, i: uint) {
assert!(i < self.entry_buffer.len()); assert!(i < self.entry_buffer.len());
let entry = self.entry_buffer[i]; let entry = self.entry_buffer[i];
self.entry_buffer[i] = entry.set_char_is_newline(); self.entry_buffer[i] = entry.set_char_is_newline();
} }
fn set_can_break_before(&mut self, i: uint, t: BreakType) { pub fn set_can_break_before(&mut self, i: uint, t: BreakType) {
assert!(i < self.entry_buffer.len()); assert!(i < self.entry_buffer.len());
let entry = self.entry_buffer[i]; let entry = self.entry_buffer[i];
self.entry_buffer[i] = entry.set_can_break_before(t); self.entry_buffer[i] = entry.set_can_break_before(t);

View file

@ -4,8 +4,6 @@
extern mod harfbuzz; extern mod harfbuzz;
use geom::Point2D;
use font::{Font, FontHandleMethods, FontTableMethods, FontTableTag}; use font::{Font, FontHandleMethods, FontTableMethods, FontTableTag};
use geometry::Au; use geometry::Au;
use platform::font::FontTable; use platform::font::FontTable;
@ -14,45 +12,37 @@ use text::shaping::ShaperMethods;
use servo_util::range::Range; use servo_util::range::Range;
use text::util::{float_to_fixed, fixed_to_float, fixed_to_rounded_int}; use text::util::{float_to_fixed, fixed_to_float, fixed_to_rounded_int};
use core::cast::transmute; use std::cast::transmute;
use core::libc::{c_uint, c_int, c_void, c_char}; use std::libc::{c_uint, c_int, c_void, c_char};
use core::ptr::null; use std::ptr;
use core::util::ignore; use std::ptr::null;
use std::str;
use std::uint;
use std::util::ignore;
use std::vec;
use geom::Point2D; use geom::Point2D;
use harfbuzz::bindgen::{hb_blob_create, hb_face_create_for_tables}; use harfbuzz::{hb_blob_create, hb_face_create_for_tables};
use harfbuzz::bindgen::{hb_buffer_add_utf8, hb_shape}; use harfbuzz::{hb_buffer_add_utf8};
use harfbuzz::bindgen::{hb_buffer_create}; use harfbuzz::{hb_buffer_get_glyph_positions};
use harfbuzz::bindgen::{hb_buffer_destroy, hb_buffer_add_utf8}; use harfbuzz::{hb_buffer_set_direction};
use harfbuzz::bindgen::{hb_buffer_get_glyph_infos}; use harfbuzz::{hb_buffer_destroy};
use harfbuzz::bindgen::{hb_buffer_get_glyph_positions}; use harfbuzz::{hb_face_destroy};
use harfbuzz::bindgen::{hb_buffer_get_glyph_positions}; use harfbuzz::{hb_font_create};
use harfbuzz::bindgen::{hb_buffer_set_direction}; use harfbuzz::{hb_font_destroy, hb_buffer_create};
use harfbuzz::bindgen::{hb_buffer_set_direction}; use harfbuzz::{hb_font_funcs_create};
use harfbuzz::bindgen::{hb_face_destroy, hb_font_create}; use harfbuzz::{hb_font_funcs_destroy};
use harfbuzz::bindgen::{hb_face_destroy}; use harfbuzz::{hb_font_funcs_set_glyph_func};
use harfbuzz::bindgen::{hb_font_create, hb_font_destroy}; use harfbuzz::{hb_font_funcs_set_glyph_h_advance_func};
use harfbuzz::bindgen::{hb_font_destroy, hb_buffer_create}; use harfbuzz::{hb_font_set_funcs};
use harfbuzz::bindgen::{hb_font_funcs_create, hb_font_funcs_destroy}; use harfbuzz::{hb_font_set_ppem};
use harfbuzz::bindgen::{hb_font_funcs_create}; use harfbuzz::{hb_font_set_scale};
use harfbuzz::bindgen::{hb_font_funcs_destroy}; use harfbuzz::{hb_shape, hb_buffer_get_glyph_infos};
use harfbuzz::bindgen::{hb_font_funcs_set_glyph_func};
use harfbuzz::bindgen::{hb_font_funcs_set_glyph_func};
use harfbuzz::bindgen::{hb_font_funcs_set_glyph_h_advance_func};
use harfbuzz::bindgen::{hb_font_funcs_set_glyph_h_advance_func};
use harfbuzz::bindgen::{hb_font_set_funcs};
use harfbuzz::bindgen::{hb_font_set_funcs};
use harfbuzz::bindgen::{hb_font_set_ppem, hb_font_set_scale};
use harfbuzz::bindgen::{hb_font_set_ppem};
use harfbuzz::bindgen::{hb_font_set_scale};
use harfbuzz::bindgen::{hb_shape, hb_buffer_get_glyph_infos};
use harfbuzz::{HB_MEMORY_MODE_READONLY, HB_DIRECTION_LTR, hb_blob_t};
use harfbuzz::{HB_MEMORY_MODE_READONLY, HB_DIRECTION_LTR}; use harfbuzz::{HB_MEMORY_MODE_READONLY, HB_DIRECTION_LTR};
use harfbuzz::{hb_blob_t, hb_face_t, hb_font_t, hb_font_funcs_t}; use harfbuzz::{hb_blob_t};
use harfbuzz::{hb_buffer_t, hb_codepoint_t, hb_bool_t}; use harfbuzz::{hb_bool_t};
use harfbuzz::{hb_face_t, hb_font_t}; use harfbuzz::{hb_face_t, hb_font_t};
use harfbuzz::{hb_font_funcs_t, hb_buffer_t, hb_codepoint_t}; use harfbuzz::{hb_font_funcs_t, hb_buffer_t, hb_codepoint_t};
use harfbuzz::{hb_glyph_info_t, hb_position_t}; use harfbuzz::{hb_glyph_info_t};
use harfbuzz::{hb_glyph_position_t, hb_glyph_info_t};
use harfbuzz::{hb_glyph_position_t}; use harfbuzz::{hb_glyph_position_t};
use harfbuzz::{hb_position_t, hb_tag_t}; use harfbuzz::{hb_position_t, hb_tag_t};
@ -74,6 +64,7 @@ pub struct ShapedGlyphEntry {
impl ShapedGlyphData { impl ShapedGlyphData {
pub fn new(buffer: *hb_buffer_t) -> ShapedGlyphData { pub fn new(buffer: *hb_buffer_t) -> ShapedGlyphData {
unsafe {
let glyph_count = 0; let glyph_count = 0;
let glyph_infos = hb_buffer_get_glyph_infos(buffer, &glyph_count); let glyph_infos = hb_buffer_get_glyph_infos(buffer, &glyph_count);
let glyph_count = glyph_count as uint; let glyph_count = glyph_count as uint;
@ -89,6 +80,7 @@ impl ShapedGlyphData {
pos_infos: pos_infos, pos_infos: pos_infos,
} }
} }
}
#[inline(always)] #[inline(always)]
fn byte_offset_of_glyph(&self, i: uint) -> uint { fn byte_offset_of_glyph(&self, i: uint) -> uint {
@ -152,6 +144,7 @@ pub struct Shaper {
#[unsafe_destructor] #[unsafe_destructor]
impl Drop for Shaper { impl Drop for Shaper {
fn finalize(&self) { fn finalize(&self) {
unsafe {
assert!(self.hb_face.is_not_null()); assert!(self.hb_face.is_not_null());
hb_face_destroy(self.hb_face); hb_face_destroy(self.hb_face);
@ -161,10 +154,12 @@ impl Drop for Shaper {
assert!(self.hb_funcs.is_not_null()); assert!(self.hb_funcs.is_not_null());
hb_font_funcs_destroy(self.hb_funcs); hb_font_funcs_destroy(self.hb_funcs);
} }
}
} }
impl Shaper { impl Shaper {
pub fn new(font: @mut Font) -> Shaper { pub fn new(font: @mut Font) -> Shaper {
unsafe {
// Indirection for Rust Issue #6248, dynamic freeze scope artifically extended // Indirection for Rust Issue #6248, dynamic freeze scope artifically extended
let font_ptr = { let font_ptr = {
let borrowed_font= &mut *font; let borrowed_font= &mut *font;
@ -198,6 +193,7 @@ impl Shaper {
hb_funcs: hb_funcs, hb_funcs: hb_funcs,
} }
} }
}
fn float_to_fixed(f: float) -> i32 { fn float_to_fixed(f: float) -> i32 {
float_to_fixed(16, f) float_to_fixed(16, f)
@ -216,6 +212,7 @@ impl ShaperMethods for Shaper {
/// Calculate the layout metrics associated with the given text when rendered in a specific /// Calculate the layout metrics associated with the given text when rendered in a specific
/// font. /// font.
fn shape_text(&self, text: &str, glyphs: &mut GlyphStore) { fn shape_text(&self, text: &str, glyphs: &mut GlyphStore) {
unsafe {
let hb_buffer: *hb_buffer_t = hb_buffer_create(); let hb_buffer: *hb_buffer_t = hb_buffer_create();
hb_buffer_set_direction(hb_buffer, HB_DIRECTION_LTR); hb_buffer_set_direction(hb_buffer, HB_DIRECTION_LTR);
@ -232,6 +229,7 @@ impl ShaperMethods for Shaper {
self.save_glyph_results(text, glyphs, hb_buffer); self.save_glyph_results(text, glyphs, hb_buffer);
hb_buffer_destroy(hb_buffer); hb_buffer_destroy(hb_buffer);
} }
}
} }
impl Shaper { impl Shaper {
@ -239,7 +237,7 @@ impl Shaper {
let glyph_data = ShapedGlyphData::new(buffer); let glyph_data = ShapedGlyphData::new(buffer);
let glyph_count = glyph_data.len(); let glyph_count = glyph_data.len();
let byte_max = text.len(); let byte_max = text.len();
let char_max = str::char_len(text); let char_max = text.char_len();
// GlyphStore records are indexed by character, not byte offset. // GlyphStore records are indexed by character, not byte offset.
// so, we must be careful to increment this when saving glyph entries. // so, we must be careful to increment this when saving glyph entries.
@ -267,7 +265,7 @@ impl Shaper {
let mut i = 0; let mut i = 0;
while i < byte_max { while i < byte_max {
byteToGlyph[i] = NO_GLYPH; byteToGlyph[i] = NO_GLYPH;
let range = str::char_range_at(text, i); let range = text.char_range_at(i);
ignore(range.ch); ignore(range.ch);
i = range.next; i = range.next;
} }
@ -292,7 +290,7 @@ impl Shaper {
debug!("(char idx): char->(glyph index):"); debug!("(char idx): char->(glyph index):");
let mut i = 0u; let mut i = 0u;
while i < byte_max { while i < byte_max {
let range = str::char_range_at(text, i); let range = text.char_range_at(i);
debug!("%u: %? --> %d", i, range.ch, byteToGlyph[i] as int); debug!("%u: %? --> %d", i, range.ch, byteToGlyph[i] as int);
i = range.next; i = range.next;
} }
@ -318,7 +316,7 @@ impl Shaper {
// find a range of chars corresponding to this glyph, plus // find a range of chars corresponding to this glyph, plus
// any trailing chars that do not have associated glyphs. // any trailing chars that do not have associated glyphs.
while char_byte_span.end() < byte_max { while char_byte_span.end() < byte_max {
let range = str::char_range_at(text, char_byte_span.end()); let range = text.char_range_at(char_byte_span.end());
ignore(range.ch); ignore(range.ch);
char_byte_span.extend_to(range.next); char_byte_span.extend_to(range.next);
@ -329,7 +327,7 @@ impl Shaper {
byteToGlyph[char_byte_span.end()] == NO_GLYPH { byteToGlyph[char_byte_span.end()] == NO_GLYPH {
debug!("Extending char byte span to include byte offset=%u with no associated \ debug!("Extending char byte span to include byte offset=%u with no associated \
glyph", char_byte_span.end()); glyph", char_byte_span.end());
let range = str::char_range_at(text, char_byte_span.end()); let range = text.char_range_at(char_byte_span.end());
ignore(range.ch); ignore(range.ch);
char_byte_span.extend_to(range.next); char_byte_span.extend_to(range.next);
} }
@ -404,7 +402,7 @@ impl Shaper {
// extend, clipping at end of text range. // extend, clipping at end of text range.
while covered_byte_span.end() < byte_max while covered_byte_span.end() < byte_max
&& byteToGlyph[covered_byte_span.end()] == NO_GLYPH { && byteToGlyph[covered_byte_span.end()] == NO_GLYPH {
let range = str::char_range_at(text, covered_byte_span.end()); let range = text.char_range_at(covered_byte_span.end());
ignore(range.ch); ignore(range.ch);
covered_byte_span.extend_to(range.next); covered_byte_span.extend_to(range.next);
} }
@ -457,7 +455,7 @@ impl Shaper {
// set the other chars, who have no glyphs // set the other chars, who have no glyphs
let mut i = covered_byte_span.begin(); let mut i = covered_byte_span.begin();
loop { loop {
let range = str::char_range_at(text, i); let range = text.char_range_at(i);
ignore(range.ch); ignore(range.ch);
i = range.next; i = range.next;
if i >= covered_byte_span.end() { break; } if i >= covered_byte_span.end() { break; }

View file

@ -42,9 +42,9 @@ impl SendableTextRun {
} }
} }
pub impl<'self> TextRun { impl<'self> TextRun {
fn new(font: @mut Font, text: ~str, underline: bool) -> TextRun { pub fn new(font: @mut Font, text: ~str, underline: bool) -> TextRun {
let mut glyph_store = GlyphStore::new(str::char_len(text)); let mut glyph_store = GlyphStore::new(text.char_len());
TextRun::compute_potential_breaks(text, &mut glyph_store); TextRun::compute_potential_breaks(text, &mut glyph_store);
do profile(time::LayoutShapingCategory, font.profiler_chan.clone()) { do profile(time::LayoutShapingCategory, font.profiler_chan.clone()) {
font.shape_text(text, &mut glyph_store); font.shape_text(text, &mut glyph_store);
@ -59,18 +59,18 @@ pub impl<'self> TextRun {
return run; return run;
} }
fn teardown(&self) { pub fn teardown(&self) {
self.font.teardown(); self.font.teardown();
} }
fn compute_potential_breaks(text: &str, glyphs: &mut GlyphStore) { pub fn compute_potential_breaks(text: &str, glyphs: &mut GlyphStore) {
// TODO(Issue #230): do a better job. See Gecko's LineBreaker. // TODO(Issue #230): do a better job. See Gecko's LineBreaker.
let mut byte_i = 0u; let mut byte_i = 0u;
let mut char_j = 0u; let mut char_j = 0u;
let mut prev_is_whitespace = false; let mut prev_is_whitespace = false;
while byte_i < text.len() { while byte_i < text.len() {
let range = str::char_range_at(text, byte_i); let range = text.char_range_at(byte_i);
let ch = range.ch; let ch = range.ch;
let next = range.next; let next = range.next;
// set char properties. // set char properties.
@ -114,10 +114,10 @@ pub impl<'self> TextRun {
} }
} }
fn char_len(&self) -> uint { self.glyphs.entry_buffer.len() } pub fn char_len(&self) -> uint { self.glyphs.entry_buffer.len() }
fn glyphs(&'self self) -> &'self GlyphStore { &self.glyphs } pub fn glyphs(&'self self) -> &'self GlyphStore { &self.glyphs }
fn range_is_trimmable_whitespace(&self, range: &Range) -> bool { pub fn range_is_trimmable_whitespace(&self, range: &Range) -> bool {
for range.eachi |i| { for range.eachi |i| {
if !self.glyphs.char_is_space(i) && if !self.glyphs.char_is_space(i) &&
!self.glyphs.char_is_tab(i) && !self.glyphs.char_is_tab(i) &&
@ -126,11 +126,11 @@ pub impl<'self> TextRun {
return true; return true;
} }
fn metrics_for_range(&self, range: &Range) -> RunMetrics { pub fn metrics_for_range(&self, range: &Range) -> RunMetrics {
self.font.measure_text(self, range) self.font.measure_text(self, range)
} }
fn min_width_for_range(&self, range: &Range) -> Au { pub fn min_width_for_range(&self, range: &Range) -> Au {
let mut max_piece_width = Au(0); let mut max_piece_width = Au(0);
debug!("iterating outer range %?", range); debug!("iterating outer range %?", range);
for self.iter_indivisible_pieces_for_range(range) |piece_range| { for self.iter_indivisible_pieces_for_range(range) |piece_range| {
@ -141,7 +141,7 @@ pub impl<'self> TextRun {
return max_piece_width; return max_piece_width;
} }
fn iter_natural_lines_for_range(&self, range: &Range, f: &fn(&Range) -> bool) -> bool { pub fn iter_natural_lines_for_range(&self, range: &Range, f: &fn(&Range) -> bool) -> bool {
let mut clump = Range::new(range.begin(), 0); let mut clump = Range::new(range.begin(), 0);
let mut in_clump = false; let mut in_clump = false;
@ -168,7 +168,7 @@ pub impl<'self> TextRun {
true true
} }
fn iter_indivisible_pieces_for_range(&self, range: &Range, f: &fn(&Range) -> bool) -> bool { pub fn iter_indivisible_pieces_for_range(&self, range: &Range, f: &fn(&Range) -> bool) -> bool {
let mut clump = Range::new(range.begin(), 0); let mut clump = Range::new(range.begin(), 0);
loop { loop {

View file

@ -38,7 +38,7 @@ pub fn transform_text(text: &str, mode: CompressionMode, incoming_whitespace: bo
let mut out_str: ~str = ~""; let mut out_str: ~str = ~"";
let out_whitespace = match mode { let out_whitespace = match mode {
CompressNone | DiscardNewline => { CompressNone | DiscardNewline => {
for str::each_char(text) |ch: char| { for text.iter().advance |ch: char| {
if is_discardable_char(ch, mode) { if is_discardable_char(ch, mode) {
// TODO: record skipped char // TODO: record skipped char
} else { } else {
@ -46,7 +46,7 @@ pub fn transform_text(text: &str, mode: CompressionMode, incoming_whitespace: bo
if ch == '\t' { if ch == '\t' {
// TODO: set "has tab" flag // TODO: set "has tab" flag
} }
str::push_char(&mut out_str, ch); out_str.push_char(ch);
} }
} }
text.len() > 0 && is_in_whitespace(text.char_at_reverse(0), mode) text.len() > 0 && is_in_whitespace(text.char_at_reverse(0), mode)
@ -54,7 +54,7 @@ pub fn transform_text(text: &str, mode: CompressionMode, incoming_whitespace: bo
CompressWhitespace | CompressWhitespaceNewline => { CompressWhitespace | CompressWhitespaceNewline => {
let mut in_whitespace: bool = incoming_whitespace; let mut in_whitespace: bool = incoming_whitespace;
for str::each_char(text) |ch: char| { for text.iter().advance |ch: char| {
// TODO: discard newlines between CJK chars // TODO: discard newlines between CJK chars
let mut next_in_whitespace: bool = is_in_whitespace(ch, mode); let mut next_in_whitespace: bool = is_in_whitespace(ch, mode);
@ -65,14 +65,14 @@ pub fn transform_text(text: &str, mode: CompressionMode, incoming_whitespace: bo
// TODO: record skipped char // TODO: record skipped char
} else { } else {
// TODO: record kept char // TODO: record kept char
str::push_char(&mut out_str, ch); out_str.push_char(ch);
} }
} else { /* next_in_whitespace; possibly add a space char */ } else { /* next_in_whitespace; possibly add a space char */
if in_whitespace { if in_whitespace {
// TODO: record skipped char // TODO: record skipped char
} else { } else {
// TODO: record kept char // TODO: record kept char
str::push_char(&mut out_str, ' '); out_str.push_char(' ');
} }
} }
// save whitespace context for next char // save whitespace context for next char

View file

@ -14,10 +14,12 @@ use gfx::render_task::{RenderChan, ReRenderMsg};
use azure::azure_hl::{DataSourceSurface, DrawTarget, SourceSurfaceMethods, current_gl_context}; use azure::azure_hl::{DataSourceSurface, DrawTarget, SourceSurfaceMethods, current_gl_context};
use azure::azure::AzGLContext; use azure::azure::AzGLContext;
use core::cell::Cell; use std::cell::Cell;
use core::comm::{Chan, SharedChan, Port}; use std::comm;
use core::num::Orderable; use std::comm::{Chan, SharedChan, Port};
use core::util; use std::num::Orderable;
use std::task;
use std::util;
use geom::matrix::identity; use geom::matrix::identity;
use geom::point::Point2D; use geom::point::Point2D;
use geom::size::Size2D; use geom::size::Size2D;
@ -137,8 +139,8 @@ impl CompositorTask {
pub fn create(port: Port<Msg>, pub fn create(port: Port<Msg>,
profiler_chan: ProfilerChan, profiler_chan: ProfilerChan,
shutdown_chan: Chan<()>) { shutdown_chan: Chan<()>) {
let port = Cell(port); let port = Cell::new(port);
let shutdown_chan = Cell(shutdown_chan); let shutdown_chan = Cell::new(shutdown_chan);
do on_osmain { do on_osmain {
let compositor_task = CompositorTask::new(port.take(), let compositor_task = CompositorTask::new(port.take(),
profiler_chan.clone(), profiler_chan.clone(),
@ -158,7 +160,7 @@ impl CompositorTask {
// list. This is only here because we don't have that logic in the renderer yet. // list. This is only here because we don't have that logic in the renderer yet.
let context = rendergl::init_render_context(); let context = rendergl::init_render_context();
let root_layer = @mut ContainerLayer(); let root_layer = @mut ContainerLayer();
let scene = @mut Scene(ContainerLayerKind(root_layer), Size2D(800.0, 600.0), identity()); let scene = @mut Scene(ContainerLayerKind(root_layer), Size2D(800.0f32, 600.0), identity());
let done = @mut false; let done = @mut false;
// FIXME: This should not be a separate offset applied after the fact but rather should be // FIXME: This should not be a separate offset applied after the fact but rather should be
@ -181,7 +183,7 @@ impl CompositorTask {
// Hook the windowing system's resize callback up to the resize rate limiter. // Hook the windowing system's resize callback up to the resize rate limiter.
do window.set_resize_callback |width, height| { do window.set_resize_callback |width, height| {
debug!("osmain: window resized to %ux%u", width, height); debug!("osmain: window resized to %ux%u", width, height);
*window_size = Size2D(width, height); *window_size = Size2D(width as int, height as int);
layout_chan_clone.chan.send(RouteScriptMsg(SendEventMsg(ResizeEvent(width, height)))); layout_chan_clone.chan.send(RouteScriptMsg(SendEventMsg(ResizeEvent(width, height))));
} }

View file

@ -4,7 +4,7 @@
use layout::aux::LayoutAuxMethods; use layout::aux::LayoutAuxMethods;
use core::cast::transmute; use std::cast::transmute;
use newcss::complete::CompleteSelectResults; use newcss::complete::CompleteSelectResults;
use script::dom::node::{AbstractNode, LayoutView}; use script::dom::node::{AbstractNode, LayoutView};

View file

@ -2,9 +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::net::url::Url; use extra::net::url::Url;
use url_from_str = std::net::url::from_str; use url_from_str = extra::net::url::from_str;
use core::cell::Cell; use std::cell::Cell;
use std::result;
use std::str;
use newcss::stylesheet::Stylesheet; use newcss::stylesheet::Stylesheet;
use newcss::select::SelectCtx; use newcss::select::SelectCtx;
use newcss::types::OriginUA; use newcss::types::OriginUA;
@ -32,7 +34,7 @@ fn default_url(name: &str) -> Url {
} }
fn style_stream(style: &str) -> DataStream { fn style_stream(style: &str) -> DataStream {
let style = Cell(str::to_bytes(style)); let style = Cell::new(style.as_bytes().to_owned());
let d: DataStream = || if !style.is_empty() { let d: DataStream = || if !style.is_empty() {
Some(style.take()) Some(style.take())
} else { } else {

View file

@ -6,7 +6,8 @@
/// Implementation of the callbacks that the CSS selector engine uses to query the DOM. /// Implementation of the callbacks that the CSS selector engine uses to query the DOM.
/// ///
use core::str::eq_slice; use std::str;
use std::str::eq_slice;
use newcss::select::SelectHandler; use newcss::select::SelectHandler;
use script::dom::node::{AbstractNode, LayoutView}; use script::dom::node::{AbstractNode, LayoutView};
@ -104,7 +105,7 @@ impl SelectHandler<AbstractNode<LayoutView>> for NodeSelectHandler {
None => false, None => false,
Some(existing_classes) => { Some(existing_classes) => {
let mut ret = false; let mut ret = false;
for str::each_split_char(existing_classes, ' ') |s| { for existing_classes.split_iter(' ').advance |s| {
if s == class { if s == class {
ret = true; ret = true;
break; break;

View file

@ -5,8 +5,10 @@
use compositing::{CompositorChan, SetLayoutChan, SetRenderChan}; use compositing::{CompositorChan, SetLayoutChan, SetRenderChan};
use layout::layout_task; use layout::layout_task;
use core::cell::Cell; use std::cell::Cell;
use core::comm::Port; use std::comm;
use std::comm::Port;
use std::task;
use gfx::opts::Opts; use gfx::opts::Opts;
use gfx::render_task::RenderChan; use gfx::render_task::RenderChan;
use gfx::render_task; use gfx::render_task;
@ -43,7 +45,7 @@ impl Engine {
($Msg:ty, $Chan:ident) => ( ($Msg:ty, $Chan:ident) => (
{ {
let (port, chan) = comm::stream::<$Msg>(); let (port, chan) = comm::stream::<$Msg>();
(Cell(port), $Chan::new(chan)) (Cell::new(port), $Chan::new(chan))
} }
); );
) )
@ -58,15 +60,15 @@ impl Engine {
let (layout_port, layout_chan) = closure_stream!(layout_interface::Msg, LayoutChan); let (layout_port, layout_chan) = closure_stream!(layout_interface::Msg, LayoutChan);
let (render_port, render_chan) = comm::stream::<render_task::Msg<CompositorChan>>(); let (render_port, render_chan) = comm::stream::<render_task::Msg<CompositorChan>>();
let (render_port, render_chan) = (Cell(render_port), RenderChan::new(render_chan)); let (render_port, render_chan) = (Cell::new(render_port), RenderChan::new(render_chan));
compositor_chan.send(SetLayoutChan(layout_chan.clone())); compositor_chan.send(SetLayoutChan(layout_chan.clone()));
compositor_chan.send(SetRenderChan(render_chan.clone())); compositor_chan.send(SetRenderChan(render_chan.clone()));
let compositor_chan = Cell(compositor_chan); let compositor_chan = Cell::new(compositor_chan);
let opts = Cell(copy *opts); let opts = Cell::new(copy *opts);
{ {
let engine_chan = engine_chan.clone(); let engine_chan = engine_chan.clone();

View file

@ -40,21 +40,20 @@ pub trait LayoutAuxMethods {
} }
impl LayoutAuxMethods for AbstractNode<LayoutView> { impl LayoutAuxMethods for AbstractNode<LayoutView> {
// FIXME (Rust #3080): These unsafe blocks are *not* unused!
pub fn layout_data(self) -> @mut LayoutData { pub fn layout_data(self) -> @mut LayoutData {
/*unsafe {*/ unsafe {
self.unsafe_layout_data() self.unsafe_layout_data()
/*}*/ }
} }
pub fn has_layout_data(self) -> bool { pub fn has_layout_data(self) -> bool {
/*unsafe {*/ unsafe {
self.unsafe_has_layout_data() self.unsafe_has_layout_data()
/*}*/ }
} }
pub fn set_layout_data(self, data: @mut LayoutData) { pub fn set_layout_data(self, data: @mut LayoutData) {
/*unsafe {*/ unsafe {
self.unsafe_set_layout_data(data) self.unsafe_set_layout_data(data)
/*}*/ }
} }
/// If none exists, creates empty layout data for the node (the reader-auxiliary /// If none exists, creates empty layout data for the node (the reader-auxiliary

View file

@ -13,7 +13,7 @@ use layout::inline::InlineLayout;
use layout::model::{MaybeAuto, Specified, Auto}; use layout::model::{MaybeAuto, Specified, Auto};
use layout::float_context::FloatContext; use layout::float_context::FloatContext;
use core::cell::Cell; use std::cell::Cell;
use geom::point::Point2D; use geom::point::Point2D;
use geom::rect::Rect; use geom::rect::Rect;
use gfx::display_list::DisplayList; use gfx::display_list::DisplayList;
@ -51,7 +51,7 @@ impl BlockFlowData {
pub fn teardown(&mut self) { pub fn teardown(&mut self) {
self.common.teardown(); self.common.teardown();
for self.box.each |box| { for self.box.iter().advance |box| {
box.teardown(); box.teardown();
} }
self.box = None; self.box = None;
@ -192,7 +192,7 @@ impl BlockFlowData {
let mut remaining_width = self.common.position.size.width; let mut remaining_width = self.common.position.size.width;
let mut x_offset = Au(0); let mut x_offset = Au(0);
for self.box.each |&box| { for self.box.iter().advance |&box| {
let style = box.style(); let style = box.style();
do box.with_model |model| { do box.with_model |model| {
// Can compute padding here since we know containing block width. // Can compute padding here since we know containing block width.
@ -251,7 +251,7 @@ impl BlockFlowData {
let mut top_offset = Au(0); let mut top_offset = Au(0);
let mut left_offset = Au(0); let mut left_offset = Au(0);
for self.box.each |&box| { for self.box.iter().advance |&box| {
do box.with_model |model| { do box.with_model |model| {
top_offset = model.margin.top + model.border.top + model.padding.top; top_offset = model.margin.top + model.border.top + model.padding.top;
cur_y += top_offset; cur_y += top_offset;

View file

@ -11,10 +11,11 @@ use layout::flow::FlowContext;
use layout::model::{BoxModel, MaybeAuto}; use layout::model::{BoxModel, MaybeAuto};
use layout::text; use layout::text;
use core::cell::Cell; use std::cell::Cell;
use core::cmp::ApproxEq; use std::cmp::ApproxEq;
use core::managed; use std::managed;
use core::num::Zero; use std::num::Zero;
use std::uint;
use geom::{Point2D, Rect, Size2D}; use geom::{Point2D, Rect, Size2D};
use gfx::display_list::{BaseDisplayItem, BorderDisplayItem, BorderDisplayItemClass}; use gfx::display_list::{BaseDisplayItem, BorderDisplayItem, BorderDisplayItemClass};
use gfx::display_list::{DisplayList, ImageDisplayItem, ImageDisplayItemClass}; use gfx::display_list::{DisplayList, ImageDisplayItem, ImageDisplayItemClass};
@ -35,7 +36,7 @@ use script::dom::node::{AbstractNode, LayoutView};
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::range::*; use servo_util::range::*;
use std::net::url::Url; use extra::net::url::Url;
/// Render boxes (`struct RenderBox`) are the leaves of the layout tree. They cannot position /// Render boxes (`struct RenderBox`) are the leaves of the layout tree. They cannot position
/// themselves. In general, render boxes do not have a simple correspondence with CSS boxes as in /// themselves. In general, render boxes do not have a simple correspondence with CSS boxes as in
@ -178,10 +179,10 @@ impl RenderBoxBase {
} }
} }
pub impl RenderBox { impl RenderBox {
/// Borrows this render box immutably in order to work with its common data. /// Borrows this render box immutably in order to work with its common data.
#[inline(always)] #[inline(always)]
fn with_base<R>(&self, callback: &fn(&RenderBoxBase) -> R) -> R { pub fn with_base<R>(&self, callback: &fn(&RenderBoxBase) -> R) -> R {
match *self { match *self {
GenericRenderBoxClass(generic_box) => callback(generic_box), GenericRenderBoxClass(generic_box) => callback(generic_box),
ImageRenderBoxClass(image_box) => { ImageRenderBoxClass(image_box) => {
@ -198,7 +199,7 @@ pub impl RenderBox {
/// Borrows this render box mutably in order to work with its common data. /// Borrows this render box mutably in order to work with its common data.
#[inline(always)] #[inline(always)]
fn with_mut_base<R>(&self, callback: &fn(&mut RenderBoxBase) -> R) -> R { pub fn with_mut_base<R>(&self, callback: &fn(&mut RenderBoxBase) -> R) -> R {
match *self { match *self {
GenericRenderBoxClass(generic_box) => callback(generic_box), GenericRenderBoxClass(generic_box) => callback(generic_box),
ImageRenderBoxClass(image_box) => { ImageRenderBoxClass(image_box) => {
@ -214,14 +215,14 @@ pub impl RenderBox {
} }
/// A convenience function to return the position of this box. /// A convenience function to return the position of this box.
fn position(&self) -> Rect<Au> { pub fn position(&self) -> Rect<Au> {
do self.with_base |base| { do self.with_base |base| {
base.position base.position
} }
} }
/// A convenience function to return the debugging ID of this box. /// A convenience function to return the debugging ID of this box.
fn id(&self) -> int { pub fn id(&self) -> int {
do self.with_mut_base |base| { do self.with_mut_base |base| {
base.id base.id
} }
@ -229,7 +230,7 @@ pub impl RenderBox {
/// Returns true if this element is replaced content. This is true for images, form elements, /// Returns true if this element is replaced content. This is true for images, form elements,
/// and so on. /// and so on.
fn is_replaced(&self) -> bool { pub fn is_replaced(&self) -> bool {
match *self { match *self {
ImageRenderBoxClass(*) => true, ImageRenderBoxClass(*) => true,
_ => false _ => false
@ -237,7 +238,7 @@ pub impl RenderBox {
} }
/// Returns true if this element can be split. This is true for text boxes. /// Returns true if this element can be split. This is true for text boxes.
fn can_split(&self) -> bool { pub fn can_split(&self) -> bool {
match *self { match *self {
TextRenderBoxClass(*) => true, TextRenderBoxClass(*) => true,
_ => false _ => false
@ -245,7 +246,7 @@ pub impl RenderBox {
} }
/// Returns true if this element is an unscanned text box that consists entirely of whitespace. /// Returns true if this element is an unscanned text box that consists entirely of whitespace.
fn is_whitespace_only(&self) -> bool { pub fn is_whitespace_only(&self) -> bool {
match *self { match *self {
UnscannedTextRenderBoxClass(unscanned_text_box) => { UnscannedTextRenderBoxClass(unscanned_text_box) => {
unscanned_text_box.text.is_whitespace() unscanned_text_box.text.is_whitespace()
@ -255,7 +256,7 @@ pub impl RenderBox {
} }
/// Determines whether this box can merge with another render box. /// Determines whether this box can merge with another render box.
fn can_merge_with_box(&self, other: RenderBox) -> bool { pub fn can_merge_with_box(&self, other: RenderBox) -> bool {
match (self, &other) { match (self, &other) {
(&UnscannedTextRenderBoxClass(*), &UnscannedTextRenderBoxClass(*)) => { (&UnscannedTextRenderBoxClass(*), &UnscannedTextRenderBoxClass(*)) => {
self.font_style() == other.font_style() && self.text_decoration() == other.text_decoration() self.font_style() == other.font_style() && self.text_decoration() == other.text_decoration()
@ -269,7 +270,7 @@ pub impl RenderBox {
/// Attempts to split this box so that its width is no more than `max_width`. Fails if this box /// Attempts to split this box so that its width is no more than `max_width`. Fails if this box
/// is an unscanned text box. /// is an unscanned text box.
fn split_to_width(&self, _: &LayoutContext, max_width: Au, starts_line: bool) pub fn split_to_width(&self, _: &LayoutContext, max_width: Au, starts_line: bool)
-> SplitBoxResult { -> SplitBoxResult {
match *self { match *self {
GenericRenderBoxClass(*) | ImageRenderBoxClass(*) => CannotSplit(*self), GenericRenderBoxClass(*) | ImageRenderBoxClass(*) => CannotSplit(*self),
@ -400,7 +401,7 @@ pub impl RenderBox {
} }
/// Returns the *minimum width* of this render box as defined by the CSS specification. /// Returns the *minimum width* of this render box as defined by the CSS specification.
fn get_min_width(&self, _: &LayoutContext) -> Au { pub fn get_min_width(&self, _: &LayoutContext) -> Au {
// FIXME(pcwalton): I think we only need to calculate this if the damage says that CSS // FIXME(pcwalton): I think we only need to calculate this if the damage says that CSS
// needs to be restyled. // needs to be restyled.
@ -426,7 +427,7 @@ pub impl RenderBox {
} }
/// Returns the *preferred width* of this render box as defined by the CSS specification. /// Returns the *preferred width* of this render box as defined by the CSS specification.
fn get_pref_width(&self, _: &LayoutContext) -> Au { pub fn get_pref_width(&self, _: &LayoutContext) -> Au {
self.guess_width() + match *self { self.guess_width() + match *self {
// TODO: This should account for the preferred width of the box element in isolation. // TODO: This should account for the preferred width of the box element in isolation.
// That includes borders, margins, and padding, but not child widths. The block // That includes borders, margins, and padding, but not child widths. The block
@ -451,7 +452,7 @@ pub impl RenderBox {
let mut line_width: Au = Au(0); let mut line_width: Au = Au(0);
for text_box.run.glyphs.iter_glyphs_for_char_range(line_range) for text_box.run.glyphs.iter_glyphs_for_char_range(line_range)
|_, glyph| { |_, glyph| {
line_width += glyph.advance() line_width += glyph.advance_()
} }
max_line_width = Au::max(max_line_width, line_width); max_line_width = Au::max(max_line_width, line_width);
@ -466,32 +467,32 @@ pub impl RenderBox {
/// Returns the amount of left and right "fringe" used by this box. This is based on margins, /// Returns the amount of left and right "fringe" used by this box. This is based on margins,
/// borders, padding, and width. /// borders, padding, and width.
fn get_used_width(&self) -> (Au, Au) { pub fn get_used_width(&self) -> (Au, Au) {
// TODO: This should actually do some computation! See CSS 2.1, Sections 10.3 and 10.4. // TODO: This should actually do some computation! See CSS 2.1, Sections 10.3 and 10.4.
(Au(0), Au(0)) (Au(0), Au(0))
} }
/// Returns the amount of left and right "fringe" used by this box. This should be based on /// Returns the amount of left and right "fringe" used by this box. This should be based on
/// margins, borders, padding, and width. /// margins, borders, padding, and width.
fn get_used_height(&self) -> (Au, Au) { pub fn get_used_height(&self) -> (Au, Au) {
// TODO: This should actually do some computation! See CSS 2.1, Sections 10.5 and 10.6. // TODO: This should actually do some computation! See CSS 2.1, Sections 10.5 and 10.6.
(Au(0), Au(0)) (Au(0), Au(0))
} }
fn compute_padding(&self, cb_width: Au) { pub fn compute_padding(&self, cb_width: Au) {
do self.with_mut_base |base| { do self.with_mut_base |base| {
base.model.compute_padding(base.node.style(), cb_width); base.model.compute_padding(base.node.style(), cb_width);
} }
} }
fn get_noncontent_width(&self) -> Au { pub fn get_noncontent_width(&self) -> Au {
do self.with_base |base| { do self.with_base |base| {
base.model.border.left + base.model.padding.left + base.model.border.left + base.model.padding.left +
base.model.border.right + base.model.padding.right base.model.border.right + base.model.padding.right
} }
} }
fn with_model<R>(&self, callback: &fn(&mut BoxModel) -> R) -> R { pub fn with_model<R>(&self, callback: &fn(&mut BoxModel) -> R) -> R {
do self.with_mut_base |base| { do self.with_mut_base |base| {
callback(&mut base.model) callback(&mut base.model)
} }
@ -499,7 +500,7 @@ pub impl RenderBox {
/// The box formed by the content edge as defined in CSS 2.1 § 8.1. Coordinates are relative to /// The box formed by the content edge as defined in CSS 2.1 § 8.1. Coordinates are relative to
/// the owning flow. /// the owning flow.
fn content_box(&self) -> Rect<Au> { pub fn content_box(&self) -> Rect<Au> {
do self.with_base |base| { do self.with_base |base| {
let origin = Point2D(base.position.origin.x + let origin = Point2D(base.position.origin.x +
base.model.border.left + base.model.border.left +
@ -513,26 +514,26 @@ pub impl RenderBox {
/// The box formed by the border edge as defined in CSS 2.1 § 8.1. Coordinates are relative to /// The box formed by the border edge as defined in CSS 2.1 § 8.1. Coordinates are relative to
/// the owning flow. /// the owning flow.
fn border_box(&self) -> Rect<Au> { pub fn border_box(&self) -> Rect<Au> {
// TODO: Actually compute the content box, padding, and border. // TODO: Actually compute the content box, padding, and border.
self.content_box() self.content_box()
} }
/// The box formed by the margin edge as defined in CSS 2.1 § 8.1. Coordinates are relative to /// The box formed by the margin edge as defined in CSS 2.1 § 8.1. Coordinates are relative to
/// the owning flow. /// the owning flow.
fn margin_box(&self) -> Rect<Au> { pub fn margin_box(&self) -> Rect<Au> {
// TODO: Actually compute the content_box, padding, border, and margin. // TODO: Actually compute the content_box, padding, border, and margin.
self.content_box() self.content_box()
} }
/// A convenience function to access the computed style of the DOM node that this render box /// A convenience function to access the computed style of the DOM node that this render box
/// represents. /// represents.
fn style(&self) -> CompleteStyle { pub fn style(&self) -> CompleteStyle {
self.with_base(|base| base.node.style()) self.with_base(|base| base.node.style())
} }
/// A convenience function to access the DOM node that this render box represents. /// A convenience function to access the DOM node that this render box represents.
fn node(&self) -> AbstractNode<LayoutView> { pub fn node(&self) -> AbstractNode<LayoutView> {
self.with_base(|base| base.node) self.with_base(|base| base.node)
} }
@ -540,7 +541,7 @@ pub impl RenderBox {
/// represents. /// represents.
/// ///
/// If there is no ancestor-or-self `Element` node, fails. /// If there is no ancestor-or-self `Element` node, fails.
fn nearest_ancestor_element(&self) -> AbstractNode<LayoutView> { pub fn nearest_ancestor_element(&self) -> AbstractNode<LayoutView> {
do self.with_base |base| { do self.with_base |base| {
let mut node = base.node; let mut node = base.node;
while !node.is_element() { while !node.is_element() {
@ -571,7 +572,7 @@ pub impl RenderBox {
/// representing the box's stacking context. When asked to construct its constituent display /// representing the box's stacking context. When asked to construct its constituent display
/// items, each box puts its display items into the correct stack layer according to CSS 2.1 /// items, each box puts its display items into the correct stack layer according to CSS 2.1
/// Appendix E. Finally, the builder flattens the list. /// Appendix E. Finally, the builder flattens the list.
fn build_display_list<E:ExtraDisplayListData>(&self, pub fn build_display_list<E:ExtraDisplayListData>(&self,
_: &DisplayListBuilder, _: &DisplayListBuilder,
dirty: &Rect<Au>, dirty: &Rect<Au>,
offset: &Point2D<Au>, offset: &Point2D<Au>,
@ -715,7 +716,7 @@ pub impl RenderBox {
/// Adds the display items necessary to paint the background of this render box to the display /// Adds the display items necessary to paint the background of this render box to the display
/// list if necessary. /// list if necessary.
fn paint_background_if_applicable<E:ExtraDisplayListData>(&self, pub fn paint_background_if_applicable<E:ExtraDisplayListData>(&self,
list: &Cell<DisplayList<E>>, list: &Cell<DisplayList<E>>,
absolute_bounds: &Rect<Au>) { absolute_bounds: &Rect<Au>) {
// FIXME: This causes a lot of background colors to be displayed when they are clearly not // FIXME: This causes a lot of background colors to be displayed when they are clearly not
@ -741,7 +742,7 @@ pub impl RenderBox {
} }
/// Converts this node's computed style to a font style used for rendering. /// Converts this node's computed style to a font style used for rendering.
fn font_style(&self) -> FontStyle { pub fn font_style(&self) -> FontStyle {
let my_style = self.nearest_ancestor_element().style(); let my_style = self.nearest_ancestor_element().style();
debug!("(font style) start: %?", self.nearest_ancestor_element().type_id()); debug!("(font style) start: %?", self.nearest_ancestor_element().type_id());
@ -757,7 +758,7 @@ pub impl RenderBox {
CSSFontFamilyGenericFamily(Monospace) => ~"monospace", CSSFontFamilyGenericFamily(Monospace) => ~"monospace",
} }
}; };
let font_families = str::connect(font_families, ~", "); let font_families = font_families.connect(", ");
debug!("(font style) font families: `%s`", font_families); debug!("(font style) font families: `%s`", font_families);
let font_size = match my_style.font_size() { let font_size = match my_style.font_size() {
@ -786,7 +787,7 @@ pub impl RenderBox {
/// Returns the text alignment of the computed style of the nearest ancestor-or-self `Element` /// Returns the text alignment of the computed style of the nearest ancestor-or-self `Element`
/// node. /// node.
fn text_align(&self) -> CSSTextAlign { pub fn text_align(&self) -> CSSTextAlign {
self.nearest_ancestor_element().style().text_align() self.nearest_ancestor_element().style().text_align()
} }
@ -795,7 +796,7 @@ pub impl RenderBox {
} }
/// Returns the text decoration of the computed style of the nearest `Element` node /// Returns the text decoration of the computed style of the nearest `Element` node
fn text_decoration(&self) -> CSSTextDecoration { pub fn text_decoration(&self) -> CSSTextDecoration {
/// Computes the propagated value of text-decoration, as specified in CSS 2.1 § 16.3.1 /// Computes the propagated value of text-decoration, as specified in CSS 2.1 § 16.3.1
/// TODO: make sure this works with anonymous box generation. /// TODO: make sure this works with anonymous box generation.
fn get_propagated_text_decoration(element: AbstractNode<LayoutView>) -> CSSTextDecoration { fn get_propagated_text_decoration(element: AbstractNode<LayoutView>) -> CSSTextDecoration {
@ -856,9 +857,10 @@ pub impl RenderBox {
GenericRenderBoxClass(*) => ~"GenericRenderBox", GenericRenderBoxClass(*) => ~"GenericRenderBox",
ImageRenderBoxClass(*) => ~"ImageRenderBox", ImageRenderBoxClass(*) => ~"ImageRenderBox",
TextRenderBoxClass(text_box) => { TextRenderBoxClass(text_box) => {
fmt!("TextRenderBox(text=%s)", str::substr(text_box.run.text, fmt!("TextRenderBox(text=%s)",
text_box.run.text.slice(
text_box.range.begin(), text_box.range.begin(),
text_box.range.length())) text_box.range.begin() + text_box.range.length()))
} }
UnscannedTextRenderBoxClass(text_box) => { UnscannedTextRenderBoxClass(text_box) => {
fmt!("UnscannedTextRenderBox(%s)", text_box.text) fmt!("UnscannedTextRenderBox(%s)", text_box.text)

View file

@ -36,8 +36,8 @@ pub struct LayoutTreeBuilder {
next_bid: int, next_bid: int,
} }
pub impl LayoutTreeBuilder { impl LayoutTreeBuilder {
fn new() -> LayoutTreeBuilder { pub fn new() -> LayoutTreeBuilder {
LayoutTreeBuilder { LayoutTreeBuilder {
root_flow: None, root_flow: None,
next_cid: -1, next_cid: -1,
@ -142,7 +142,8 @@ impl BoxGenerator {
inline.boxes.push(new_box); inline.boxes.push(new_box);
} else if self.inline_spacers_needed_for_node(node) { } else if self.inline_spacers_needed_for_node(node) {
// else, maybe make a spacer for "left" margin, border, padding // else, maybe make a spacer for "left" margin, border, padding
for self.make_inline_spacer_for_node_side(ctx, node, LogicalBefore).each let inline_spacer = self.make_inline_spacer_for_node_side(ctx, node, LogicalBefore);
for inline_spacer.iter().advance
|spacer: &RenderBox| { |spacer: &RenderBox| {
inline.boxes.push(*spacer); inline.boxes.push(*spacer);
} }
@ -190,7 +191,7 @@ impl BoxGenerator {
// If this non-leaf box generates extra horizontal spacing, add a SpacerBox for // If this non-leaf box generates extra horizontal spacing, add a SpacerBox for
// it. // it.
let result = self.make_inline_spacer_for_node_side(ctx, node, LogicalAfter); let result = self.make_inline_spacer_for_node_side(ctx, node, LogicalAfter);
for result.each |spacer| { for result.iter().advance |spacer| {
let boxes = &mut self.flow.inline().boxes; let boxes = &mut self.flow.inline().boxes;
boxes.push(*spacer); boxes.push(*spacer);
} }
@ -269,14 +270,14 @@ impl BoxGenerator {
} }
pub impl LayoutTreeBuilder { impl LayoutTreeBuilder {
/* Debug-only ids */ /* Debug-only ids */
fn next_flow_id(&mut self) -> int { self.next_cid += 1; self.next_cid } pub fn next_flow_id(&mut self) -> int { self.next_cid += 1; self.next_cid }
fn next_box_id(&mut self) -> int { self.next_bid += 1; self.next_bid } pub fn next_box_id(&mut self) -> int { self.next_bid += 1; self.next_bid }
/// Creates necessary box(es) and flow context(s) for the current DOM node, /// Creates necessary box(es) and flow context(s) for the current DOM node,
/// and recurses on its children. /// and recurses on its children.
fn construct_recursively(&mut self, pub fn construct_recursively(&mut self,
layout_ctx: &LayoutContext, layout_ctx: &LayoutContext,
cur_node: AbstractNode<LayoutView>, cur_node: AbstractNode<LayoutView>,
parent_generator: @mut BoxGenerator, parent_generator: @mut BoxGenerator,
@ -319,7 +320,7 @@ pub impl LayoutTreeBuilder {
Some(this_generator) Some(this_generator)
} }
fn box_generator_for_node(&mut self, pub fn box_generator_for_node(&mut self,
node: AbstractNode<LayoutView>, node: AbstractNode<LayoutView>,
parent_generator: @mut BoxGenerator, parent_generator: @mut BoxGenerator,
sibling_generator: Option<@mut BoxGenerator>) sibling_generator: Option<@mut BoxGenerator>)
@ -433,7 +434,7 @@ pub impl LayoutTreeBuilder {
Some(new_generator) Some(new_generator)
} }
fn create_child_generator(&mut self, pub fn create_child_generator(&mut self,
node: AbstractNode<LayoutView>, node: AbstractNode<LayoutView>,
parent_generator: @mut BoxGenerator, parent_generator: @mut BoxGenerator,
ty: FlowContextType) ty: FlowContextType)
@ -445,7 +446,7 @@ pub impl LayoutTreeBuilder {
@mut BoxGenerator::new(new_flow) @mut BoxGenerator::new(new_flow)
} }
fn create_child_generator_if_needed(&mut self, pub fn create_child_generator_if_needed(&mut self,
node: AbstractNode<LayoutView>, node: AbstractNode<LayoutView>,
parent_generator: @mut BoxGenerator, parent_generator: @mut BoxGenerator,
maybe_generator: Option<@mut BoxGenerator>, maybe_generator: Option<@mut BoxGenerator>,
@ -466,7 +467,7 @@ pub impl LayoutTreeBuilder {
/// ///
/// The latter can only be done immediately adjacent to, or at the beginning or end of a block /// The latter can only be done immediately adjacent to, or at the beginning or end of a block
/// flow. Otherwise, the whitespace might affect whitespace collapsing with adjacent text. /// flow. Otherwise, the whitespace might affect whitespace collapsing with adjacent text.
fn simplify_children_of_flow(&self, _: &LayoutContext, parent_flow: &mut FlowContext) { pub fn simplify_children_of_flow(&self, _: &LayoutContext, parent_flow: &mut FlowContext) {
match *parent_flow { match *parent_flow {
InlineFlow(*) => { InlineFlow(*) => {
let mut found_child_inline = false; let mut found_child_inline = false;
@ -493,7 +494,7 @@ pub impl LayoutTreeBuilder {
let first_child = do parent_flow.with_base |parent_node| { let first_child = do parent_flow.with_base |parent_node| {
parent_node.first_child parent_node.first_child
}; };
for first_child.each |&first_flow| { for first_child.iter().advance |&first_flow| {
if first_flow.starts_inline_flow() { if first_flow.starts_inline_flow() {
// FIXME: workaround for rust#6393 // FIXME: workaround for rust#6393
let mut do_remove = false; let mut do_remove = false;
@ -516,7 +517,7 @@ pub impl LayoutTreeBuilder {
let last_child = do parent_flow.with_base |parent_node| { let last_child = do parent_flow.with_base |parent_node| {
parent_node.last_child parent_node.last_child
}; };
for last_child.each |&last_flow| { for last_child.iter().advance |&last_flow| {
if last_flow.starts_inline_flow() { if last_flow.starts_inline_flow() {
// FIXME: workaround for rust#6393 // FIXME: workaround for rust#6393
let mut do_remove = false; let mut do_remove = false;
@ -540,13 +541,13 @@ pub impl LayoutTreeBuilder {
} }
} }
fn fixup_split_inline(&self, _: FlowContext) { pub fn fixup_split_inline(&self, _: FlowContext) {
// TODO: finish me. // TODO: finish me.
fail!(~"TODO: handle case where an inline is split by a block") fail!(~"TODO: handle case where an inline is split by a block")
} }
/// Entry point for box creation. Should only be called on the root DOM element. /// Entry point for box creation. Should only be called on the root DOM element.
fn construct_trees(&mut self, layout_ctx: &LayoutContext, root: AbstractNode<LayoutView>) pub fn construct_trees(&mut self, layout_ctx: &LayoutContext, root: AbstractNode<LayoutView>)
-> Result<FlowContext, ()> { -> Result<FlowContext, ()> {
let new_flow = self.make_flow(Flow_Root, root); let new_flow = self.make_flow(Flow_Root, root);
let new_generator = @mut BoxGenerator::new(new_flow); let new_generator = @mut BoxGenerator::new(new_flow);
@ -557,7 +558,7 @@ pub impl LayoutTreeBuilder {
} }
/// Creates a flow of the given type for the supplied node. /// Creates a flow of the given type for the supplied node.
fn make_flow(&mut self, ty: FlowContextType, node: AbstractNode<LayoutView>) -> FlowContext { pub fn make_flow(&mut self, ty: FlowContextType, node: AbstractNode<LayoutView>) -> FlowContext {
let info = FlowData::new(self.next_flow_id(), node); let info = FlowData::new(self.next_flow_id(), node);
let result = match ty { let result = match ty {
Flow_Absolute => AbsoluteFlow(@mut info), Flow_Absolute => AbsoluteFlow(@mut info),

View file

@ -8,7 +8,7 @@ use layout::box::RenderBox;
use layout::context::LayoutContext; use layout::context::LayoutContext;
use layout::flow::FlowContext; use layout::flow::FlowContext;
use core::cell::Cell; use std::cell::Cell;
use geom::point::Point2D; use geom::point::Point2D;
use geom::rect::Rect; use geom::rect::Rect;
use gfx::display_list::DisplayList; use gfx::display_list::DisplayList;

View file

@ -10,7 +10,7 @@ use layout::flow::{FloatFlow, FlowData};
use layout::model::{MaybeAuto}; use layout::model::{MaybeAuto};
use layout::float_context::{FloatContext, PlacementInfo, FloatLeft}; use layout::float_context::{FloatContext, PlacementInfo, FloatLeft};
use core::cell::Cell; use std::cell::Cell;
use geom::point::Point2D; use geom::point::Point2D;
use geom::rect::Rect; use geom::rect::Rect;
use gfx::display_list::DisplayList; use gfx::display_list::DisplayList;
@ -48,7 +48,7 @@ impl FloatFlowData {
pub fn teardown(&mut self) { pub fn teardown(&mut self) {
self.common.teardown(); self.common.teardown();
for self.box.each |box| { for self.box.iter().advance |box| {
box.teardown(); box.teardown();
} }
self.box = None; self.box = None;
@ -95,7 +95,7 @@ impl FloatFlowData {
self.containing_width = remaining_width; self.containing_width = remaining_width;
let mut x_offset = Au(0); let mut x_offset = Au(0);
for self.box.each |&box| { for self.box.iter().advance |&box| {
let style = box.style(); let style = box.style();
do box.with_model |model| { do box.with_model |model| {
// Can compute padding here since we know containing block width. // Can compute padding here since we know containing block width.
@ -161,7 +161,7 @@ impl FloatFlowData {
let mut cur_y = Au(0); let mut cur_y = Au(0);
let mut top_offset = Au(0); let mut top_offset = Au(0);
for self.box.each |&box| { for self.box.iter().advance |&box| {
do box.with_model |model| { do box.with_model |model| {
top_offset = model.margin.top + model.border.top + model.padding.top; top_offset = model.margin.top + model.border.top + model.padding.top;
cur_y += top_offset; cur_y += top_offset;
@ -193,7 +193,7 @@ impl FloatFlowData {
//TODO(eatkinson): compute heights properly using the 'height' property. //TODO(eatkinson): compute heights properly using the 'height' property.
for self.box.each |&box| { for self.box.iter().advance |&box| {
let height_prop = let height_prop =
MaybeAuto::from_height(box.style().height(), Au(0)).spec_or_default(Au(0)); MaybeAuto::from_height(box.style().height(), Au(0)).spec_or_default(Au(0));

View file

@ -6,7 +6,8 @@ use geom::point::Point2D;
use geom::size::Size2D; use geom::size::Size2D;
use geom::rect::Rect; use geom::rect::Rect;
use gfx::geometry::{Au, max, min}; use gfx::geometry::{Au, max, min};
use core::util::replace; use std::util::replace;
use std::vec;
pub enum FloatType{ pub enum FloatType{
FloatLeft, FloatLeft,

View file

@ -33,7 +33,8 @@ use layout::display_list_builder::{DisplayListBuilder, ExtraDisplayListData};
use layout::inline::{InlineFlowData}; use layout::inline::{InlineFlowData};
use layout::float_context::{FloatContext, Invalid}; use layout::float_context::{FloatContext, Invalid};
use core::cell::Cell; use std::cell::Cell;
use std::uint;
use geom::point::Point2D; use geom::point::Point2D;
use geom::rect::Rect; use geom::rect::Rect;
use gfx::display_list::DisplayList; use gfx::display_list::DisplayList;
@ -89,14 +90,14 @@ impl FlowData {
// or we risk dynamic borrow failures. // or we risk dynamic borrow failures.
self.parent = None; self.parent = None;
for self.first_child.each |flow| { for self.first_child.iter().advance |flow| {
flow.teardown(); flow.teardown();
} }
self.first_child = None; self.first_child = None;
self.last_child = None; self.last_child = None;
for self.next_sibling.each |flow| { for self.next_sibling.iter().advance |flow| {
flow.teardown(); flow.teardown();
} }
self.next_sibling = None; self.next_sibling = None;
@ -317,14 +318,14 @@ impl<'self> FlowContext {
match *self { match *self {
BlockFlow(block) => { BlockFlow(block) => {
let block = &mut *block; let block = &mut *block;
do block.box.map_default(seed) |box| { do block.box.map_default(copy seed) |box| {
cb(seed, *box) cb(copy seed, *box)
} }
} }
InlineFlow(inline) => { InlineFlow(inline) => {
let inline = &mut *inline; let inline = &mut *inline;
do inline.boxes.foldl(seed) |acc, box| { do inline.boxes.foldl(seed) |acc, box| {
cb(*acc, *box) cb(copy *acc, *box)
} }
} }
_ => fail!(fmt!("Don't know how to iterate node's RenderBoxes for %?", self)), _ => fail!(fmt!("Don't know how to iterate node's RenderBoxes for %?", self)),
@ -349,7 +350,7 @@ impl<'self> FlowContext {
match *self { match *self {
BlockFlow(block) => { BlockFlow(block) => {
let block = &mut *block; let block = &mut *block;
for block.box.each |box| { for block.box.iter().advance |box| {
if !cb(*box) { if !cb(*box) {
break; break;
} }
@ -357,7 +358,7 @@ impl<'self> FlowContext {
} }
InlineFlow(inline) => { InlineFlow(inline) => {
let inline = &mut *inline; let inline = &mut *inline;
for inline.boxes.each |box| { for inline.boxes.iter().advance |box| {
if !cb(*box) { if !cb(*box) {
break; break;
} }

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 core::cell::Cell; use std::cell::Cell;
use core; use std;
use layout::box::{CannotSplit, GenericRenderBoxClass, ImageRenderBoxClass, RenderBox}; use layout::box::{CannotSplit, GenericRenderBoxClass, ImageRenderBoxClass, RenderBox};
use layout::box::{SplitDidFit, SplitDidNotFit, TextRenderBoxClass, UnscannedTextRenderBoxClass}; use layout::box::{SplitDidFit, SplitDidNotFit, TextRenderBoxClass, UnscannedTextRenderBoxClass};
use layout::context::LayoutContext; use layout::context::LayoutContext;
@ -12,7 +12,10 @@ use layout::flow::{FlowContext, FlowData, InlineFlow};
use layout::text::{UnscannedMethods, adapt_textbox_with_range}; use layout::text::{UnscannedMethods, adapt_textbox_with_range};
use layout::float_context::FloatContext; use layout::float_context::FloatContext;
use core::util; use std::u16;
use std::uint;
use std::util;
use std::vec;
use geom::{Point2D, Rect, Size2D}; use geom::{Point2D, Rect, Size2D};
use gfx::display_list::DisplayList; use gfx::display_list::DisplayList;
use gfx::geometry::Au; use gfx::geometry::Au;
@ -25,8 +28,8 @@ use newcss::units::{Em, Px, Pt};
use newcss::values::{CSSLineHeightNormal, CSSLineHeightNumber, CSSLineHeightLength, CSSLineHeightPercentage}; use newcss::values::{CSSLineHeightNormal, CSSLineHeightNumber, CSSLineHeightLength, CSSLineHeightPercentage};
use servo_util::range::Range; use servo_util::range::Range;
use std::deque::Deque;
use servo_util::tree::{TreeNodeRef, TreeUtils}; use servo_util::tree::{TreeNodeRef, TreeUtils};
use extra::deque::Deque;
/* /*
Lineboxes are represented as offsets into the child list, rather than Lineboxes are represented as offsets into the child list, rather than
@ -55,8 +58,8 @@ pub struct NodeRange {
range: Range, range: Range,
} }
pub impl NodeRange { impl NodeRange {
fn new(node: AbstractNode<LayoutView>, range: &Range) -> NodeRange { pub fn new(node: AbstractNode<LayoutView>, range: &Range) -> NodeRange {
NodeRange { node: node, range: copy *range } NodeRange { node: node, range: copy *range }
} }
} }
@ -326,9 +329,9 @@ impl TextRunScanner {
let mut new_ranges: ~[Range] = ~[]; let mut new_ranges: ~[Range] = ~[];
let mut char_total = 0; let mut char_total = 0;
for uint::range(0, transformed_strs.len()) |i| { for uint::range(0, transformed_strs.len()) |i| {
let added_chars = str::char_len(transformed_strs[i]); let added_chars = transformed_strs[i].char_len();
new_ranges.push(Range::new(char_total, added_chars)); new_ranges.push(Range::new(char_total, added_chars));
str::push_str(&mut run_str, transformed_strs[i]); run_str.push_str(transformed_strs[i]);
char_total += added_chars; char_total += added_chars;
} }
@ -415,7 +418,7 @@ impl LineboxScanner {
flow: inline, flow: inline,
new_boxes: ~[], new_boxes: ~[],
work_list: @mut Deque::new(), work_list: @mut Deque::new(),
pending_line: PendingLine {mut range: Range::empty(), mut bounds: Rect(Point2D(Au(0), Au(0)), Size2D(Au(0), Au(0)))}, pending_line: PendingLine {range: Range::empty(), bounds: Rect(Point2D(Au(0), Au(0)), Size2D(Au(0), Au(0)))},
line_spans: ~[], line_spans: ~[],
} }
} }
@ -637,7 +640,7 @@ impl LineboxScanner {
debug!("LineboxScanner: Pushing box b%d to line %u", box.id(), self.line_spans.len()); debug!("LineboxScanner: Pushing box b%d to line %u", box.id(), self.line_spans.len());
if self.pending_line.range.length() == 0 { if self.pending_line.range.length() == 0 {
assert!(self.new_boxes.len() <= (core::u16::max_value as uint)); assert!(self.new_boxes.len() <= (u16::max_value 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);

View file

@ -15,9 +15,9 @@ use layout::context::LayoutContext;
use layout::display_list_builder::{DisplayListBuilder, FlowDisplayListBuilderMethods}; use layout::display_list_builder::{DisplayListBuilder, FlowDisplayListBuilderMethods};
use layout::flow::FlowContext; use layout::flow::FlowContext;
use core::cast::transmute; use std::cast::transmute;
use core::cell::Cell; use std::cell::Cell;
use core::comm::{Chan, Port}; use std::comm::{Chan, Port};
use geom::point::Point2D; use geom::point::Point2D;
use geom::rect::Rect; use geom::rect::Rect;
use geom::size::Size2D; use geom::size::Size2D;
@ -43,7 +43,7 @@ use servo_net::local_image_cache::LocalImageCache;
use servo_util::tree::{TreeNodeRef, TreeUtils}; use servo_util::tree::{TreeNodeRef, TreeUtils};
use servo_util::time::{ProfilerChan, profile, time}; use servo_util::time::{ProfilerChan, profile, time};
use servo_util::time; use servo_util::time;
use std::net::url::Url; use extra::net::url::Url;
pub fn create_layout_task(port: Port<Msg>, pub fn create_layout_task(port: Port<Msg>,
script_chan: ScriptChan, script_chan: ScriptChan,
@ -51,7 +51,7 @@ pub fn create_layout_task(port: Port<Msg>,
img_cache_task: ImageCacheTask, img_cache_task: ImageCacheTask,
opts: Opts, opts: Opts,
profiler_chan: ProfilerChan) { profiler_chan: ProfilerChan) {
let port = Cell(port); let port = Cell::new(port);
do spawn { do spawn {
let mut layout = Layout::new(port.take(), let mut layout = Layout::new(port.take(),
script_chan.clone(), script_chan.clone(),
@ -129,14 +129,14 @@ impl Layout {
match self.port.recv() { match self.port.recv() {
AddStylesheetMsg(sheet) => self.handle_add_stylesheet(sheet), AddStylesheetMsg(sheet) => self.handle_add_stylesheet(sheet),
ReflowMsg(data) => { ReflowMsg(data) => {
let data = Cell(data); let data = Cell::new(data);
do profile(time::LayoutPerformCategory, self.profiler_chan.clone()) { do profile(time::LayoutPerformCategory, self.profiler_chan.clone()) {
self.handle_reflow(data.take()); self.handle_reflow(data.take());
} }
} }
QueryMsg(query, chan) => { QueryMsg(query, chan) => {
let chan = Cell(chan); let chan = Cell::new(chan);
do profile(time::LayoutQueryCategory, self.profiler_chan.clone()) { do profile(time::LayoutQueryCategory, self.profiler_chan.clone()) {
self.handle_query(query, chan.take()); self.handle_query(query, chan.take());
} }
@ -154,7 +154,7 @@ impl Layout {
} }
fn handle_add_stylesheet(&self, sheet: Stylesheet) { fn handle_add_stylesheet(&self, sheet: Stylesheet) {
let sheet = Cell(sheet); let sheet = Cell::new(sheet);
self.css_select_ctx.append_sheet(sheet.take(), OriginAuthor); self.css_select_ctx.append_sheet(sheet.take(), OriginAuthor);
} }
@ -237,7 +237,7 @@ impl Layout {
ctx: &layout_ctx, ctx: &layout_ctx,
}; };
let display_list = @Cell(DisplayList::new()); let display_list = @Cell::new(DisplayList::new());
// TODO: Set options on the builder before building. // TODO: Set options on the builder before building.
// TODO: Be smarter about what needs painting. // TODO: Be smarter about what needs painting.
@ -346,7 +346,7 @@ impl Layout {
ctx: &layout_ctx, ctx: &layout_ctx,
}; };
let display_list: @Cell<DisplayList<RenderBox>> = let display_list: @Cell<DisplayList<RenderBox>> =
@Cell(DisplayList::new()); @Cell::new(DisplayList::new());
flow.build_display_list(&builder, flow.build_display_list(&builder,
&flow.position(), &flow.position(),
display_list); display_list);
@ -355,7 +355,7 @@ impl Layout {
let mut resp = Err(()); let mut resp = Err(());
let display_list = &display_list.take().list; let display_list = &display_list.take().list;
// iterate in reverse to ensure we have the most recently painted render box // iterate in reverse to ensure we have the most recently painted render box
for display_list.each_reverse |display_item| { for display_list.rev_iter().advance |display_item| {
let bounds = display_item.bounds(); let bounds = display_item.bounds();
// TODO this check should really be performed by a method of DisplayItem // TODO this check should really be performed by a method of DisplayItem
if x <= bounds.origin.x + bounds.size.width && if x <= bounds.origin.x + bounds.size.width &&

View file

@ -7,8 +7,8 @@
use layout::display_list_builder::{ExtraDisplayListData, ToGfxColor}; use layout::display_list_builder::{ExtraDisplayListData, ToGfxColor};
use layout::box::RenderBox; use layout::box::RenderBox;
use core::cell::Cell; use std::cell::Cell;
use core::num::Zero; use std::num::Zero;
use geom::point::Point2D; use geom::point::Point2D;
use geom::rect::Rect; use geom::rect::Rect;
use geom::size::Size2D; use geom::size::Size2D;
@ -172,7 +172,8 @@ impl RenderBox {
// Are all the widths equal? // Are all the widths equal?
// //
// FIXME(pcwalton): Obviously this is wrong. // FIXME(pcwalton): Obviously this is wrong.
if [ border.top, border.right, border.bottom ].all(|a| *a == border.left) { let borders = [ border.top, border.right, border.bottom ];
if borders.iter().all(|a| *a == border.left) {
let border_width = border.top; let border_width = border.top;
let bounds = Rect { let bounds = Rect {
origin: Point2D { origin: Point2D {

View file

@ -12,7 +12,7 @@ use windowing::{ResizeCallback, ScrollCallback, WindowMethods, WindowMouseEvent,
use windowing::{WindowMouseDownEvent, WindowMouseUpEvent, ZoomCallback}; use windowing::{WindowMouseDownEvent, WindowMouseUpEvent, ZoomCallback};
use alert::{Alert, AlertMethods}; use alert::{Alert, AlertMethods};
use core::libc::c_int; use std::libc::c_int;
use geom::point::Point2D; use geom::point::Point2D;
use geom::size::Size2D; use geom::size::Size2D;
use servo_msg::compositor::{IdleRenderState, RenderState, RenderingRenderState}; use servo_msg::compositor::{IdleRenderState, RenderState, RenderingRenderState};
@ -59,8 +59,7 @@ impl WindowMethods<Application> for Window {
/// Creates a new window. /// Creates a new window.
pub fn new(_: &Application) -> @mut Window { pub fn new(_: &Application) -> @mut Window {
// Create the GLUT window. // Create the GLUT window.
// FIXME (Rust #3080): These unsafe blocks are *not* unused! unsafe { glut::glutInitWindowSize(800, 600); }
/*unsafe { */glut::bindgen::glutInitWindowSize(800, 600);/* }*/
let glut_window = glut::create_window(~"Servo"); let glut_window = glut::create_window(~"Servo");
// Create our window object. // Create our window object.
@ -74,10 +73,10 @@ impl WindowMethods<Application> for Window {
scroll_callback: None, scroll_callback: None,
zoom_callback: None, zoom_callback: None,
drag_origin: Point2D(0, 0), drag_origin: Point2D(0 as c_int, 0),
mouse_down_button: @mut 0, mouse_down_button: @mut 0,
mouse_down_point: @mut Point2D(0, 0), mouse_down_point: @mut Point2D(0 as c_int, 0),
ready_state: FinishedLoading, ready_state: FinishedLoading,
render_state: IdleRenderState, render_state: IdleRenderState,
@ -231,12 +230,12 @@ impl Window {
match key { match key {
12 => self.load_url(), // Ctrl+L 12 => self.load_url(), // Ctrl+L
k if k == ('=' as u8) && (glut::get_modifiers() & ACTIVE_CTRL) != 0 => { // Ctrl++ k if k == ('=' as u8) && (glut::get_modifiers() & ACTIVE_CTRL) != 0 => { // Ctrl++
for self.zoom_callback.each |&callback| { for self.zoom_callback.iter().advance |&callback| {
callback(0.1); callback(0.1);
} }
} }
k if k == 31 && (glut::get_modifiers() & ACTIVE_CTRL) != 0 => { // Ctrl+- k if k == 31 && (glut::get_modifiers() & ACTIVE_CTRL) != 0 => { // Ctrl+-
for self.zoom_callback.each |&callback| { for self.zoom_callback.iter().advance |&callback| {
callback(-0.1); callback(-0.1);
} }
} }

View file

@ -27,7 +27,7 @@ extern mod servo_msg (name = "msg");
extern mod servo_util (name = "util"); extern mod servo_util (name = "util");
extern mod sharegl; extern mod sharegl;
extern mod stb_image; extern mod stb_image;
extern mod std; extern mod extra;
#[cfg(target_os="macos")] #[cfg(target_os="macos")]
extern mod core_graphics; extern mod core_graphics;
@ -42,11 +42,13 @@ use gfx::opts;
use servo_net::image_cache_task::ImageCacheTask; use servo_net::image_cache_task::ImageCacheTask;
use servo_net::resource_task::ResourceTask; use servo_net::resource_task::ResourceTask;
use servo_util::time::{Profiler, ProfilerChan, PrintMsg}; use servo_util::time::{Profiler, ProfilerChan, PrintMsg};
use std::uv_global_loop; use extra::uv_global_loop;
pub use gfx::opts::Opts; pub use gfx::opts::Opts;
pub use gfx::text; pub use gfx::text;
pub use servo_util::url::make_url; pub use servo_util::url::make_url;
use std::comm;
use std::os;
#[path="compositing/mod.rs"] #[path="compositing/mod.rs"]
pub mod compositing; pub mod compositing;
@ -102,7 +104,7 @@ fn run(opts: &Opts) {
let period = *period; let period = *period;
do spawn { do spawn {
loop { loop {
std::timer::sleep(&uv_global_loop::get(), extra::timer::sleep(&uv_global_loop::get(),
(period * 1000f64) as uint); (period * 1000f64) as uint);
profiler_chan.send(PrintMsg); profiler_chan.send(PrintMsg);
} }

View file

@ -2,9 +2,10 @@
* 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 core::cell::Cell; use std::cell::Cell;
use core::comm::{Chan, Port}; use std::comm;
use core::task; use std::comm::{Chan, Port};
use std::task;
pub fn spawn_listener<A: Owned>(f: ~fn(Port<A>)) -> Chan<A> { pub fn spawn_listener<A: Owned>(f: ~fn(Port<A>)) -> Chan<A> {
let (setup_po, setup_ch) = comm::stream(); let (setup_po, setup_ch) = comm::stream();
@ -18,7 +19,7 @@ pub fn spawn_listener<A: Owned>(f: ~fn(Port<A>)) -> Chan<A> {
pub fn spawn_conversation<A: Owned, B: Owned>(f: ~fn(Port<A>, Chan<B>)) -> (Port<B>, Chan<A>) { pub fn spawn_conversation<A: Owned, B: Owned>(f: ~fn(Port<A>, Chan<B>)) -> (Port<B>, Chan<A>) {
let (from_child, to_parent) = comm::stream(); let (from_child, to_parent) = comm::stream();
let to_parent = Cell(to_parent); let to_parent = Cell::new(to_parent);
let to_child = do spawn_listener |from_parent| { let to_child = do spawn_listener |from_parent| {
f(from_parent, to_parent.take()) f(from_parent, to_parent.take())
}; };

View file

@ -5,8 +5,8 @@
//! The high-level interface from script to engine. Using this abstract interface helps reduce //! The high-level interface from script to engine. Using this abstract interface helps reduce
/// coupling between these two components /// coupling between these two components
use core::comm::{Chan, SharedChan}; use std::comm::{Chan, SharedChan};
use std::net::url::Url; use extra::net::url::Url;
#[deriving(Clone)] #[deriving(Clone)]
pub struct EngineChan { pub struct EngineChan {

View file

@ -10,9 +10,9 @@
extern mod azure; extern mod azure;
extern mod core;
extern mod geom;
extern mod std; extern mod std;
extern mod geom;
extern mod extra;
pub mod compositor; pub mod compositor;
pub mod engine; pub mod engine;

View file

@ -4,8 +4,8 @@
use resource_task::{Done, LoaderTask, Payload}; use resource_task::{Done, LoaderTask, Payload};
use core::io::{ReaderUtil, file_reader}; use std::io::{ReaderUtil, file_reader};
use core::task; use std::task;
static READ_SIZE: uint = 1024; static READ_SIZE: uint = 1024;

View file

@ -4,8 +4,8 @@
use resource_task::{Payload, Done, LoaderTask}; use resource_task::{Payload, Done, LoaderTask};
use core::comm::SharedChan; use std::comm::SharedChan;
use core::task; use std::task;
use http_client::uv_http_request; use http_client::uv_http_request;
use http_client; use http_client;

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 std::vec;
use stb_image = stb_image::image; use stb_image = stb_image::image;
// FIXME: Images must not be copied every frame. Instead we should atomically // FIXME: Images must not be copied every frame. Instead we should atomically

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 core::util::replace; use std::util::replace;
use geom::size::Size2D; use geom::size::Size2D;
use std::net::url::Url; use extra::net::url::Url;
use std::arc::{ARC, clone, get}; use extra::arc::ARC;
// 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
@ -24,7 +24,7 @@ pub struct ImageHolder {
local_image_cache: @mut LocalImageCache, local_image_cache: @mut LocalImageCache,
} }
pub impl ImageHolder { impl ImageHolder {
pub fn new(url: Url, local_image_cache: @mut LocalImageCache) -> ImageHolder { pub fn new(url: Url, local_image_cache: @mut LocalImageCache) -> ImageHolder {
debug!("ImageHolder::new() %?", url.to_str()); debug!("ImageHolder::new() %?", url.to_str());
let holder = ImageHolder { let holder = ImageHolder {
@ -50,16 +50,16 @@ pub impl ImageHolder {
/// ///
/// The intent is that the impure version is used during layout when dimensions are used for /// The intent is that the impure version is used during layout when dimensions are used for
/// computing layout. /// computing layout.
fn size(&self) -> Size2D<int> { pub fn size(&self) -> Size2D<int> {
self.cached_size self.cached_size
} }
/// Query and update the current image size. /// Query and update the current image size.
fn get_size(&mut self) -> Option<Size2D<int>> { pub fn get_size(&mut self) -> Option<Size2D<int>> {
debug!("get_size() %?", self.url); debug!("get_size() %?", self.url);
match self.get_image() { match self.get_image() {
Some(img) => { Some(img) => {
let img_ref = get(&img); let img_ref = img.get();
self.cached_size = Size2D(img_ref.width as int, self.cached_size = Size2D(img_ref.width as int,
img_ref.height as int); img_ref.height as int);
Some(copy self.cached_size) Some(copy self.cached_size)
@ -68,7 +68,7 @@ pub impl ImageHolder {
} }
} }
fn get_image(&mut self) -> Option<ARC<~Image>> { pub fn get_image(&mut self) -> Option<ARC<~Image>> {
debug!("get_image() %?", self.url); debug!("get_image() %?", self.url);
// If this is the first time we've called this function, load // If this is the first time we've called this function, load
@ -91,7 +91,7 @@ pub impl ImageHolder {
let image = replace(&mut self.image, None); let image = replace(&mut self.image, None);
let result = match image { let result = match image {
Some(ref image) => Some(clone(image)), Some(ref image) => Some(image.clone()),
None => None None => None
}; };

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 clone_arc = std::arc::clone; use std::cell::Cell;
use core::cell::Cell; use std::comm::{Chan, Port, SharedChan, stream};
use core::comm::{Chan, Port, SharedChan, stream}; use std::task::spawn;
use core::task::spawn; use std::to_str::ToStr;
use core::to_str::ToStr; use std::util::replace;
use core::util::replace; use std::result;
use std::arc::ARC; use extra::arc::ARC;
use std::net::url::Url; use extra::net::url::Url;
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
@ -54,7 +54,7 @@ pub enum ImageResponseMsg {
impl ImageResponseMsg { impl ImageResponseMsg {
fn clone(&self) -> ImageResponseMsg { fn clone(&self) -> ImageResponseMsg {
match *self { match *self {
ImageReady(ref img) => ImageReady(clone_arc(img)), ImageReady(ref img) => ImageReady(img.clone()),
ImageNotReady => ImageNotReady, ImageNotReady => ImageNotReady,
ImageFailed => ImageFailed, ImageFailed => ImageFailed,
} }
@ -91,12 +91,12 @@ pub fn ImageCacheTask_(resource_task: ResourceTask, decoder_factory: DecoderFact
// FIXME: Doing some dancing to avoid copying decoder_factory, our test // FIXME: Doing some dancing to avoid copying decoder_factory, our test
// version of which contains an uncopyable type which rust will currently // version of which contains an uncopyable type which rust will currently
// copy unsoundly // copy unsoundly
let decoder_factory_cell = Cell(decoder_factory); let decoder_factory_cell = Cell::new(decoder_factory);
let (port, chan) = stream(); let (port, chan) = stream();
let chan = SharedChan::new(chan); let chan = SharedChan::new(chan);
let port_cell = Cell(port); let port_cell = Cell::new(port);
let chan_cell = Cell(chan.clone()); let chan_cell = Cell::new(chan.clone());
do spawn { do spawn {
let mut cache = ImageCache { let mut cache = ImageCache {
@ -116,7 +116,7 @@ pub fn ImageCacheTask_(resource_task: ResourceTask, decoder_factory: DecoderFact
fn SyncImageCacheTask(resource_task: ResourceTask) -> ImageCacheTask { fn SyncImageCacheTask(resource_task: ResourceTask) -> ImageCacheTask {
let (port, chan) = stream(); let (port, chan) = stream();
let port_cell = Cell(port); let port_cell = Cell::new(port);
do spawn { do spawn {
let port = port_cell.take(); let port = port_cell.take();
@ -247,7 +247,7 @@ impl ImageCache {
Init => { Init => {
let to_cache = self.chan.clone(); let to_cache = self.chan.clone();
let resource_task = self.resource_task.clone(); let resource_task = self.resource_task.clone();
let url_cell = Cell(copy url); let url_cell = Cell::new(copy url);
do spawn { do spawn {
let url = url_cell.take(); let url = url_cell.take();
@ -256,7 +256,7 @@ impl ImageCache {
let image = load_image_data(copy url, resource_task.clone()); let image = load_image_data(copy url, resource_task.clone());
let result = if image.is_ok() { let result = if image.is_ok() {
Ok(Cell(result::unwrap(image))) Ok(Cell::new(result::unwrap(image)))
} else { } else {
Err(()) Err(())
}; };
@ -279,7 +279,7 @@ impl ImageCache {
match data { match data {
Ok(data_cell) => { Ok(data_cell) => {
let data = data_cell.take(); let data = data_cell.take();
self.set_state(copy url, Prefetched(@Cell(data))); self.set_state(copy url, Prefetched(@Cell::new(data)));
match next_step { match next_step {
DoDecode => self.decode(url), DoDecode => self.decode(url),
_ => () _ => ()
@ -320,7 +320,7 @@ impl ImageCache {
let data = data_cell.take(); let data = data_cell.take();
let to_cache = self.chan.clone(); let to_cache = self.chan.clone();
let url_cell = Cell(copy url); let url_cell = Cell::new(copy url);
let decode = (self.decoder_factory)(); let decode = (self.decoder_factory)();
do spawn { do spawn {
@ -351,8 +351,8 @@ impl ImageCache {
Decoding => { Decoding => {
match image { match image {
Some(image) => { Some(image) => {
self.set_state(copy url, Decoded(@clone_arc(&image))); self.set_state(copy url, Decoded(@image.clone()));
self.purge_waiters(url, || ImageReady(clone_arc(&image)) ); self.purge_waiters(url, || ImageReady(image.clone()) );
} }
None => { None => {
self.set_state(copy url, Failed); self.set_state(copy url, Failed);
@ -389,7 +389,7 @@ impl ImageCache {
Prefetching(DoDecode) => response.send(ImageNotReady), Prefetching(DoDecode) => response.send(ImageNotReady),
Prefetching(DoNotDecode) | Prefetched(*) => fail!(~"request for image before decode"), Prefetching(DoNotDecode) | Prefetched(*) => fail!(~"request for image before decode"),
Decoding => response.send(ImageNotReady), Decoding => response.send(ImageNotReady),
Decoded(image) => response.send(ImageReady(clone_arc(image))), Decoded(image) => response.send(ImageReady((*image).clone())),
Failed => response.send(ImageFailed), Failed => response.send(ImageFailed),
} }
} }
@ -411,7 +411,7 @@ impl ImageCache {
} }
Decoded(image) => { Decoded(image) => {
response.send(ImageReady(clone_arc(image))); response.send(ImageReady((*image).clone()));
} }
Failed => { Failed => {

View file

@ -11,16 +11,17 @@ multiple times and thus triggering reflows multiple times.
use image_cache_task::{Decode, GetImage, ImageCacheTask, ImageFailed, ImageNotReady, ImageReady}; use image_cache_task::{Decode, GetImage, ImageCacheTask, ImageFailed, ImageNotReady, ImageReady};
use image_cache_task::{ImageResponseMsg, Prefetch, WaitForImage}; use image_cache_task::{ImageResponseMsg, Prefetch, WaitForImage};
use clone_arc = std::arc::clone; use std::comm;
use core::comm::Port; use std::comm::Port;
use std::task;
use servo_util::url::{UrlMap, url_map}; use servo_util::url::{UrlMap, url_map};
use std::net::url::Url; use extra::net::url::Url;
pub fn LocalImageCache(image_cache_task: ImageCacheTask) -> LocalImageCache { pub fn LocalImageCache(image_cache_task: ImageCacheTask) -> LocalImageCache {
LocalImageCache { LocalImageCache {
image_cache_task: image_cache_task, image_cache_task: image_cache_task,
round_number: 1, round_number: 1,
mut on_image_available: None, on_image_available: None,
state_map: url_map() state_map: url_map()
} }
} }
@ -40,7 +41,7 @@ priv struct ImageState {
} }
#[allow(non_implicitly_copyable_typarams)] // Using maps of Urls #[allow(non_implicitly_copyable_typarams)] // Using maps of Urls
pub impl LocalImageCache { impl LocalImageCache {
/// The local cache will only do a single remote request for a given /// The local cache will only do a single remote request for a given
/// URL in each 'round'. Layout should call this each time it begins /// URL in each 'round'. Layout should call this each time it begins
pub fn next_round(&mut self, on_image_available: @fn() -> ~fn(ImageResponseMsg)) { pub fn next_round(&mut self, on_image_available: @fn() -> ~fn(ImageResponseMsg)) {
@ -76,7 +77,7 @@ pub impl LocalImageCache {
match state.last_response { match state.last_response {
ImageReady(ref image) => { ImageReady(ref image) => {
let (port, chan) = comm::stream(); let (port, chan) = comm::stream();
chan.send(ImageReady(clone_arc(image))); chan.send(ImageReady(image.clone()));
return port; return port;
} }
ImageNotReady => { ImageNotReady => {
@ -122,7 +123,7 @@ pub impl LocalImageCache {
// Put a copy of the response in the cache // Put a copy of the response in the cache
let response_copy = match response { let response_copy = match response {
ImageReady(ref image) => ImageReady(clone_arc(image)), ImageReady(ref image) => ImageReady(image.clone()),
ImageNotReady => ImageNotReady, ImageNotReady => ImageNotReady,
ImageFailed => ImageFailed ImageFailed => ImageFailed
}; };

View file

@ -12,7 +12,7 @@ extern mod geom;
extern mod http_client; extern mod http_client;
extern mod servo_util (name = "util"); extern mod servo_util (name = "util");
extern mod stb_image; extern mod stb_image;
extern mod std; extern mod extra;
/// Image handling. /// Image handling.
/// ///

View file

@ -7,9 +7,9 @@
use file_loader; use file_loader;
use http_loader; use http_loader;
use core::cell::Cell; use std::cell::Cell;
use core::comm::{Chan, Port, SharedChan}; use std::comm::{Chan, Port, SharedChan};
use std::net::url::{Url, to_str}; use extra::net::url::{Url, to_str};
use util::spawn_listener; use util::spawn_listener;
pub enum ControlMsg { pub enum ControlMsg {
@ -52,7 +52,7 @@ 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 loaders_cell = Cell(loaders); let loaders_cell = Cell::new(loaders);
let chan = do spawn_listener |from_client| { let chan = do spawn_listener |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_cell.take()).start() ResourceManager(from_client, loaders_cell.take()).start()

View file

@ -2,7 +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 core::comm::{Chan, Port}; use std::comm;
use std::comm::{Chan, Port};
use std::task;
pub fn spawn_listener<A: Owned>(f: ~fn(Port<A>)) -> Chan<A> { pub fn spawn_listener<A: Owned>(f: ~fn(Port<A>)) -> Chan<A> {
let (setup_port, setup_chan) = comm::stream(); let (setup_port, setup_chan) = comm::stream();

View file

@ -8,9 +8,11 @@ use dom::clientrect::ClientRect;
use script_task::{task_from_context, global_script_context}; use script_task::{task_from_context, global_script_context};
use js::jsapi::{JSObject, JSContext, JSVal}; use js::jsapi::{JSObject, JSContext, JSVal};
use js::glue::bindgen::RUST_OBJECT_TO_JSVAL; use js::glue::RUST_OBJECT_TO_JSVAL;
pub impl ClientRect { use std::cast;
impl ClientRect {
pub fn init_wrapper(@mut self) { pub fn init_wrapper(@mut self) {
let script_context = global_script_context(); let script_context = global_script_context();
let cx = script_context.js_compartment.cx.ptr; let cx = script_context.js_compartment.cx.ptr;

View file

@ -9,8 +9,10 @@ use script_task::{task_from_context, global_script_context};
use js::jsapi::{JSObject, JSContext}; use js::jsapi::{JSObject, JSContext};
pub impl ClientRectList { use std::cast;
fn init_wrapper(@mut self) {
impl ClientRectList {
pub fn init_wrapper(@mut self) {
let script_context = global_script_context(); let script_context = global_script_context();
let cx = script_context.js_compartment.cx.ptr; let cx = script_context.js_compartment.cx.ptr;
let owner = script_context.root_frame.get_ref().window; let owner = script_context.root_frame.get_ref().window;

View file

@ -2853,7 +2853,7 @@ class CGCallGenerator(CGThing):
""" """
def __init__(self, errorReport, arguments, argsPre, returnType, def __init__(self, errorReport, arguments, argsPre, returnType,
extendedAttributes, descriptorProvider, nativeMethodName, extendedAttributes, descriptorProvider, nativeMethodName,
static, object="self", declareResult=True): static, object="this", declareResult=True):
CGThing.__init__(self) CGThing.__init__(self)
assert errorReport is None or isinstance(errorReport, CGThing) assert errorReport is None or isinstance(errorReport, CGThing)
@ -3070,7 +3070,7 @@ class CGAbstractBindingMethod(CGAbstractExternMethod):
unwrapThis = CGIndenter(CGGeneric( unwrapThis = CGIndenter(CGGeneric(
str(CastableObjectUnwrapper( str(CastableObjectUnwrapper(
FakeCastableDescriptor(self.descriptor), FakeCastableDescriptor(self.descriptor),
"obj", "self", self.unwrapFailureCode)))) "obj", "this", self.unwrapFailureCode))))
return CGList([ self.getThis(), unwrapThis, return CGList([ self.getThis(), unwrapThis,
self.generate_code() ], "\n").define() self.generate_code() ], "\n").define()
@ -3081,7 +3081,7 @@ class CGAbstractBindingMethod(CGAbstractExternMethod):
" return false as JSBool;\n" " return false as JSBool;\n"
"}\n" "}\n"
"\n" "\n"
"let self: *rust_box<%s>;" % self.descriptor.nativeType)) "let this: *rust_box<%s>;" % self.descriptor.nativeType))
def generate_code(self): def generate_code(self):
assert(False) # Override me assert(False) # Override me
@ -3098,7 +3098,7 @@ class CGGenericMethod(CGAbstractBindingMethod):
def generate_code(self): def generate_code(self):
return CGIndenter(CGGeneric( return CGIndenter(CGGeneric(
"let _info: *JSJitInfo = RUST_FUNCTION_VALUE_TO_JITINFO(JS_CALLEE(cx, vp));\n" "let _info: *JSJitInfo = RUST_FUNCTION_VALUE_TO_JITINFO(JS_CALLEE(cx, vp));\n"
"return CallJitMethodOp(_info, cx, obj, ptr::to_unsafe_ptr(&(*self).payload) as *libc::c_void, argc, vp);")) "return CallJitMethodOp(_info, cx, obj, ptr::to_unsafe_ptr(&(*this).payload) as *libc::c_void, argc, vp);"))
class CGAbstractStaticMethod(CGAbstractMethod): class CGAbstractStaticMethod(CGAbstractMethod):
""" """
@ -3121,7 +3121,7 @@ class CGSpecializedMethod(CGAbstractExternMethod):
self.method = method self.method = method
name = method.identifier.name name = method.identifier.name
args = [Argument('*JSContext', 'cx'), Argument('JSHandleObject', 'obj'), args = [Argument('*JSContext', 'cx'), Argument('JSHandleObject', 'obj'),
Argument('*mut %s' % descriptor.nativeType, 'self'), Argument('*mut %s' % descriptor.nativeType, 'this'),
Argument('libc::c_uint', 'argc'), Argument('*mut JSVal', 'vp')] Argument('libc::c_uint', 'argc'), Argument('*mut JSVal', 'vp')]
CGAbstractExternMethod.__init__(self, descriptor, name, 'JSBool', args) CGAbstractExternMethod.__init__(self, descriptor, name, 'JSBool', args)
@ -3154,7 +3154,7 @@ class CGGenericGetter(CGAbstractBindingMethod):
def generate_code(self): def generate_code(self):
return CGIndenter(CGGeneric( return CGIndenter(CGGeneric(
"let _info: *JSJitInfo = RUST_FUNCTION_VALUE_TO_JITINFO(JS_CALLEE(cx, vp));\n" "let _info: *JSJitInfo = RUST_FUNCTION_VALUE_TO_JITINFO(JS_CALLEE(cx, vp));\n"
"return CallJitPropertyOp(_info, cx, obj, ptr::to_unsafe_ptr(&(*self).payload) as *libc::c_void, vp);")) "return CallJitPropertyOp(_info, cx, obj, ptr::to_unsafe_ptr(&(*this).payload) as *libc::c_void, vp);"))
class CGSpecializedGetter(CGAbstractExternMethod): class CGSpecializedGetter(CGAbstractExternMethod):
""" """
@ -3166,7 +3166,7 @@ class CGSpecializedGetter(CGAbstractExternMethod):
name = 'get_' + attr.identifier.name name = 'get_' + attr.identifier.name
args = [ Argument('*JSContext', 'cx'), args = [ Argument('*JSContext', 'cx'),
Argument('JSHandleObject', 'obj'), Argument('JSHandleObject', 'obj'),
Argument('*%s' % descriptor.nativeType, 'self'), Argument('*%s' % descriptor.nativeType, 'this'),
Argument('*mut JSVal', 'vp') ] Argument('*mut JSVal', 'vp') ]
CGAbstractExternMethod.__init__(self, descriptor, name, "JSBool", args) CGAbstractExternMethod.__init__(self, descriptor, name, "JSBool", args)
@ -3466,7 +3466,7 @@ if expando.is_not_null() {
getIndexedOrExpando = ("let index = GetArrayIndexFromId(cx, id);\n" + getIndexedOrExpando = ("let index = GetArrayIndexFromId(cx, id);\n" +
"if index.is_some() {\n" + "if index.is_some() {\n" +
" let index = index.get();\n" + " let index = index.get();\n" +
" let self = UnwrapProxy(proxy);\n" + " let this = UnwrapProxy(proxy);\n" +
CGIndenter(CGProxyIndexedGetter(self.descriptor, templateValues)).define()) CGIndenter(CGProxyIndexedGetter(self.descriptor, templateValues)).define())
getIndexedOrExpando += """ getIndexedOrExpando += """
// Even if we don't have this index, we don't forward the // Even if we don't have this index, we don't forward the
@ -3488,7 +3488,7 @@ if expando.is_not_null() {
" return false;\n" + " return false;\n" +
" }\n" + " }\n" +
"\n" + "\n" +
" let self = UnwrapProxy(proxy);\n" + " let this = UnwrapProxy(proxy);\n" +
CGIndenter(CGProxyNamedGetter(self.descriptor, templateValues)).define() + CGIndenter(CGProxyNamedGetter(self.descriptor, templateValues)).define() +
"}\n") % (self.descriptor.nativeType) "}\n") % (self.descriptor.nativeType)
else: else:
@ -3558,7 +3558,7 @@ class CGAbstractClassHook(CGAbstractExternMethod):
def definition_body_prologue(self): def definition_body_prologue(self):
return "" #XXXjdm we may want to do a proper unwrap here return "" #XXXjdm we may want to do a proper unwrap here
return """ return """
let self: *%s = &(unwrap::<*rust_box<%s>>(obj).payload); let this: *%s = &(unwrap::<*rust_box<%s>>(obj).payload);
""" % (self.descriptor.nativeType, self.descriptor.nativeType) """ % (self.descriptor.nativeType, self.descriptor.nativeType)
def definition_body(self): def definition_body(self):
@ -3570,8 +3570,8 @@ class CGAbstractClassHook(CGAbstractExternMethod):
def finalizeHook(descriptor, hookName, context): def finalizeHook(descriptor, hookName, context):
if descriptor.customFinalize: if descriptor.customFinalize:
return """if (self) { return """if (this) {
self->%s(%s); this->%s(%s);
}""" % (hookName, context) }""" % (hookName, context)
#clearWrapper = "ClearWrapper(self, self);\n" if descriptor.wrapperCache else "" #clearWrapper = "ClearWrapper(self, self);\n" if descriptor.wrapperCache else ""
if descriptor.workers: if descriptor.workers:
@ -4132,9 +4132,7 @@ class CGBindingRoot(CGThing):
dictionaries, dictionaries,
['js::*', ['js::*',
'js::jsapi::*', 'js::jsapi::*',
'js::jsapi::bindgen::*',
'js::jsfriendapi::bindgen::*', 'js::jsfriendapi::bindgen::*',
'js::glue::bindgen::*',
'js::glue::*', 'js::glue::*',
'dom::node::AbstractNode', #XXXjdm 'dom::node::AbstractNode', #XXXjdm
'dom::document::Document', #XXXjdm 'dom::document::Document', #XXXjdm
@ -4150,6 +4148,11 @@ class CGBindingRoot(CGThing):
'script_task::task_from_context', 'script_task::task_from_context',
'dom::bindings::utils::EnumEntry', 'dom::bindings::utils::EnumEntry',
'dom::node::ScriptView', 'dom::node::ScriptView',
'std::cast',
'std::libc',
'std::ptr',
'std::vec',
'std::str'
], ],
[], [],
curr) curr)

View file

@ -4,7 +4,7 @@
use js::jsapi::JSVal; use js::jsapi::JSVal;
use js::{JSVAL_FALSE, JSVAL_TRUE}; use js::{JSVAL_FALSE, JSVAL_TRUE};
use js::glue::bindgen::{RUST_UINT_TO_JSVAL, RUST_JSVAL_TO_INT}; use js::glue::{RUST_UINT_TO_JSVAL, RUST_JSVAL_TO_INT};
pub trait JSValConvertible { pub trait JSValConvertible {
fn to_jsval(&self) -> JSVal; fn to_jsval(&self) -> JSVal;
@ -13,12 +13,16 @@ pub trait JSValConvertible {
impl JSValConvertible for u32 { impl JSValConvertible for u32 {
fn to_jsval(&self) -> JSVal { fn to_jsval(&self) -> JSVal {
unsafe {
RUST_UINT_TO_JSVAL(*self) RUST_UINT_TO_JSVAL(*self)
} }
}
fn from_jsval(val: JSVal) -> Option<u32> { fn from_jsval(val: JSVal) -> Option<u32> {
unsafe {
Some(RUST_JSVAL_TO_INT(val) as u32) Some(RUST_JSVAL_TO_INT(val) as u32)
} }
}
} }
impl JSValConvertible for bool { impl JSValConvertible for bool {

View file

@ -2,16 +2,21 @@
* 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::cast;
use std::libc;
use std::ptr;
use std::result;
use std::vec;
use dom::bindings::utils::{DOMString, rust_box, squirrel_away, str}; use dom::bindings::utils::{DOMString, rust_box, squirrel_away, str};
use dom::bindings::utils::{WrapperCache, DerivedWrapper}; use dom::bindings::utils::{WrapperCache, DerivedWrapper};
use dom::bindings::utils::{jsval_to_str, WrapNewBindingObject, CacheableWrapper}; use dom::bindings::utils::{jsval_to_str, WrapNewBindingObject, CacheableWrapper};
use dom::bindings::utils; use dom::bindings::utils;
use dom::document::Document; use dom::document::Document;
use dom::htmlcollection::HTMLCollection; use dom::htmlcollection::HTMLCollection;
use js::glue::bindgen::*; use js::glue::*;
use js::glue::{PROPERTY_STUB, STRICT_PROPERTY_STUB}; use js::glue::{PROPERTY_STUB, STRICT_PROPERTY_STUB};
use js::jsapi::bindgen::{JS_DefineProperties}; use js::jsapi::{JS_DefineProperties};
use js::jsapi::bindgen::{JS_GetReservedSlot, JS_SetReservedSlot, JS_DefineFunctions}; use js::jsapi::{JS_GetReservedSlot, JS_SetReservedSlot, JS_DefineFunctions};
use js::jsapi::{JSContext, JSVal, JSObject, JSBool, JSFreeOp, JSPropertySpec, JSPropertyOpWrapper}; use js::jsapi::{JSContext, JSVal, JSObject, JSBool, JSFreeOp, JSPropertySpec, JSPropertyOpWrapper};
use js::jsapi::{JSStrictPropertyOpWrapper, JSNativeWrapper, JSFunctionSpec}; use js::jsapi::{JSStrictPropertyOpWrapper, JSNativeWrapper, JSFunctionSpec};
use js::rust::{Compartment, jsobj}; use js::rust::{Compartment, jsobj};
@ -19,8 +24,8 @@ use js::{JSPROP_NATIVE_ACCESSORS};
use js::{JS_ARGV, JSPROP_ENUMERATE, JSPROP_SHARED, JSVAL_NULL, JS_THIS_OBJECT, JS_SET_RVAL}; use js::{JS_ARGV, JSPROP_ENUMERATE, JSPROP_SHARED, JSVAL_NULL, JS_THIS_OBJECT, JS_SET_RVAL};
use script_task::task_from_context; use script_task::task_from_context;
use core::libc::c_uint; use std::libc::c_uint;
use core::ptr::null; use std::ptr::null;
extern fn getDocumentElement(cx: *JSContext, _argc: c_uint, vp: *mut JSVal) -> JSBool { extern fn getDocumentElement(cx: *JSContext, _argc: c_uint, vp: *mut JSVal) -> JSBool {
unsafe { unsafe {
@ -96,9 +101,11 @@ pub fn init(compartment: @mut Compartment) {
flags: (JSPROP_SHARED | JSPROP_ENUMERATE | JSPROP_NATIVE_ACCESSORS) as u8, flags: (JSPROP_SHARED | JSPROP_ENUMERATE | JSPROP_NATIVE_ACCESSORS) as u8,
getter: JSPropertyOpWrapper {op: null(), info: null()}, getter: JSPropertyOpWrapper {op: null(), info: null()},
setter: JSStrictPropertyOpWrapper {op: null(), info: null()}}]; setter: JSStrictPropertyOpWrapper {op: null(), info: null()}}];
vec::push(&mut compartment.global_props, attrs); compartment.global_props.push(attrs);
vec::as_imm_buf(*attrs, |specs, _len| { vec::as_imm_buf(*attrs, |specs, _len| {
unsafe {
assert!(JS_DefineProperties(compartment.cx.ptr, obj.ptr, specs) == 1); assert!(JS_DefineProperties(compartment.cx.ptr, obj.ptr, specs) == 1);
}
}); });
let methods = @~[JSFunctionSpec {name: compartment.add_name(~"getElementsByTagName"), let methods = @~[JSFunctionSpec {name: compartment.add_name(~"getElementsByTagName"),
@ -112,7 +119,9 @@ pub fn init(compartment: @mut Compartment) {
flags: 0, flags: 0,
selfHostedName: null()}]; selfHostedName: null()}];
vec::as_imm_buf(*methods, |fns, _len| { vec::as_imm_buf(*methods, |fns, _len| {
unsafe {
JS_DefineFunctions(compartment.cx.ptr, obj.ptr, fns); JS_DefineFunctions(compartment.cx.ptr, obj.ptr, fns);
}
}); });
compartment.register_class(utils::instance_jsclass(~"DocumentInstance", compartment.register_class(utils::instance_jsclass(~"DocumentInstance",
@ -129,12 +138,12 @@ pub fn create(compartment: @mut Compartment, doc: @mut Document) -> *JSObject {
unsafe { unsafe {
let raw_ptr: *libc::c_void = cast::transmute(squirrel_away(doc)); let raw_ptr: *libc::c_void = cast::transmute(squirrel_away(doc));
JS_SetReservedSlot(instance.ptr, 0, RUST_PRIVATE_TO_JSVAL(raw_ptr)); JS_SetReservedSlot(instance.ptr, 0, RUST_PRIVATE_TO_JSVAL(raw_ptr));
}
compartment.define_property(~"document", RUST_OBJECT_TO_JSVAL(instance.ptr), compartment.define_property(~"document", RUST_OBJECT_TO_JSVAL(instance.ptr),
GetJSClassHookStubPointer(PROPERTY_STUB) as *u8, GetJSClassHookStubPointer(PROPERTY_STUB) as *u8,
GetJSClassHookStubPointer(STRICT_PROPERTY_STUB) as *u8, GetJSClassHookStubPointer(STRICT_PROPERTY_STUB) as *u8,
JSPROP_ENUMERATE); JSPROP_ENUMERATE);
}
instance.ptr instance.ptr
} }

View file

@ -8,7 +8,9 @@ use dom::bindings::utils::{BindingObject, DerivedWrapper};
use dom::domparser::DOMParser; use dom::domparser::DOMParser;
use js::jsapi::{JSContext, JSObject, JSVal}; use js::jsapi::{JSContext, JSObject, JSVal};
use js::glue::bindgen::{RUST_OBJECT_TO_JSVAL}; use js::glue::{RUST_OBJECT_TO_JSVAL};
use std::cast;
impl CacheableWrapper for DOMParser { impl CacheableWrapper for DOMParser {
fn get_wrappercache(&mut self) -> &mut WrapperCache { fn get_wrappercache(&mut self) -> &mut WrapperCache {

View file

@ -12,10 +12,17 @@ use layout_interface::{ContentBoxQuery, ContentBoxResponse};
use script_task::task_from_context; use script_task::task_from_context;
use super::utils; use super::utils;
use core::libc::c_uint; use std::cast;
use core::ptr::null; use std::i32;
use js::glue::bindgen::*; use std::libc;
use js::jsapi::bindgen::*; use std::libc::c_uint;
use std::ptr;
use std::ptr::null;
use std::result;
use std::str;
use std::vec;
use js::glue::*;
use js::jsapi::*;
use js::jsapi::{JSContext, JSVal, JSObject, JSBool, JSFreeOp, JSPropertySpec}; use js::jsapi::{JSContext, JSVal, JSObject, JSBool, JSFreeOp, JSPropertySpec};
use js::jsapi::{JSNativeWrapper, JSTracer, JSTRACE_OBJECT}; use js::jsapi::{JSNativeWrapper, JSTracer, JSTRACE_OBJECT};
use js::jsapi::{JSPropertyOpWrapper, JSStrictPropertyOpWrapper, JSFunctionSpec}; use js::jsapi::{JSPropertyOpWrapper, JSStrictPropertyOpWrapper, JSFunctionSpec};
@ -78,7 +85,9 @@ pub fn init(compartment: @mut Compartment) {
setter: JSStrictPropertyOpWrapper {op: null(), info: null()}}]; setter: JSStrictPropertyOpWrapper {op: null(), info: null()}}];
vec::push(&mut compartment.global_props, attrs); vec::push(&mut compartment.global_props, attrs);
vec::as_imm_buf(*attrs, |specs, _len| { vec::as_imm_buf(*attrs, |specs, _len| {
unsafe {
JS_DefineProperties(compartment.cx.ptr, obj.ptr, specs); JS_DefineProperties(compartment.cx.ptr, obj.ptr, specs);
}
}); });
let methods = @~[JSFunctionSpec {name: compartment.add_name(~"getClientRects"), let methods = @~[JSFunctionSpec {name: compartment.add_name(~"getClientRects"),
@ -102,7 +111,9 @@ pub fn init(compartment: @mut Compartment) {
flags: 0, flags: 0,
selfHostedName: null()}]; selfHostedName: null()}];
vec::as_imm_buf(*methods, |fns, _len| { vec::as_imm_buf(*methods, |fns, _len| {
unsafe {
JS_DefineFunctions(compartment.cx.ptr, obj.ptr, fns); JS_DefineFunctions(compartment.cx.ptr, obj.ptr, fns);
}
}); });
compartment.register_class(utils::instance_jsclass(~"GenericElementInstance", compartment.register_class(utils::instance_jsclass(~"GenericElementInstance",
@ -127,7 +138,9 @@ pub fn init(compartment: @mut Compartment) {
setter: JSStrictPropertyOpWrapper {op: null(), info: null()}}]; setter: JSStrictPropertyOpWrapper {op: null(), info: null()}}];
vec::push(&mut compartment.global_props, attrs); vec::push(&mut compartment.global_props, attrs);
vec::as_imm_buf(*attrs, |specs, _len| { vec::as_imm_buf(*attrs, |specs, _len| {
unsafe {
JS_DefineProperties(compartment.cx.ptr, obj.ptr, specs); JS_DefineProperties(compartment.cx.ptr, obj.ptr, specs);
}
}); });
} }
@ -299,8 +312,10 @@ pub fn create(cx: *JSContext, node: &mut AbstractNode<ScriptView>) -> jsobj {
assert!(cache.get_wrapper().is_null()); assert!(cache.get_wrapper().is_null());
cache.set_wrapper(obj.ptr); cache.set_wrapper(obj.ptr);
unsafe {
let raw_ptr = node.raw_object() as *libc::c_void; let raw_ptr = node.raw_object() as *libc::c_void;
JS_SetReservedSlot(obj.ptr, DOM_OBJECT_SLOT as u32, RUST_PRIVATE_TO_JSVAL(raw_ptr)); JS_SetReservedSlot(obj.ptr, DOM_OBJECT_SLOT as u32, RUST_PRIVATE_TO_JSVAL(raw_ptr));
}
return obj; return obj;
} }

View file

@ -2,15 +2,16 @@
* 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::cast;
use dom::bindings::codegen::EventBinding; use dom::bindings::codegen::EventBinding;
use dom::bindings::utils::{CacheableWrapper, WrapperCache, BindingObject, DerivedWrapper}; use dom::bindings::utils::{CacheableWrapper, WrapperCache, BindingObject, DerivedWrapper};
use dom::event::Event_; use dom::event::Event_;
use script_task::{task_from_context, global_script_context}; use script_task::{task_from_context, global_script_context};
use js::glue::bindgen::RUST_OBJECT_TO_JSVAL; use js::glue::RUST_OBJECT_TO_JSVAL;
use js::jsapi::{JSObject, JSContext, JSVal}; use js::jsapi::{JSObject, JSContext, JSVal};
pub impl Event_ { impl Event_ {
pub fn init_wrapper(@mut self) { pub fn init_wrapper(@mut self) {
let script_context = global_script_context(); let script_context = global_script_context();
let cx = script_context.js_compartment.cx.ptr; let cx = script_context.js_compartment.cx.ptr;

View file

@ -2,15 +2,16 @@
* 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::cast;
use dom::bindings::codegen::EventTargetBinding; use dom::bindings::codegen::EventTargetBinding;
use dom::bindings::utils::{CacheableWrapper, WrapperCache, BindingObject, DerivedWrapper}; use dom::bindings::utils::{CacheableWrapper, WrapperCache, BindingObject, DerivedWrapper};
use dom::eventtarget::EventTarget; use dom::eventtarget::EventTarget;
use script_task::{task_from_context, global_script_context}; use script_task::{task_from_context, global_script_context};
use js::glue::bindgen::RUST_OBJECT_TO_JSVAL; use js::glue::RUST_OBJECT_TO_JSVAL;
use js::jsapi::{JSObject, JSContext, JSVal}; use js::jsapi::{JSObject, JSContext, JSVal};
pub impl EventTarget { impl EventTarget {
pub fn init_wrapper(@mut self) { pub fn init_wrapper(@mut self) {
let script_context = global_script_context(); let script_context = global_script_context();
let cx = script_context.js_compartment.cx.ptr; let cx = script_context.js_compartment.cx.ptr;

View file

@ -9,8 +9,10 @@ use script_task::{task_from_context, global_script_context};
use js::jsapi::{JSObject, JSContext}; use js::jsapi::{JSObject, JSContext};
pub impl HTMLCollection { use std::cast;
fn init_wrapper(@mut self) {
impl HTMLCollection {
pub fn init_wrapper(@mut self) {
let script_context = global_script_context(); let script_context = global_script_context();
let cx = script_context.js_compartment.cx.ptr; let cx = script_context.js_compartment.cx.ptr;
let owner = script_context.root_frame.get_ref().window; let owner = script_context.root_frame.get_ref().window;

View file

@ -9,9 +9,12 @@ use dom::bindings::utils::{CacheableWrapper, WrapperCache, DerivedWrapper};
use dom::node::{AbstractNode, Node, ElementNodeTypeId, TextNodeTypeId, CommentNodeTypeId}; use dom::node::{AbstractNode, Node, ElementNodeTypeId, TextNodeTypeId, CommentNodeTypeId};
use dom::node::{DoctypeNodeTypeId, ScriptView}; use dom::node::{DoctypeNodeTypeId, ScriptView};
use core::libc::c_uint; use std::cast;
use core::ptr::null; use std::libc::c_uint;
use js::jsapi::bindgen::*; use std::ptr;
use std::ptr::null;
use std::vec;
use js::jsapi::*;
use js::jsapi::{JSContext, JSVal, JSObject, JSBool, JSPropertySpec}; use js::jsapi::{JSContext, JSVal, JSObject, JSBool, JSPropertySpec};
use js::jsapi::{JSPropertyOpWrapper, JSStrictPropertyOpWrapper}; use js::jsapi::{JSPropertyOpWrapper, JSStrictPropertyOpWrapper};
use js::jsval::{INT_TO_JSVAL}; use js::jsval::{INT_TO_JSVAL};
@ -53,7 +56,9 @@ pub fn init(compartment: @mut Compartment) {
setter: JSStrictPropertyOpWrapper {op: null(), info: null()}}]; setter: JSStrictPropertyOpWrapper {op: null(), info: null()}}];
vec::push(&mut compartment.global_props, attrs); vec::push(&mut compartment.global_props, attrs);
vec::as_imm_buf(*attrs, |specs, _len| { vec::as_imm_buf(*attrs, |specs, _len| {
unsafe {
JS_DefineProperties(compartment.cx.ptr, obj.ptr, specs); JS_DefineProperties(compartment.cx.ptr, obj.ptr, specs);
}
}); });
} }

View file

@ -3,11 +3,15 @@
* 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 js::jsapi::{JSContext, jsid, JSPropertyDescriptor, JSObject, JSString, jschar}; use js::jsapi::{JSContext, jsid, JSPropertyDescriptor, JSObject, JSString, jschar};
use js::jsapi::bindgen::{JS_GetPropertyDescriptorById, JS_NewUCString, JS_malloc, JS_free}; use js::jsapi::{JS_GetPropertyDescriptorById, JS_NewUCString, JS_malloc, JS_free};
use js::glue::bindgen::{RUST_JSVAL_IS_VOID, RUST_JSVAL_TO_OBJECT, GetProxyExtra}; use js::glue::{RUST_JSVAL_IS_VOID, RUST_JSVAL_TO_OBJECT, GetProxyExtra};
use js::glue::bindgen::{GetObjectProto}; use js::glue::{GetObjectProto};
use core::sys::size_of; use std::cast;
use std::libc;
use std::ptr;
use std::str;
use std::sys::size_of;
type c_bool = libc::c_int; type c_bool = libc::c_int;
@ -68,7 +72,7 @@ pub fn _obj_toString(cx: *JSContext, className: *libc::c_char) -> *JSString {
} }
let result = ~"[object " + name + ~"]"; let result = ~"[object " + name + ~"]";
for result.each_chari |i, c| { for result.iter().enumerate().advance |(i, c)| {
*chars.offset(i) = c as jschar; *chars.offset(i) = c as jschar;
} }
*chars.offset(nchars) = 0; *chars.offset(nchars) = 0;

View file

@ -10,10 +10,14 @@ use dom::node::{AbstractNode, Text, Comment, Doctype, TextNodeTypeId, CommentNod
use dom::node::{DoctypeNodeTypeId, ScriptView}; use dom::node::{DoctypeNodeTypeId, ScriptView};
use js::jsapi::{JSFreeOp, JSObject, JSContext}; use js::jsapi::{JSFreeOp, JSObject, JSContext};
use js::jsapi::bindgen::{JS_SetReservedSlot}; use js::jsapi::{JS_SetReservedSlot};
use js::glue::bindgen::{RUST_PRIVATE_TO_JSVAL}; use js::glue::{RUST_PRIVATE_TO_JSVAL};
use js::rust::{Compartment, jsobj}; use js::rust::{Compartment, jsobj};
use std::cast;
use std::libc;
use std::result;
extern fn finalize_text(_fop: *JSFreeOp, obj: *JSObject) { extern fn finalize_text(_fop: *JSFreeOp, obj: *JSObject) {
debug!("text finalize: %?!", obj as uint); debug!("text finalize: %?!", obj as uint);
unsafe { unsafe {
@ -83,8 +87,10 @@ pub fn create(cx: *JSContext, node: &mut AbstractNode<ScriptView>) -> jsobj {
assert!(cache.get_wrapper().is_null()); assert!(cache.get_wrapper().is_null());
cache.set_wrapper(obj.ptr); cache.set_wrapper(obj.ptr);
unsafe {
let raw_ptr = node.raw_object() as *libc::c_void; let raw_ptr = node.raw_object() as *libc::c_void;
JS_SetReservedSlot(obj.ptr, DOM_OBJECT_SLOT as u32, RUST_PRIVATE_TO_JSVAL(raw_ptr)); JS_SetReservedSlot(obj.ptr, DOM_OBJECT_SLOT as u32, RUST_PRIVATE_TO_JSVAL(raw_ptr));
}
return obj; return obj;
} }

View file

@ -6,20 +6,26 @@ use dom::bindings::node;
use dom::node::{AbstractNode, ScriptView}; use dom::node::{AbstractNode, ScriptView};
use script_task::task_from_context; use script_task::task_from_context;
use core::cast; use std::cast;
use core::hashmap::HashMap; use std::hashmap::HashMap;
use core::ptr::{null, to_unsafe_ptr}; use std::libc;
use js::glue::bindgen::*; use std::ptr;
use js::glue::bindgen::{DefineFunctionWithReserved, GetObjectJSClass, RUST_OBJECT_TO_JSVAL}; use std::ptr::{null, to_unsafe_ptr};
use std::result;
use std::str;
use std::sys;
use std::uint;
use js::glue::*;
use js::glue::{DefineFunctionWithReserved, GetObjectJSClass, RUST_OBJECT_TO_JSVAL};
use js::glue::{PROPERTY_STUB, STRICT_PROPERTY_STUB, ENUMERATE_STUB, CONVERT_STUB, RESOLVE_STUB}; use js::glue::{PROPERTY_STUB, STRICT_PROPERTY_STUB, ENUMERATE_STUB, CONVERT_STUB, RESOLVE_STUB};
use js::jsapi::bindgen::{JS_AlreadyHasOwnProperty, JS_NewObject, JS_NewFunction}; use js::jsapi::{JS_AlreadyHasOwnProperty, JS_NewObject, JS_NewFunction};
use js::jsapi::bindgen::{JS_DefineProperties, JS_WrapValue, JS_ForwardGetPropertyTo}; use js::jsapi::{JS_DefineProperties, JS_WrapValue, JS_ForwardGetPropertyTo};
use js::jsapi::bindgen::{JS_EncodeString, JS_free, JS_GetStringCharsAndLength}; use js::jsapi::{JS_EncodeString, JS_free, JS_GetStringCharsAndLength};
use js::jsapi::bindgen::{JS_GetClass, JS_GetPrototype, JS_LinkConstructorAndPrototype}; use js::jsapi::{JS_GetClass, JS_GetPrototype, JS_LinkConstructorAndPrototype};
use js::jsapi::bindgen::{JS_GetFunctionPrototype, JS_InternString, JS_GetFunctionObject}; use js::jsapi::{JS_GetFunctionPrototype, JS_InternString, JS_GetFunctionObject};
use js::jsapi::bindgen::{JS_HasPropertyById, JS_GetPrototype, JS_GetGlobalForObject}; use js::jsapi::{JS_HasPropertyById, JS_GetPrototype, JS_GetGlobalForObject};
use js::jsapi::bindgen::{JS_NewStringCopyN, JS_DefineFunctions, JS_DefineProperty}; use js::jsapi::{JS_NewStringCopyN, JS_DefineFunctions, JS_DefineProperty};
use js::jsapi::bindgen::{JS_ValueToString, JS_GetReservedSlot, JS_SetReservedSlot}; use js::jsapi::{JS_ValueToString, JS_GetReservedSlot, JS_SetReservedSlot};
use js::jsapi::{JSContext, JSVal, JSObject, JSBool, jsid, JSClass, JSNative}; use js::jsapi::{JSContext, JSVal, JSObject, JSBool, jsid, JSClass, JSNative};
use js::jsapi::{JSFunctionSpec, JSPropertySpec, JSVal, JSPropertyDescriptor}; use js::jsapi::{JSFunctionSpec, JSPropertySpec, JSVal, JSPropertyDescriptor};
use js::jsfriendapi::bindgen::JS_NewObjectWithUniqueType; use js::jsfriendapi::bindgen::JS_NewObjectWithUniqueType;
@ -88,8 +94,8 @@ pub enum DOMString {
null_string null_string
} }
pub impl DOMString { impl DOMString {
fn to_str(&self) -> ~str { pub fn to_str(&self) -> ~str {
match *self { match *self {
str(ref s) => s.clone(), str(ref s) => s.clone(),
null_string => ~"" null_string => ~""
@ -129,6 +135,7 @@ pub unsafe fn squirrel_away<T>(x: @mut T) -> *rust_box<T> {
//XXX very incomplete //XXX very incomplete
pub fn jsval_to_str(cx: *JSContext, v: JSVal) -> Result<~str, ()> { pub fn jsval_to_str(cx: *JSContext, v: JSVal) -> Result<~str, ()> {
unsafe {
let jsstr; let jsstr;
if RUST_JSVAL_IS_STRING(v) == 1 { if RUST_JSVAL_IS_STRING(v) == 1 {
jsstr = RUST_JSVAL_TO_STRING(v) jsstr = RUST_JSVAL_TO_STRING(v)
@ -139,7 +146,6 @@ pub fn jsval_to_str(cx: *JSContext, v: JSVal) -> Result<~str, ()> {
} }
} }
unsafe {
let strbuf = JS_EncodeString(cx, jsstr); let strbuf = JS_EncodeString(cx, jsstr);
let buf = str::raw::from_buf(strbuf as *u8); let buf = str::raw::from_buf(strbuf as *u8);
JS_free(cx, strbuf as *libc::c_void); JS_free(cx, strbuf as *libc::c_void);
@ -172,6 +178,7 @@ pub fn get_compartment(cx: *JSContext) -> @mut Compartment {
extern fn has_instance(_cx: *JSContext, obj: **JSObject, v: *JSVal, bp: *mut JSBool) -> JSBool { extern fn has_instance(_cx: *JSContext, obj: **JSObject, v: *JSVal, bp: *mut JSBool) -> JSBool {
//XXXjdm this is totally broken for non-object values //XXXjdm this is totally broken for non-object values
unsafe {
let mut o = RUST_JSVAL_TO_OBJECT(unsafe {*v}); let mut o = RUST_JSVAL_TO_OBJECT(unsafe {*v});
let obj = unsafe {*obj}; let obj = unsafe {*obj};
unsafe { *bp = 0; } unsafe { *bp = 0; }
@ -183,10 +190,12 @@ extern fn has_instance(_cx: *JSContext, obj: **JSObject, v: *JSVal, bp: *mut JSB
o = JS_GetPrototype(o); o = JS_GetPrototype(o);
} }
return 1; return 1;
}
} }
pub fn prototype_jsclass(name: ~str) -> @fn(compartment: @mut Compartment) -> JSClass { pub fn prototype_jsclass(name: ~str) -> @fn(compartment: @mut Compartment) -> JSClass {
let f: @fn(@mut Compartment) -> JSClass = |compartment: @mut Compartment| { let f: @fn(@mut Compartment) -> JSClass = |compartment: @mut Compartment| {
unsafe {
JSClass { JSClass {
name: compartment.add_name(copy name), name: compartment.add_name(copy name),
flags: 0, flags: 0,
@ -212,6 +221,7 @@ pub fn prototype_jsclass(name: ~str) -> @fn(compartment: @mut Compartment) -> JS
null(), null(), null(), null(), null(), // 35 null(), null(), null(), null(), null(), // 35
null(), null(), null(), null(), null()) // 40 null(), null(), null(), null(), null()) // 40
} }
}
}; };
return f; return f;
} }
@ -219,6 +229,7 @@ pub fn prototype_jsclass(name: ~str) -> @fn(compartment: @mut Compartment) -> JS
pub fn instance_jsclass(name: ~str, finalize: *u8, trace: *u8) pub fn instance_jsclass(name: ~str, finalize: *u8, trace: *u8)
-> @fn(compartment: @mut Compartment) -> JSClass { -> @fn(compartment: @mut Compartment) -> JSClass {
let f: @fn(@mut Compartment) -> JSClass = |compartment: @mut Compartment| { let f: @fn(@mut Compartment) -> JSClass = |compartment: @mut Compartment| {
unsafe {
JSClass { JSClass {
name: compartment.add_name(copy name), name: compartment.add_name(copy name),
flags: JSCLASS_HAS_RESERVED_SLOTS(1) | js::JSCLASS_IS_DOMJSCLASS, flags: JSCLASS_HAS_RESERVED_SLOTS(1) | js::JSCLASS_IS_DOMJSCLASS,
@ -244,6 +255,7 @@ pub fn instance_jsclass(name: ~str, finalize: *u8, trace: *u8)
null(), null(), null(), null(), null(), // 35 null(), null(), null(), null(), null(), // 35
null(), null(), null(), null(), null()) // 40 null(), null(), null(), null(), null()) // 40
} }
}
}; };
return f; return f;
} }
@ -262,12 +274,14 @@ pub fn define_empty_prototype(name: ~str, proto: Option<~str>, compartment: @mut
None => compartment.new_object(copy name, null(), compartment.global_obj.ptr) None => compartment.new_object(copy name, null(), compartment.global_obj.ptr)
}); });
unsafe {
compartment.define_property(copy name, RUST_OBJECT_TO_JSVAL(obj.ptr), compartment.define_property(copy name, RUST_OBJECT_TO_JSVAL(obj.ptr),
GetJSClassHookStubPointer(PROPERTY_STUB) as *u8, GetJSClassHookStubPointer(PROPERTY_STUB) as *u8,
GetJSClassHookStubPointer(STRICT_PROPERTY_STUB) as *u8, GetJSClassHookStubPointer(STRICT_PROPERTY_STUB) as *u8,
JSPROP_ENUMERATE); JSPROP_ENUMERATE);
compartment.stash_global_proto(name, obj); compartment.stash_global_proto(name, obj);
return obj; return obj;
}
} }
// We use slot 0 for holding the raw object. This is safe for both // We use slot 0 for holding the raw object. This is safe for both
@ -390,9 +404,11 @@ pub fn CreateInterfaceObjects2(cx: *JSContext, global: *JSObject, receiver: *JSO
return ptr::null(); return ptr::null();
} }
unsafe {
JS_SetReservedSlot(proto, DOM_PROTO_INSTANCE_CLASS_SLOT, JS_SetReservedSlot(proto, DOM_PROTO_INSTANCE_CLASS_SLOT,
RUST_PRIVATE_TO_JSVAL(domClass as *libc::c_void)); RUST_PRIVATE_TO_JSVAL(domClass as *libc::c_void));
} }
}
let mut interface = ptr::null(); let mut interface = ptr::null();
if constructorClass.is_not_null() || constructor.is_not_null() { if constructorClass.is_not_null() || constructor.is_not_null() {
@ -419,6 +435,7 @@ fn CreateInterfaceObject(cx: *JSContext, global: *JSObject, receiver: *JSObject,
staticMethods: *JSFunctionSpec, staticMethods: *JSFunctionSpec,
constants: *ConstantSpec, constants: *ConstantSpec,
name: *libc::c_char) -> *JSObject { name: *libc::c_char) -> *JSObject {
unsafe {
let constructor = if constructorClass.is_not_null() { let constructor = if constructorClass.is_not_null() {
let functionProto = JS_GetFunctionPrototype(cx, global); let functionProto = JS_GetFunctionPrototype(cx, global);
if functionProto.is_null() { if functionProto.is_null() {
@ -488,6 +505,7 @@ fn CreateInterfaceObject(cx: *JSContext, global: *JSObject, receiver: *JSObject,
} }
return constructor; return constructor;
}
} }
fn DefineConstants(cx: *JSContext, obj: *JSObject, constants: *ConstantSpec) -> bool { fn DefineConstants(cx: *JSContext, obj: *JSObject, constants: *ConstantSpec) -> bool {
@ -520,11 +538,15 @@ fn DefineConstants(cx: *JSContext, obj: *JSObject, constants: *ConstantSpec) ->
} }
fn DefineMethods(cx: *JSContext, obj: *JSObject, methods: *JSFunctionSpec) -> bool { fn DefineMethods(cx: *JSContext, obj: *JSObject, methods: *JSFunctionSpec) -> bool {
unsafe {
JS_DefineFunctions(cx, obj, methods) != 0 JS_DefineFunctions(cx, obj, methods) != 0
}
} }
fn DefineProperties(cx: *JSContext, obj: *JSObject, properties: *JSPropertySpec) -> bool { fn DefineProperties(cx: *JSContext, obj: *JSObject, properties: *JSPropertySpec) -> bool {
unsafe {
JS_DefineProperties(cx, obj, properties) != 0 JS_DefineProperties(cx, obj, properties) != 0
}
} }
fn CreateInterfacePrototypeObject(cx: *JSContext, global: *JSObject, fn CreateInterfacePrototypeObject(cx: *JSContext, global: *JSObject,
@ -532,6 +554,7 @@ fn CreateInterfacePrototypeObject(cx: *JSContext, global: *JSObject,
methods: *JSFunctionSpec, methods: *JSFunctionSpec,
properties: *JSPropertySpec, properties: *JSPropertySpec,
constants: *ConstantSpec) -> *JSObject { constants: *ConstantSpec) -> *JSObject {
unsafe {
let ourProto = JS_NewObjectWithUniqueType(cx, protoClass, parentProto, global); let ourProto = JS_NewObjectWithUniqueType(cx, protoClass, parentProto, global);
if ourProto.is_null() { if ourProto.is_null() {
return ptr::null(); return ptr::null();
@ -550,6 +573,7 @@ fn CreateInterfacePrototypeObject(cx: *JSContext, global: *JSObject,
} }
return ourProto; return ourProto;
}
} }
pub extern fn ThrowingConstructor(_cx: *JSContext, _argc: uint, _vp: *JSVal) -> JSBool { pub extern fn ThrowingConstructor(_cx: *JSContext, _argc: uint, _vp: *JSVal) -> JSBool {
@ -578,20 +602,20 @@ pub struct WrapperCache {
wrapper: *JSObject wrapper: *JSObject
} }
pub impl WrapperCache { impl WrapperCache {
fn get_wrapper(&self) -> *JSObject { pub fn get_wrapper(&self) -> *JSObject {
unsafe { cast::transmute(self.wrapper) } unsafe { cast::transmute(self.wrapper) }
} }
fn set_wrapper(&mut self, wrapper: *JSObject) { pub fn set_wrapper(&mut self, wrapper: *JSObject) {
self.wrapper = wrapper; self.wrapper = wrapper;
} }
fn get_rootable(&self) -> **JSObject { pub fn get_rootable(&self) -> **JSObject {
return to_unsafe_ptr(&self.wrapper); return to_unsafe_ptr(&self.wrapper);
} }
fn new() -> WrapperCache { pub fn new() -> WrapperCache {
WrapperCache { WrapperCache {
wrapper: ptr::null() wrapper: ptr::null()
} }
@ -660,10 +684,12 @@ pub fn GetPropertyOnPrototype(cx: *JSContext, proxy: *JSObject, id: jsid, found:
} }
pub fn GetArrayIndexFromId(_cx: *JSContext, id: jsid) -> Option<u32> { pub fn GetArrayIndexFromId(_cx: *JSContext, id: jsid) -> Option<u32> {
unsafe {
if RUST_JSID_IS_INT(id) != 0 { if RUST_JSID_IS_INT(id) != 0 {
return Some(RUST_JSID_TO_INT(id) as u32); return Some(RUST_JSID_TO_INT(id) as u32);
} }
return None; return None;
}
// if id is length atom, -1, otherwise // if id is length atom, -1, otherwise
/*return if JSID_IS_ATOM(id) { /*return if JSID_IS_ATOM(id) {
let atom = JSID_TO_ATOM(id); let atom = JSID_TO_ATOM(id);
@ -730,12 +756,14 @@ pub fn XrayResolveProperty(cx: *JSContext,
} }
fn InternJSString(cx: *JSContext, chars: *libc::c_char) -> Option<jsid> { fn InternJSString(cx: *JSContext, chars: *libc::c_char) -> Option<jsid> {
unsafe {
let s = JS_InternString(cx, chars); let s = JS_InternString(cx, chars);
if s.is_not_null() { if s.is_not_null() {
Some(RUST_INTERNED_STRING_TO_JSID(cx, s)) Some(RUST_INTERNED_STRING_TO_JSID(cx, s))
} else { } else {
None None
} }
}
} }
pub fn InitIds(cx: *JSContext, specs: &[JSPropertySpec], ids: &mut [jsid]) -> bool { pub fn InitIds(cx: *JSContext, specs: &[JSPropertySpec], ids: &mut [jsid]) -> bool {

View file

@ -9,16 +9,19 @@ use dom::bindings::utils::{WrapperCache};
use dom::window::Window; use dom::window::Window;
use super::utils; use super::utils;
use core::libc::c_uint; use std::cast;
use core::ptr::null; use std::libc;
use core::ptr; use std::libc::c_uint;
use std::ptr::null;
use std::ptr;
use std::result;
use js::crust::{JS_PropertyStub, JS_StrictPropertyStub}; use js::crust::{JS_PropertyStub, JS_StrictPropertyStub};
use js::global::jsval_to_rust_str; use js::global::jsval_to_rust_str;
use js::glue::bindgen::*; use js::glue::*;
use js::glue::bindgen::RUST_JSVAL_TO_INT; use js::glue::RUST_JSVAL_TO_INT;
use js::jsapi::bindgen::{JS_DefineFunctions, JS_GC, JS_GetRuntime}; use js::jsapi::{JS_DefineFunctions, JS_GC, JS_GetRuntime};
use js::jsapi::bindgen::{JS_GetReservedSlot, JS_SetReservedSlot}; use js::jsapi::{JS_GetReservedSlot, JS_SetReservedSlot};
use js::jsapi::bindgen::{JS_ValueToString}; use js::jsapi::{JS_ValueToString};
use js::jsapi::{JSContext, JSVal, JSObject, JSBool, JSFreeOp, JSFunctionSpec}; use js::jsapi::{JSContext, JSVal, JSObject, JSBool, JSFreeOp, JSFunctionSpec};
use js::jsapi::{JSNativeWrapper}; use js::jsapi::{JSNativeWrapper};
use js::rust::Compartment; use js::rust::Compartment;
@ -67,9 +70,11 @@ extern fn close(cx: *JSContext, _argc: c_uint, vp: *JSVal) -> JSBool {
} }
extern fn gc(cx: *JSContext, _argc: c_uint, _vp: *JSVal) -> JSBool { extern fn gc(cx: *JSContext, _argc: c_uint, _vp: *JSVal) -> JSBool {
unsafe {
let runtime = JS_GetRuntime(cx); let runtime = JS_GetRuntime(cx);
JS_GC(runtime); JS_GC(runtime);
return 1; return 1;
}
} }
unsafe fn unwrap(obj: *JSObject) -> *rust_box<Window> { unsafe fn unwrap(obj: *JSObject) -> *rust_box<Window> {
@ -128,7 +133,9 @@ pub fn init(compartment: @mut Compartment) {
} }
]; ];
unsafe {
JS_DefineFunctions(compartment.cx.ptr, proto.ptr, &methods[0]); JS_DefineFunctions(compartment.cx.ptr, proto.ptr, &methods[0]);
}
} }
pub fn create(compartment: @mut Compartment, win: @mut Window) { pub fn create(compartment: @mut Compartment, win: @mut Window) {
@ -141,13 +148,13 @@ pub fn create(compartment: @mut Compartment, win: @mut Window) {
unsafe { unsafe {
let raw_ptr: *libc::c_void = cast::transmute(squirrel_away(win)); let raw_ptr: *libc::c_void = cast::transmute(squirrel_away(win));
JS_SetReservedSlot(obj.ptr, 0, RUST_PRIVATE_TO_JSVAL(raw_ptr)); JS_SetReservedSlot(obj.ptr, 0, RUST_PRIVATE_TO_JSVAL(raw_ptr));
}
//TODO: All properties/methods on Window need to be available on the global //TODO: All properties/methods on Window need to be available on the global
// object as well. We probably want a special JSClass with a resolve hook. // object as well. We probably want a special JSClass with a resolve hook.
compartment.define_property(~"window", RUST_OBJECT_TO_JSVAL(obj.ptr), compartment.define_property(~"window", RUST_OBJECT_TO_JSVAL(obj.ptr),
JS_PropertyStub, JS_StrictPropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
JSPROP_ENUMERATE); JSPROP_ENUMERATE);
}
} }
impl CacheableWrapper for Window { impl CacheableWrapper for Window {

View file

@ -7,7 +7,7 @@
use dom::bindings::utils::{DOMString, null_string, str}; use dom::bindings::utils::{DOMString, null_string, str};
use dom::node::{Node, NodeTypeId, ScriptView}; use dom::node::{Node, NodeTypeId, ScriptView};
use core::str; use std::str;
pub struct CharacterData { pub struct CharacterData {
parent: Node<ScriptView>, parent: Node<ScriptView>,
@ -46,7 +46,7 @@ impl CharacterData {
pub fn AppendData(&mut self, arg: DOMString) { pub fn AppendData(&mut self, arg: DOMString) {
let s = self.data.to_str(); let s = self.data.to_str();
self.data = str(str::append(s, arg.to_str())); self.data = str(s.append(arg.to_str()));
} }
pub fn InsertData(&mut self, _offset: u32, _arg: DOMString) { pub fn InsertData(&mut self, _offset: u32, _arg: DOMString) {

View file

@ -4,6 +4,8 @@
use dom::bindings::utils::WrapperCache; use dom::bindings::utils::WrapperCache;
use std::f32;
pub struct ClientRect { pub struct ClientRect {
wrapper: WrapperCache, wrapper: WrapperCache,
top: f32, top: f32,

View file

@ -10,8 +10,8 @@ pub struct ClientRectList {
rects: ~[@mut ClientRect] rects: ~[@mut ClientRect]
} }
pub impl ClientRectList { impl ClientRectList {
fn new(rects: ~[@mut ClientRect]) -> @mut ClientRectList { pub fn new(rects: ~[@mut ClientRect]) -> @mut ClientRectList {
let list = @mut ClientRectList { let list = @mut ClientRectList {
wrapper: WrapperCache::new(), wrapper: WrapperCache::new(),
rects: rects rects: rects
@ -20,11 +20,11 @@ pub impl ClientRectList {
list list
} }
fn Length(&self) -> u32 { pub fn Length(&self) -> u32 {
self.rects.len() as u32 self.rects.len() as u32
} }
fn Item(&self, index: u32) -> Option<@mut ClientRect> { pub fn Item(&self, index: u32) -> Option<@mut ClientRect> {
if index < self.rects.len() as u32 { if index < self.rects.len() as u32 {
Some(self.rects[index]) Some(self.rects[index])
} else { } else {
@ -32,7 +32,7 @@ pub impl ClientRectList {
} }
} }
fn IndexedGetter(&self, index: u32, found: &mut bool) -> Option<@mut ClientRect> { pub fn IndexedGetter(&self, index: u32, found: &mut bool) -> Option<@mut ClientRect> {
*found = index < self.rects.len() as u32; *found = index < self.rects.len() as u32;
self.Item(index) self.Item(index)
} }

View file

@ -9,7 +9,7 @@ use dom::node::{AbstractNode, ScriptView};
use dom::window::Window; use dom::window::Window;
use script_task::global_script_context; use script_task::global_script_context;
use js::jsapi::bindgen::{JS_AddObjectRoot, JS_RemoveObjectRoot}; use js::jsapi::{JS_AddObjectRoot, JS_RemoveObjectRoot};
use servo_util::tree::{TreeNodeRef, TreeUtils}; use servo_util::tree::{TreeNodeRef, TreeUtils};
pub struct Document { pub struct Document {
@ -19,6 +19,7 @@ pub struct Document {
} }
pub fn Document(root: AbstractNode<ScriptView>, window: Option<@mut Window>) -> @mut Document { pub fn Document(root: AbstractNode<ScriptView>, window: Option<@mut Window>) -> @mut Document {
unsafe {
let doc = @mut Document { let doc = @mut Document {
root: root, root: root,
wrapper: WrapperCache::new(), wrapper: WrapperCache::new(),
@ -32,10 +33,11 @@ pub fn Document(root: AbstractNode<ScriptView>, window: Option<@mut Window>) ->
} }
document::create(compartment, doc); document::create(compartment, doc);
doc doc
}
} }
pub impl Document { impl Document {
fn getElementsByTagName(&self, tag: DOMString) -> Option<@mut HTMLCollection> { pub fn getElementsByTagName(&self, tag: DOMString) -> Option<@mut HTMLCollection> {
let mut elements = ~[]; let mut elements = ~[];
let tag = tag.to_str(); let tag = tag.to_str();
let _ = for self.root.traverse_preorder |child| { let _ = for self.root.traverse_preorder |child| {
@ -50,13 +52,14 @@ pub impl Document {
Some(HTMLCollection::new(elements)) Some(HTMLCollection::new(elements))
} }
fn content_changed(&self) { pub fn content_changed(&self) {
for self.window.each |window| { for self.window.iter().advance |window| {
window.content_changed() window.content_changed()
} }
} }
fn teardown(&self) { pub fn teardown(&self) {
unsafe {
let compartment = global_script_context().js_compartment; let compartment = global_script_context().js_compartment;
do self.root.with_base |node| { do self.root.with_base |node| {
assert!(node.wrapper.get_wrapper().is_not_null()); assert!(node.wrapper.get_wrapper().is_not_null());
@ -64,5 +67,6 @@ pub impl Document {
JS_RemoveObjectRoot(compartment.cx.ptr, rootable); JS_RemoveObjectRoot(compartment.cx.ptr, rootable);
} }
} }
}
} }

View file

@ -11,9 +11,10 @@ use dom::node::{ElementNodeTypeId, Node, ScriptView};
use layout_interface::{ContentBoxQuery, ContentBoxResponse, ContentBoxesQuery}; use layout_interface::{ContentBoxQuery, ContentBoxResponse, ContentBoxesQuery};
use layout_interface::{ContentBoxesResponse}; use layout_interface::{ContentBoxesResponse};
use core::cell::Cell; use std::cell::Cell;
use core::str::eq_slice; use std::uint;
use std::net::url::Url; use std::str::eq_slice;
use extra::net::url::Url;
pub struct Element { pub struct Element {
parent: Node<ScriptView>, parent: Node<ScriptView>,
@ -114,7 +115,7 @@ pub struct HTMLImageElement {
// Element methods // Element methods
// //
pub impl<'self> Element { impl<'self> Element {
pub fn new(type_id: ElementTypeId, tag_name: ~str) -> Element { pub fn new(type_id: ElementTypeId, tag_name: ~str) -> Element {
Element { Element {
parent: Node::new(ElementNodeTypeId(type_id)), parent: Node::new(ElementNodeTypeId(type_id)),
@ -123,7 +124,7 @@ pub impl<'self> Element {
} }
} }
fn get_attr(&'self self, name: &str) -> Option<&'self str> { pub fn get_attr(&'self self, name: &str) -> Option<&'self str> {
// FIXME: Need an each() that links lifetimes in Rust. // FIXME: Need an each() that links lifetimes in Rust.
for uint::range(0, self.attrs.len()) |i| { for uint::range(0, self.attrs.len()) |i| {
if eq_slice(self.attrs[i].name, name) { if eq_slice(self.attrs[i].name, name) {
@ -134,11 +135,11 @@ pub impl<'self> Element {
return None; return None;
} }
fn set_attr(&mut self, name: &DOMString, value: &DOMString) { pub fn set_attr(&mut self, name: &DOMString, value: &DOMString) {
let name = name.to_str(); let name = name.to_str();
let value = value.to_str(); let value = value.to_str();
// FIXME: We need a better each_mut in Rust; this is ugly. // FIXME: We need a better each_mut in Rust; this is ugly.
let value_cell = Cell(value); let value_cell = Cell::new(value);
let mut found = false; let mut found = false;
for uint::range(0, self.attrs.len()) |i| { for uint::range(0, self.attrs.len()) |i| {
if eq_slice(self.attrs[i].name, name) { if eq_slice(self.attrs[i].name, name) {
@ -157,7 +158,7 @@ pub impl<'self> Element {
} }
} }
fn getClientRects(&self) -> Option<@mut ClientRectList> { pub fn getClientRects(&self) -> Option<@mut ClientRectList> {
let rects = match self.parent.owner_doc { let rects = match self.parent.owner_doc {
Some(doc) => { Some(doc) => {
match doc.window { match doc.window {
@ -199,7 +200,7 @@ pub impl<'self> Element {
Some(ClientRectList::new(rects)) Some(ClientRectList::new(rects))
} }
fn getBoundingClientRect(&self) -> Option<@mut ClientRect> { pub fn getBoundingClientRect(&self) -> Option<@mut ClientRect> {
match self.parent.owner_doc { match self.parent.owner_doc {
Some(doc) => { Some(doc) => {
match doc.window { match doc.window {

View file

@ -9,6 +9,8 @@ use dom::bindings::utils::{DOMString, ErrorResult, WrapperCache};
use geom::point::Point2D; use geom::point::Point2D;
use std::comm;
pub enum Event { pub enum Event {
ResizeEvent(uint, uint), ResizeEvent(uint, uint),
ReflowEvent, ReflowEvent,

View file

@ -8,8 +8,8 @@ pub struct EventTarget {
wrapper: WrapperCache wrapper: WrapperCache
} }
pub impl EventTarget { impl EventTarget {
fn new() -> ~EventTarget { pub fn new() -> ~EventTarget {
~EventTarget { ~EventTarget {
wrapper: WrapperCache::new() wrapper: WrapperCache::new()
} }

View file

@ -8,13 +8,15 @@ use dom::node::{AbstractNode, ScriptView};
use js::jsapi::{JSObject, JSContext}; use js::jsapi::{JSObject, JSContext};
use std::ptr;
pub struct HTMLCollection { pub struct HTMLCollection {
elements: ~[AbstractNode<ScriptView>], elements: ~[AbstractNode<ScriptView>],
wrapper: WrapperCache wrapper: WrapperCache
} }
pub impl HTMLCollection { impl HTMLCollection {
fn new(elements: ~[AbstractNode<ScriptView>]) -> @mut HTMLCollection { pub fn new(elements: ~[AbstractNode<ScriptView>]) -> @mut HTMLCollection {
let collection = @mut HTMLCollection { let collection = @mut HTMLCollection {
elements: elements, elements: elements,
wrapper: WrapperCache::new() wrapper: WrapperCache::new()
@ -23,11 +25,11 @@ pub impl HTMLCollection {
collection collection
} }
fn Length(&self) -> u32 { pub fn Length(&self) -> u32 {
self.elements.len() as u32 self.elements.len() as u32
} }
fn Item(&self, index: u32) -> Option<AbstractNode<ScriptView>> { pub fn Item(&self, index: u32) -> Option<AbstractNode<ScriptView>> {
if index < self.Length() { if index < self.Length() {
Some(self.elements[index]) Some(self.elements[index])
} else { } else {
@ -35,12 +37,12 @@ pub impl HTMLCollection {
} }
} }
fn NamedItem(&self, _cx: *JSContext, _name: DOMString, rv: &mut ErrorResult) -> *JSObject { pub fn NamedItem(&self, _cx: *JSContext, _name: DOMString, rv: &mut ErrorResult) -> *JSObject {
*rv = Ok(()); *rv = Ok(());
ptr::null() ptr::null()
} }
fn IndexedGetter(&self, index: u32, found: &mut bool) -> Option<AbstractNode<ScriptView>> { pub fn IndexedGetter(&self, index: u32, found: &mut bool) -> Option<AbstractNode<ScriptView>> {
*found = true; *found = true;
self.Item(index) self.Item(index)
} }

View file

@ -14,8 +14,10 @@ use dom::element::{Element, ElementTypeId, HTMLImageElement, HTMLImageElementTyp
use dom::element::{HTMLStyleElementTypeId}; use dom::element::{HTMLStyleElementTypeId};
use script_task::global_script_context; use script_task::global_script_context;
use core::cast::transmute; use std::cast;
use core::libc::c_void; use std::cast::transmute;
use std::libc::c_void;
use std::uint;
use js::rust::Compartment; use js::rust::Compartment;
use netsurfcss::util::VoidPtrLike; use netsurfcss::util::VoidPtrLike;
use servo_util::tree::{TreeNode, TreeNodeRef, TreeUtils}; use servo_util::tree::{TreeNode, TreeNodeRef, TreeUtils};

View file

@ -8,10 +8,15 @@ use dom::bindings::window;
use layout_interface::ReflowForScriptQuery; use layout_interface::ReflowForScriptQuery;
use script_task::{ExitMsg, FireTimerMsg, ScriptChan, ScriptContext}; use script_task::{ExitMsg, FireTimerMsg, ScriptChan, ScriptContext};
use core::comm::Chan; use std::comm;
use std::comm::Chan;
use std::libc;
use std::int;
use std::io;
use std::ptr;
use js::jsapi::JSVal; use js::jsapi::JSVal;
use std::timer; use extra::timer;
use std::uv_global_loop; use extra::uv_global_loop;
pub enum TimerControlMsg { pub enum TimerControlMsg {
TimerMessage_Fire(~TimerData), TimerMessage_Fire(~TimerData),
@ -61,17 +66,17 @@ pub fn TimerData(argc: libc::c_uint, argv: *JSVal) -> TimerData {
// FIXME: delayed_send shouldn't require Copy // FIXME: delayed_send shouldn't require Copy
#[allow(non_implicitly_copyable_typarams)] #[allow(non_implicitly_copyable_typarams)]
pub impl Window { impl Window {
fn alert(&self, s: &str) { pub fn alert(&self, s: &str) {
// Right now, just print to the console // Right now, just print to the console
io::println(fmt!("ALERT: %s", s)); io::println(fmt!("ALERT: %s", s));
} }
fn close(&self) { pub fn close(&self) {
self.timer_chan.send(TimerMessage_TriggerExit); self.timer_chan.send(TimerMessage_TriggerExit);
} }
fn setTimeout(&self, timeout: int, argc: libc::c_uint, argv: *JSVal) { pub fn setTimeout(&self, timeout: int, argc: libc::c_uint, argv: *JSVal) {
let timeout = int::max(0, timeout) as uint; let timeout = int::max(0, timeout) as uint;
// Post a delayed message to the per-window timer task; it will dispatch it // Post a delayed message to the per-window timer task; it will dispatch it
@ -82,7 +87,7 @@ pub impl Window {
TimerMessage_Fire(~TimerData(argc, argv))); TimerMessage_Fire(~TimerData(argc, argv)));
} }
fn content_changed(&self) { pub fn content_changed(&self) {
unsafe { unsafe {
(*self.script_context).reflow_all(ReflowForScriptQuery) (*self.script_context).reflow_all(ReflowForScriptQuery)
} }

View file

@ -4,13 +4,15 @@
/// Some little helpers for hooking up the HTML parser with the CSS parser. /// Some little helpers for hooking up the HTML parser with the CSS parser.
use core::cell::Cell; use std::cell::Cell;
use core::comm::Port; use std::comm;
use core::str; use std::comm::Port;
use std::task;
use std::str;
use newcss::stylesheet::Stylesheet; use newcss::stylesheet::Stylesheet;
use newcss::util::DataStream; use newcss::util::DataStream;
use servo_net::resource_task::{ResourceTask, ProgressMsg, Load, Payload, Done}; use servo_net::resource_task::{ResourceTask, ProgressMsg, Load, Payload, Done};
use std::net::url::Url; use extra::net::url::Url;
/// Where a style sheet comes from. /// Where a style sheet comes from.
pub enum StylesheetProvenance { pub enum StylesheetProvenance {
@ -23,12 +25,12 @@ pub fn spawn_css_parser(provenance: StylesheetProvenance,
-> Port<Stylesheet> { -> Port<Stylesheet> {
let (result_port, result_chan) = comm::stream(); let (result_port, result_chan) = comm::stream();
let provenance_cell = Cell(provenance); let provenance_cell = Cell::new(provenance);
do task::spawn { do task::spawn {
let url = do provenance_cell.with_ref |p| { let url = do provenance_cell.with_ref |p| {
match *p { match *p {
UrlProvenance(copy the_url) => the_url, UrlProvenance(ref the_url) => copy *the_url,
InlineProvenance(copy the_url, _) => the_url InlineProvenance(ref the_url, _) => copy *the_url
} }
}; };
@ -64,13 +66,14 @@ fn resource_port_to_data_stream(input_port: Port<ProgressMsg>) -> DataStream {
} }
fn data_to_data_stream(data: ~str) -> DataStream { fn data_to_data_stream(data: ~str) -> DataStream {
let data_cell = Cell(data); let data_cell = Cell::new(data);
return || { return || {
if data_cell.is_empty() { if data_cell.is_empty() {
None None
} else { } else {
// FIXME: Blech, a copy. // FIXME: Blech, a copy.
Some(str::to_bytes(data_cell.take())) let data = data_cell.take();
Some(data.as_bytes().to_owned())
} }
} }
} }

View file

@ -8,17 +8,21 @@ use dom::node::{Text};
use html::cssparse::{InlineProvenance, StylesheetProvenance, UrlProvenance, spawn_css_parser}; use html::cssparse::{InlineProvenance, StylesheetProvenance, UrlProvenance, spawn_css_parser};
use newcss::stylesheet::Stylesheet; use newcss::stylesheet::Stylesheet;
use core::cell::Cell; use std::cast;
use core::comm::{Chan, Port, SharedChan}; use std::cell::Cell;
use core::str::eq_slice; use std::comm;
use std::comm::{Chan, Port, SharedChan};
use std::str::eq_slice;
use std::result;
use std::task;
use hubbub::hubbub; use hubbub::hubbub;
use servo_net::image_cache_task::ImageCacheTask; use servo_net::image_cache_task::ImageCacheTask;
use servo_net::image_cache_task; use servo_net::image_cache_task;
use servo_net::resource_task::{Done, Load, Payload, ResourceTask}; use servo_net::resource_task::{Done, Load, Payload, ResourceTask};
use servo_util::tree::TreeUtils; use servo_util::tree::TreeUtils;
use servo_util::url::make_url; use servo_util::url::make_url;
use std::net::url::Url; use extra::net::url::Url;
use std::net::url; use extra::net::url;
macro_rules! handle_element( macro_rules! handle_element(
($tag:expr, $string:expr, $type_id:expr, $ctor:ident, [ $(($field:ident : $field_init:expr)),* ]) => ( ($tag:expr, $string:expr, $type_id:expr, $ctor:ident, [ $(($field:ident : $field_init:expr)),* ]) => (
@ -101,7 +105,7 @@ fn css_link_listener(to_parent: Chan<Option<Stylesheet>>,
// Send the sheets back in order // Send the sheets back in order
// FIXME: Shouldn't wait until after we've recieved CSSTaskExit to start sending these // FIXME: Shouldn't wait until after we've recieved CSSTaskExit to start sending these
do vec::consume(result_vec) |_i, port| { do result_vec.consume |_i, port| {
to_parent.send(Some(port.recv())); to_parent.send(Some(port.recv()));
} }
to_parent.send(None); to_parent.send(None);
@ -140,7 +144,7 @@ fn js_script_listener(to_parent: Chan<~[~[u8]]>,
} }
} }
} }
vec::push(&mut result_vec, result_port); result_vec.push(result_port);
} }
JSTaskExit => { JSTaskExit => {
break; break;
@ -148,7 +152,7 @@ fn js_script_listener(to_parent: Chan<~[~[u8]]>,
} }
} }
let js_scripts = vec::filter_map(result_vec, |result_port| result_port.recv()); let js_scripts = result_vec.iter().filter_map(|result_port| result_port.recv()).collect();
to_parent.send(js_scripts); to_parent.send(js_scripts);
} }
@ -211,9 +215,9 @@ pub fn parse_html(url: Url,
let resource_task2 = resource_task.clone(); let resource_task2 = resource_task.clone();
let (stylesheet_port, stylesheet_chan) = comm::stream(); let (stylesheet_port, stylesheet_chan) = comm::stream();
let stylesheet_chan = Cell(stylesheet_chan); let stylesheet_chan = Cell::new(stylesheet_chan);
let (css_msg_port, css_msg_chan) = comm::stream(); let (css_msg_port, css_msg_chan) = comm::stream();
let css_msg_port = Cell(css_msg_port); let css_msg_port = Cell::new(css_msg_port);
do spawn { do spawn {
css_link_listener(stylesheet_chan.take(), css_msg_port.take(), resource_task2.clone()); css_link_listener(stylesheet_chan.take(), css_msg_port.take(), resource_task2.clone());
} }
@ -223,15 +227,16 @@ pub fn parse_html(url: Url,
// 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_port, js_result_chan) = comm::stream(); let (js_result_port, js_result_chan) = comm::stream();
let js_result_chan = Cell(js_result_chan); let js_result_chan = Cell::new(js_result_chan);
let (js_msg_port, js_msg_chan) = comm::stream(); let (js_msg_port, js_msg_chan) = comm::stream();
let js_msg_port = Cell(js_msg_port); let js_msg_port = Cell::new(js_msg_port);
do spawn { do spawn {
js_script_listener(js_result_chan.take(), js_msg_port.take(), resource_task2.clone()); js_script_listener(js_result_chan.take(), js_msg_port.take(), resource_task2.clone());
} }
let js_chan = SharedChan::new(js_msg_chan); let js_chan = SharedChan::new(js_msg_chan);
let url2 = url.clone(), url3 = url.clone(); let url2 = url.clone();
let url3 = url.clone();
// Build the root node. // Build the root node.
let root = ~HTMLHtmlElement { parent: Element::new(HTMLHtmlElementTypeId, ~"html") }; let root = ~HTMLHtmlElement { parent: Element::new(HTMLHtmlElementTypeId, ~"html") };
@ -239,7 +244,7 @@ pub fn parse_html(url: Url,
debug!("created new node"); debug!("created new node");
let mut parser = hubbub::Parser("UTF-8", false); let mut parser = hubbub::Parser("UTF-8", false);
debug!("created parser"); debug!("created parser");
parser.set_document_node(root.to_hubbub_node()); parser.set_document_node(unsafe { root.to_hubbub_node() });
parser.enable_scripting(true); parser.enable_scripting(true);
// Performs various actions necessary after appending has taken place. Currently, this // Performs various actions necessary after appending has taken place. Currently, this
@ -250,7 +255,7 @@ pub fn parse_html(url: Url,
if parent_node.is_style_element() && child_node.is_text() { if parent_node.is_style_element() && child_node.is_text() {
debug!("found inline CSS stylesheet"); debug!("found inline CSS stylesheet");
let url = url::from_str("http://example.com/"); // FIXME let url = url::from_str("http://example.com/"); // FIXME
let url_cell = Cell(url); let url_cell = Cell::new(url);
do child_node.with_imm_text |text_node| { do child_node.with_imm_text |text_node| {
let data = text_node.parent.data.to_str(); // FIXME: Bad copy. let data = text_node.parent.data.to_str(); // FIXME: Bad copy.
let provenance = InlineProvenance(result::unwrap(url_cell.take()), data); let provenance = InlineProvenance(result::unwrap(url_cell.take()), data);
@ -330,7 +335,7 @@ pub fn parse_html(url: Url,
_ => {} _ => {}
} }
node.to_hubbub_node() unsafe { node.to_hubbub_node() }
}, },
create_text: |data: ~str| { create_text: |data: ~str| {
debug!("create text"); debug!("create text");

View file

@ -9,13 +9,13 @@
use dom::node::{AbstractNode, ScriptView, LayoutView}; use dom::node::{AbstractNode, ScriptView, LayoutView};
use script_task::{ScriptMsg, ScriptChan}; use script_task::{ScriptMsg, ScriptChan};
use core::comm::{Chan, SharedChan}; use std::comm::{Chan, SharedChan};
use geom::rect::Rect; use geom::rect::Rect;
use geom::size::Size2D; use geom::size::Size2D;
use geom::point::Point2D; use geom::point::Point2D;
use gfx::geometry::Au; use gfx::geometry::Au;
use newcss::stylesheet::Stylesheet; use newcss::stylesheet::Stylesheet;
use std::net::url::Url; use extra::net::url::Url;
/// Asynchronous messages that script can send to layout. /// Asynchronous messages that script can send to layout.
/// ///

View file

@ -20,7 +20,7 @@ extern mod newcss (name = "css");
extern mod servo_net (name = "net"); extern mod servo_net (name = "net");
extern mod servo_util (name = "util"); extern mod servo_util (name = "util");
extern mod servo_msg (name = "msg"); extern mod servo_msg (name = "msg");
extern mod std; extern mod extra;
pub mod dom { pub mod dom {
pub mod bindings { pub mod bindings {

View file

@ -19,30 +19,31 @@ use layout_interface::{ReflowForDisplay, ReflowForScriptQuery, ReflowGoal, Reflo
use layout_interface; use layout_interface;
use servo_msg::engine::{EngineChan, LoadUrlMsg}; use servo_msg::engine::{EngineChan, LoadUrlMsg};
use core::cast::transmute; use std::cast::transmute;
use core::cell::Cell; use std::cell::Cell;
use core::comm::{Port, SharedChan}; use std::comm;
use core::io::read_whole_file; use std::comm::{Port, SharedChan};
use core::local_data; use std::io::read_whole_file;
use core::ptr::null; use std::local_data;
use core::task::{SingleThreaded, task}; use std::ptr::null;
use core::util::replace; use std::task::{SingleThreaded, task};
use std::util::replace;
use dom::window::TimerData; use dom::window::TimerData;
use geom::size::Size2D; use geom::size::Size2D;
use html::hubbub_html_parser; use html::hubbub_html_parser;
use js::JSVAL_NULL; use js::JSVAL_NULL;
use js::global::{global_class, debug_fns}; use js::global::{global_class, debug_fns};
use js::glue::bindgen::RUST_JSVAL_TO_OBJECT; use js::glue::RUST_JSVAL_TO_OBJECT;
use js::jsapi::JSContext; use js::jsapi::JSContext;
use js::jsapi::bindgen::{JS_CallFunctionValue, JS_GetContextPrivate}; use js::jsapi::{JS_CallFunctionValue, JS_GetContextPrivate};
use js::rust::{Compartment, Cx}; use js::rust::{Compartment, Cx};
use js; use js;
use servo_net::image_cache_task::ImageCacheTask; use servo_net::image_cache_task::ImageCacheTask;
use servo_net::resource_task::ResourceTask; use servo_net::resource_task::ResourceTask;
use servo_util::tree::TreeNodeRef; use servo_util::tree::TreeNodeRef;
use servo_util::url::make_url; use servo_util::url::make_url;
use std::net::url::Url; use extra::net::url::Url;
use std::net::url; use extra::net::url;
/// Messages used to control the script task. /// Messages used to control the script task.
pub enum ScriptMsg { pub enum ScriptMsg {
@ -146,7 +147,9 @@ pub fn global_script_context() -> @ScriptContext {
/// ///
/// FIXME: Rename to `script_context_from_js_context`. /// FIXME: Rename to `script_context_from_js_context`.
pub fn task_from_context(js_context: *JSContext) -> *mut ScriptContext { pub fn task_from_context(js_context: *JSContext) -> *mut ScriptContext {
unsafe {
JS_GetContextPrivate(js_context) as *mut ScriptContext JS_GetContextPrivate(js_context) as *mut ScriptContext
}
} }
#[unsafe_destructor] #[unsafe_destructor]
@ -200,7 +203,7 @@ impl ScriptContext {
root_frame: None, root_frame: None,
window_size: Size2D(800, 600), window_size: Size2D(800u, 600),
damage: None, damage: None,
}; };
// Indirection for Rust Issue #6248, dynamic freeze scope artifically extended // Indirection for Rust Issue #6248, dynamic freeze scope artifically extended
@ -208,9 +211,9 @@ impl ScriptContext {
let borrowed_ctx= &mut *script_context; let borrowed_ctx= &mut *script_context;
borrowed_ctx as *mut ScriptContext borrowed_ctx as *mut ScriptContext
}; };
js_context.set_cx_private(script_context_ptr as *());
unsafe { unsafe {
js_context.set_cx_private(script_context_ptr as *());
local_data::local_data_set(global_script_context_key, transmute(script_context)) local_data::local_data_set(global_script_context_key, transmute(script_context))
} }
@ -232,8 +235,8 @@ impl ScriptContext {
compositor_task: ~fn(ReadyState), compositor_task: ~fn(ReadyState),
resource_task: ResourceTask, resource_task: ResourceTask,
image_cache_task: ImageCacheTask) { image_cache_task: ImageCacheTask) {
let script_port = Cell(script_port); let script_port = Cell::new(script_port);
let compositor_task = Cell(compositor_task); let compositor_task = Cell::new(compositor_task);
// FIXME: rust#6399 // FIXME: rust#6399
let mut the_task = task(); let mut the_task = task();
the_task.sched_mode(SingleThreaded); the_task.sched_mode(SingleThreaded);
@ -298,6 +301,7 @@ impl ScriptContext {
/// Handles a timer that fired. /// Handles a timer that fired.
fn handle_fire_timer_msg(&mut self, timer_data: ~TimerData) { fn handle_fire_timer_msg(&mut self, timer_data: ~TimerData) {
unsafe {
let this_value = if timer_data.args.len() > 0 { let this_value = if timer_data.args.len() > 0 {
RUST_JSVAL_TO_OBJECT(timer_data.args[0]) RUST_JSVAL_TO_OBJECT(timer_data.args[0])
} else { } else {
@ -315,6 +319,7 @@ impl ScriptContext {
self.reflow(ReflowForScriptQuery) self.reflow(ReflowForScriptQuery)
} }
}
/// Handles a notification that reflow completed. /// Handles a notification that reflow completed.
fn handle_reflow_complete_msg(&mut self) { fn handle_reflow_complete_msg(&mut self) {
@ -325,7 +330,7 @@ impl ScriptContext {
/// Handles a request to exit the script task and shut down layout. /// Handles a request to exit the script task and shut down layout.
fn handle_exit_msg(&mut self) { fn handle_exit_msg(&mut self) {
self.join_layout(); self.join_layout();
for self.root_frame.each |frame| { for self.root_frame.iter().advance |frame| {
frame.document.teardown(); frame.document.teardown();
} }
@ -401,7 +406,7 @@ impl ScriptContext {
self.js_compartment.define_functions(debug_fns); self.js_compartment.define_functions(debug_fns);
// Evaluate every script in the document. // Evaluate every script in the document.
do vec::consume(js_scripts) |_, bytes| { do js_scripts.consume |_, bytes| {
let _ = self.js_context.evaluate_script(self.js_compartment.global_obj, let _ = self.js_context.evaluate_script(self.js_compartment.global_obj,
bytes, bytes,
~"???", ~"???",
@ -472,7 +477,7 @@ impl ScriptContext {
/// ///
/// FIXME: This should basically never be used. /// FIXME: This should basically never be used.
pub fn reflow_all(&mut self, goal: ReflowGoal) { pub fn reflow_all(&mut self, goal: ReflowGoal) {
for self.root_frame.each |root_frame| { for self.root_frame.iter().advance |root_frame| {
ScriptContext::damage(&mut self.damage, ScriptContext::damage(&mut self.damage,
root_frame.document.root, root_frame.document.root,
MatchSelectorsDocumentDamage) MatchSelectorsDocumentDamage)
@ -520,7 +525,7 @@ impl ScriptContext {
self.window_size = Size2D(new_width, new_height); self.window_size = Size2D(new_width, new_height);
for self.root_frame.each |root_frame| { for self.root_frame.iter().advance |root_frame| {
ScriptContext::damage(&mut self.damage, ScriptContext::damage(&mut self.damage,
root_frame.document.root, root_frame.document.root,
ReflowDocumentDamage); ReflowDocumentDamage);
@ -535,7 +540,7 @@ impl ScriptContext {
ReflowEvent => { ReflowEvent => {
debug!("script got reflow event"); debug!("script got reflow event");
for self.root_frame.each |root_frame| { for self.root_frame.iter().advance |root_frame| {
ScriptContext::damage(&mut self.damage, ScriptContext::damage(&mut self.damage,
root_frame.document.root, root_frame.document.root,
MatchSelectorsDocumentDamage); MatchSelectorsDocumentDamage);

View file

@ -13,8 +13,8 @@ pub struct MonoCache<K, V> {
entry: Option<(K,V)>, entry: Option<(K,V)>,
} }
pub impl<K: Copy + Eq, V: Copy> MonoCache<K,V> { impl<K: Copy + Eq, V: Copy> MonoCache<K,V> {
fn new(_size: uint) -> MonoCache<K,V> { pub fn new(_size: uint) -> MonoCache<K,V> {
MonoCache { entry: None } MonoCache { entry: None }
} }
} }
@ -27,7 +27,7 @@ impl<K: Copy + Eq, V: Copy> Cache<K,V> for MonoCache<K,V> {
fn find(&mut self, key: &K) -> Option<V> { fn find(&mut self, key: &K) -> Option<V> {
match self.entry { match self.entry {
None => None, None => None,
Some((ref k,v)) => if *k == *key { Some(v) } else { None } Some((ref k, ref v)) => if *k == *key { Some(copy *v) } else { None }
} }
} }
@ -65,19 +65,19 @@ pub struct LRUCache<K, V> {
cache_size: uint, cache_size: uint,
} }
pub impl<K: Copy + Eq, V: Copy> LRUCache<K,V> { impl<K: Copy + Eq, V: Copy> LRUCache<K,V> {
fn new(size: uint) -> LRUCache<K, V> { pub fn new(size: uint) -> LRUCache<K, V> {
LRUCache { LRUCache {
entries: ~[], entries: ~[],
cache_size: size, cache_size: size,
} }
} }
fn touch(&mut self, pos: uint) -> V { pub fn touch(&mut self, pos: uint) -> V {
let (key, val) = copy self.entries[pos]; let (key, val) = copy self.entries[pos];
if pos != self.cache_size { if pos != self.cache_size {
self.entries.remove(pos); self.entries.remove(pos);
self.entries.push((key, val)); self.entries.push((key, copy val));
} }
val val
} }
@ -103,7 +103,7 @@ impl<K: Copy + Eq, V: Copy> Cache<K,V> for LRUCache<K,V> {
Some(pos) => self.touch(pos), Some(pos) => self.touch(pos),
None => { None => {
let val = blk(key); let val = blk(key);
self.insert(key, val); self.insert(key, copy val);
val val
} }
} }

View file

@ -2,6 +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::uint;
enum RangeRelation { enum RangeRelation {
OverlapsBegin(/* overlap */ uint), OverlapsBegin(/* overlap */ uint),
OverlapsEnd(/* overlap */ uint), OverlapsEnd(/* overlap */ uint),
@ -17,7 +19,7 @@ pub struct Range {
priv len: uint priv len: uint
} }
pub impl Range { impl Range {
pub fn new(off: uint, len: uint) -> Range { pub fn new(off: uint, len: uint) -> Range {
Range { off: off, len: len } Range { off: off, len: len }
} }
@ -27,12 +29,12 @@ pub impl Range {
} }
} }
pub impl Range { impl Range {
fn begin(&self) -> uint { self.off } pub fn begin(&self) -> uint { self.off }
fn length(&self) -> uint { self.len } pub fn length(&self) -> uint { self.len }
fn end(&self) -> uint { self.off + self.len } pub fn end(&self) -> uint { self.off + self.len }
fn eachi(&self, callback: &fn(uint) -> bool) -> bool { pub fn eachi(&self, callback: &fn(uint) -> bool) -> bool {
for uint::range(self.off, self.off + self.len) |i| { for uint::range(self.off, self.off + self.len) |i| {
if !callback(i) { if !callback(i) {
break break
@ -41,32 +43,32 @@ pub impl Range {
true true
} }
fn contains(&self, i: uint) -> bool { pub fn contains(&self, i: uint) -> bool {
i >= self.begin() && i < self.end() i >= self.begin() && i < self.end()
} }
fn is_valid_for_string(&self, s: &str) -> bool { pub fn is_valid_for_string(&self, s: &str) -> bool {
self.begin() < s.len() && self.end() <= s.len() && self.length() <= s.len() self.begin() < s.len() && self.end() <= s.len() && self.length() <= s.len()
} }
fn shift_by(&mut self, i: int) { pub fn shift_by(&mut self, i: int) {
self.off = ((self.off as int) + i) as uint; self.off = ((self.off as int) + i) as uint;
} }
fn extend_by(&mut self, i: int) { pub fn extend_by(&mut self, i: int) {
self.len = ((self.len as int) + i) as uint; self.len = ((self.len as int) + i) as uint;
} }
fn extend_to(&mut self, i: uint) { pub fn extend_to(&mut self, i: uint) {
self.len = i - self.off; self.len = i - self.off;
} }
fn adjust_by(&mut self, off_i: int, len_i: int) { pub fn adjust_by(&mut self, off_i: int, len_i: int) {
self.off = ((self.off as int) + off_i) as uint; self.off = ((self.off as int) + off_i) as uint;
self.len = ((self.len as int) + len_i) as uint; self.len = ((self.len as int) + len_i) as uint;
} }
fn reset(&mut self, off_i: uint, len_i: uint) { pub fn reset(&mut self, off_i: uint, len_i: uint) {
self.off = off_i; self.off = off_i;
self.len = len_i; self.len = len_i;
} }
@ -74,7 +76,7 @@ pub impl Range {
/// Computes the relationship between two ranges (`self` and `other`), /// Computes the relationship between two ranges (`self` and `other`),
/// from the point of view of `self`. So, 'EntirelyBefore' means /// from the point of view of `self`. So, 'EntirelyBefore' means
/// that the `self` range is entirely before `other` range. /// that the `self` range is entirely before `other` range.
fn relation_to_range(&self, other: &Range) -> RangeRelation { pub fn relation_to_range(&self, other: &Range) -> RangeRelation {
if other.begin() > self.end() { if other.begin() > self.end() {
return EntirelyBefore; return EntirelyBefore;
} }
@ -102,7 +104,7 @@ pub impl Range {
self, other)); self, other));
} }
fn repair_after_coalesced_range(&mut self, other: &Range) { pub fn repair_after_coalesced_range(&mut self, other: &Range) {
let relation = self.relation_to_range(other); let relation = self.relation_to_range(other);
debug!("repair_after_coalesced_range: possibly repairing range %?", self); debug!("repair_after_coalesced_range: possibly repairing range %?", self);
debug!("repair_after_coalesced_range: relation of original range and coalesced range(%?): %?", debug!("repair_after_coalesced_range: relation of original range and coalesced range(%?): %?",

View file

@ -3,10 +3,10 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// Timing functions. // Timing functions.
use std::time::precise_time_ns; use extra::time::precise_time_ns;
use core::cell::Cell; use std::cell::Cell;
use core::comm::{Port, SharedChan}; use std::comm::{Port, SharedChan};
use std::sort::tim_sort; use extra::sort::tim_sort;
// front-end representation of the profiler used to communicate with the profiler // front-end representation of the profiler used to communicate with the profiler
#[deriving(Clone)] #[deriving(Clone)]
@ -111,7 +111,7 @@ impl ProfilerCategory {
impl Profiler { impl Profiler {
pub fn create(port: Port<ProfilerMsg>) { pub fn create(port: Port<ProfilerMsg>) {
let port = Cell(port); let port = Cell::new(port);
do spawn { do spawn {
let mut profiler = Profiler::new(port.take()); let mut profiler = Profiler::new(port.take());
profiler.start(); profiler.start();
@ -154,7 +154,7 @@ impl Profiler {
println(fmt!("%31s %15s %15s %15s %15s %15s", println(fmt!("%31s %15s %15s %15s %15s %15s",
"_category (ms)_", "_mean (ms)_", "_median (ms)_", "_category (ms)_", "_mean (ms)_", "_median (ms)_",
"_min (ms)_", "_max (ms)_", "_bucket size_")); "_min (ms)_", "_max (ms)_", "_bucket size_"));
for vec::each_mut(self.buckets) |bucket| { for self.buckets.mut_iter().advance |bucket| {
match *bucket { match *bucket {
(category, ref mut data) => { (category, ref mut data) => {
tim_sort(*data); tim_sort(*data);
@ -163,8 +163,8 @@ impl Profiler {
let (mean, median, min, max) = let (mean, median, min, max) =
(data.foldl(0f64, |a, b| a + *b) / (data_len as f64), (data.foldl(0f64, |a, b| a + *b) / (data_len as f64),
data[data_len / 2], data[data_len / 2],
data.min(), data.iter().min(),
data.max()); data.iter().max());
println(fmt!("%-30s: %15.4? %15.4? %15.4? %15.4? %15u", println(fmt!("%-30s: %15.4? %15.4? %15.4? %15.4? %15u",
category.format(), mean, median, min, max, data_len)); category.format(), mean, median, min, max, data_len));
} }

View file

@ -2,9 +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::net::url; use extra::net::url;
use std::net::url::Url; use extra::net::url::Url;
use core::hashmap::HashMap; use std::hashmap::HashMap;
use std::os;
use std::result;
/** /**
Create a URL object from a string. Does various helpful browsery things like Create a URL object from a string. Does various helpful browsery things like
@ -36,15 +38,15 @@ pub fn make_url(str_url: ~str, current_url: Option<Url>) -> Url {
str_url.starts_with("/") { str_url.starts_with("/") {
current_url.scheme + "://" + current_url.scheme + "://" +
current_url.host + "/" + current_url.host + "/" +
str_url.trim_left_chars([ '/' ]) str_url.trim_left_chars(&'/')
} else { } else {
let mut path = ~[]; let mut path = ~[];
for str::each_split_char(current_url.path, '/') |p| { for current_url.path.split_iter('/').advance |p| {
path.push(p.to_str()); path.push(p.to_str());
} }
let path = path; // FIXME: borrow checker workaround let path = path; // FIXME: borrow checker workaround
let path = path.init(); let path = path.init();
let path = str::connect(path.map(|x| copy *x) + ~[str_url], "/"); let path = (path.map(|x| copy *x) + [str_url]).connect("/");
current_url.scheme + "://" + current_url.host + path current_url.scheme + "://" + current_url.host + path
} }

View file

@ -8,7 +8,7 @@
url = "http://servo.org/")]; url = "http://servo.org/")];
#[crate_type = "lib"]; #[crate_type = "lib"];
extern mod std; extern mod extra;
pub mod cache; pub mod cache;
pub mod range; pub mod range;

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/. */
use core::cmp::{Ord, Eq}; use std::cmp::{Ord, Eq};
pub trait BinarySearchMethods<'self, T: Ord + Eq> { pub trait BinarySearchMethods<'self, T: Ord + Eq> {
fn binary_search(&self, key: &T) -> Option<&'self T>; fn binary_search(&self, key: &T) -> Option<&'self T>;

@ -1 +1 @@
Subproject commit 7cb7a7aace99b17f99f15649377bb13a0dac9b63 Subproject commit faca1281aaf112e96ee03041744fe85ac4273192

@ -1 +1 @@
Subproject commit cde4fdcfe2c956f070c2b0e26c5fd99821248cdc Subproject commit 5247c3e97f7eafa336c8a028a3175c3bc3a2d95a

@ -1 +1 @@
Subproject commit 0ac7b8dc20c4142ac6ad4500d7ae90c2bd3e7424 Subproject commit 788f41a6e924e5c3f9d254d3e5dabf2b3e622f00

@ -1 +1 @@
Subproject commit d916b9796668d4bb46a3b1b4976c95ab7da79837 Subproject commit 3ef4cf7fdaaaa51026ec546a71426ff03a0899fd

@ -1 +1 @@
Subproject commit 40b2a4eaf80287a4c4727b97313151705b4f04c6 Subproject commit ea8d2bd026cd91d3fb5fd753677da3fd7d21dbab

@ -1 +1 @@
Subproject commit 3433fbda15cf2f16e00ff8103ae7652468a43a2c Subproject commit bf9d0ebf3e0283f8bdb505d29d93de9631f7877c

@ -1 +1 @@
Subproject commit 98e2d7e3870759fe91c93ba520452a700fec8756 Subproject commit 72c7673ac50cc1ffb518de65022fb034df334ed9

@ -1 +1 @@
Subproject commit 0cba81aab4858442e9a995cf3b0149d0d116627c Subproject commit 8a15a3bd2bd98ee4fb0513b71d7055c8be40a4b7

@ -1 +1 @@
Subproject commit cf5641f5b0b7720e3841518ab7fbfafb4d2443a4 Subproject commit 6daaffe3b6cf226c6da4979d0fb907a8258b0288

@ -1 +1 @@
Subproject commit 865f539114383a021822583801e8362faf916699 Subproject commit 5e8c30cc69286e68ba9bf843f146a580381bff83

@ -1 +1 @@
Subproject commit efba52c020945e08f00bebf8ff54ec292e95eced Subproject commit a23cb0bc99a933efa9104c2471ccd14638744ea4

@ -1 +1 @@
Subproject commit 453bf81e021008f5eba29b135f07f4529e6c8b2e Subproject commit 42931c8e0894c0d3d70d29abdf16639b30e6bf92

@ -1 +1 @@
Subproject commit 56e106b9aa05f3a341397c0e116695fb8a826226 Subproject commit 4d576047b5b94d98669080f3ac25efa053024d7e

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