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 text::SendableTextRun;
use core::cast::transmute_region;
use std::cast::transmute_region;
use geom::{Point2D, Rect, Size2D};
use servo_net::image::base::Image;
use servo_util::range::Range;
use std::arc::ARC;
use extra::arc::ARC;
/// A list of rendering operations to be performed.
pub struct DisplayList<E> {

View file

@ -9,6 +9,11 @@ use platform::font_context::FontContextHandle;
use platform::font::{FontHandle, FontTable};
use render_context::RenderContext;
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::shaping::ShaperMethods;
use text::{Shaper, TextRun};
@ -94,7 +99,7 @@ pub enum CSSFontWeight {
FontWeight900,
}
pub impl CSSFontWeight {
impl CSSFontWeight {
pub fn is_bold(self) -> bool {
match self {
FontWeight900 | FontWeight800 | FontWeight700 | FontWeight600 => true,
@ -140,8 +145,8 @@ pub struct FontDescriptor {
selector: FontSelector,
}
pub impl FontDescriptor {
fn new(style: UsedFontStyle, selector: FontSelector) -> FontDescriptor {
impl FontDescriptor {
pub fn new(style: UsedFontStyle, selector: FontSelector) -> FontDescriptor {
FontDescriptor {
style: style,
selector: selector,
@ -170,8 +175,8 @@ pub struct FontGroup {
fonts: ~[@mut Font],
}
pub impl FontGroup {
fn new(families: @str, style: &UsedFontStyle, fonts: ~[@mut Font]) -> FontGroup {
impl FontGroup {
pub fn new(families: @str, style: &UsedFontStyle, fonts: ~[@mut Font]) -> FontGroup {
FontGroup {
families: families,
style: copy *style,
@ -179,11 +184,11 @@ pub impl FontGroup {
}
}
fn teardown(&mut self) {
pub fn teardown(&mut self) {
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);
// TODO(Issue #177): Actually fall back through the FontGroup when a font is unsuitable.
@ -215,8 +220,8 @@ pub struct Font {
profiler_chan: ProfilerChan,
}
pub impl Font {
fn new_from_buffer(ctx: &FontContext,
impl Font {
pub fn new_from_buffer(ctx: &FontContext,
buffer: ~[u8],
style: &SpecifiedFontStyle,
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,
profiler_chan: ProfilerChan) -> @mut Font {
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,
profiler_chan: ProfilerChan) -> Result<@mut Font,()> {
@ -284,7 +289,7 @@ pub impl Font {
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 status = if result.is_some() { "Found" } else { "Didn't find" };
@ -295,7 +300,7 @@ pub impl Font {
return result;
}
fn teardown(&mut self) {
pub fn teardown(&mut self) {
self.shaper = None;
self.azure_font = None;
}
@ -332,19 +337,19 @@ pub impl Font {
}
pub impl Font {
fn draw_text_into_context(&mut self,
impl Font {
pub fn draw_text_into_context(&mut self,
rctx: &RenderContext,
run: &TextRun,
range: &Range,
baseline_origin: Point2D<Au>,
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,
struct__AzGlyph,
struct__AzGlyphBuffer,
struct__AzPoint};
use azure::azure::bindgen::{AzDrawTargetFillGlyphs};
use azure::azure::{AzDrawTargetFillGlyphs};
let target = rctx.get_draw_target();
let azfontref = self.get_azure_font();
@ -362,7 +367,7 @@ pub impl Font {
vec::reserve(&mut azglyphs, range.length());
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 azglyph = struct__AzGlyph {
@ -379,28 +384,28 @@ pub impl Font {
let azglyph_buf_len = azglyphs.len();
if azglyph_buf_len == 0 { return; } // Otherwise the Quartz backend will assert.
let glyphbuf = unsafe {
struct__AzGlyphBuffer {
mGlyphs: vec::raw::to_ptr(azglyphs),
mNumGlyphs: azglyph_buf_len as uint32_t
}
let glyphbuf = struct__AzGlyphBuffer {
mGlyphs: vec::raw::to_ptr(azglyphs),
mNumGlyphs: azglyph_buf_len as uint32_t
};
// TODO(Issue #64): this call needs to move into azure_hl.rs
AzDrawTargetFillGlyphs(target.azure_draw_target,
azfontref,
ptr::to_unsafe_ptr(&glyphbuf),
azure_pattern,
ptr::to_unsafe_ptr(&options),
ptr::null());
unsafe {
// TODO(Issue #64): this call needs to move into azure_hl.rs
AzDrawTargetFillGlyphs(target.azure_draw_target,
azfontref,
ptr::to_unsafe_ptr(&glyphbuf),
azure_pattern,
ptr::to_unsafe_ptr(&options),
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 #98): using inter-char and inter-word spacing settings when measuring text
let mut advance = Au(0);
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),
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.
// For example, Gecko uses a per-"word" hashtable of shaper results.
let shaper = self.get_shaper();
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()))
}
fn glyph_index(&self, codepoint: char) -> Option<GlyphIndex> {
pub fn glyph_index(&self, codepoint: char) -> Option<GlyphIndex> {
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) {
Some(adv) => adv,
None => /* FIXME: Need fallback strategy */ 10f as FractionalPixel

View file

@ -14,7 +14,9 @@ use platform::font::FontHandle;
use platform::font_context::FontContextHandle;
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
// for not being able to store symbolic enums in top-level constants.
@ -46,8 +48,8 @@ pub struct FontContext {
}
#[allow(non_implicitly_copyable_typarams)]
pub impl<'self> FontContext {
fn new(backend: BackendType,
impl<'self> FontContext {
pub fn new(backend: BackendType,
needs_font_list: bool,
profiler_chan: ProfilerChan)
-> FontContext {
@ -79,7 +81,7 @@ pub impl<'self> FontContext {
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) {
Some(fg) => {
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) {
Some(f) => {
debug!("font cache hit");
@ -129,8 +131,8 @@ pub impl<'self> FontContext {
debug!("(create font group) --- starting ---");
// TODO(Issue #193): make iteration over 'font-family' more robust.
for str::each_split_char(style.families, ',') |family| {
let family_name = str::trim(family);
for style.families.split_iter(',').advance |family| {
let family_name = family.trim();
let transformed_family_name = self.transform_family(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;
for result.each |font_entry| {
for result.iter().advance |font_entry| {
found = true;
let font_id =
@ -161,7 +163,7 @@ pub impl<'self> FontContext {
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 {
Some(ref fl) => {
fl.find_font_in_family(*family, style)
@ -169,7 +171,7 @@ pub impl<'self> FontContext {
None => None,
};
for result.each |font_entry| {
for result.iter().advance |font_entry| {
let font_id =
SelectorPlatformIdentifier(font_entry.handle.face_identifier());
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_list::FontListHandle;
use servo_util::time;
use servo_util::time::time;
use servo_util::time::profile;
use servo_util::time::ProfilerChan;
use core::hashmap::HashMap;
use std::hashmap::HashMap;
pub type FontFamilyMap = HashMap<~str, @mut FontFamily>;
@ -29,8 +28,8 @@ pub struct FontList {
prof_chan: ProfilerChan,
}
pub impl FontList {
fn new(fctx: &FontContextHandle,
impl FontList {
pub fn new(fctx: &FontContextHandle,
prof_chan: ProfilerChan)
-> FontList {
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,
style: &SpecifiedFontStyle) -> Option<@FontEntry> {
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
let mut result: Option<@FontEntry> = None;
for family.each |fam| {
for family.iter().advance |fam| {
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::size::Size2D;
use core::num::{NumCast, One, Zero};
use std::num::{NumCast, One, Zero};
#[deriving(Clone)]
pub struct Au(i32);
impl Add<Au,Au> for Au {
@ -34,14 +35,14 @@ impl Neg<Au> for Au {
fn neg(&self) -> Au { Au(-**self) }
}
impl cmp::Ord for Au {
impl Ord for Au {
fn lt(&self, other: &Au) -> bool { **self < **other }
fn le(&self, other: &Au) -> bool { **self <= **other }
fn ge(&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 ne(&self, other: &Au) -> bool { **self != **other }
}
@ -80,11 +81,11 @@ impl NumCast for Au {
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))
}
pub impl Au {
impl Au {
pub fn scale_by(self, factor: float) -> Au {
Au(((*self as float) * factor) as i32)
}

View file

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

View file

@ -8,6 +8,10 @@
use azure::azure_hl::{BackendType, CairoBackend, CoreGraphicsBackend};
use azure::azure_hl::{CoreGraphicsAcceleratedBackend, Direct2DBackend, SkiaBackend};
use std::f64;
use std::result;
use std::uint;
pub struct Opts {
urls: ~[~str],
render_backend: BackendType,
@ -22,17 +26,17 @@ pub struct Opts {
#[allow(non_implicitly_copyable_typarams)]
pub fn from_cmdline_args(args: &[~str]) -> Opts {
use std::getopts;
use extra::getopts;
let args = args.tail();
let opts = ~[
getopts::optopt(~"o"), // output file
getopts::optopt(~"r"), // rendering backend
getopts::optopt(~"s"), // size of tiles
getopts::optopt(~"t"), // threads to render with
getopts::optflagopt(~"p"), // profiler flag and output interval
getopts::optopt(~"z"), // zoom level
getopts::optopt("o"), // output file
getopts::optopt("r"), // rendering backend
getopts::optopt("s"), // size of tiles
getopts::optopt("t"), // threads to render with
getopts::optflagopt("p"), // profiler flag and output interval
getopts::optopt("z"), // zoom level
];
let opt_match = match getopts::getopts(args, opts) {
@ -45,11 +49,11 @@ pub fn from_cmdline_args(args: &[~str]) -> Opts {
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.")
}
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) => {
if backend_str == ~"direct2d" {
Direct2DBackend
@ -68,24 +72,24 @@ pub fn from_cmdline_args(args: &[~str]) -> Opts {
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(),
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(),
None => 1, // FIXME: Number of cores.
};
let profiler_period: Option<f64> =
// 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()),
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(),
None => 1,
};

View file

@ -14,10 +14,10 @@ use platform::font_context::FontContextHandle;
use text::glyph::GlyphIndex;
use text::util::{float_to_fixed, fixed_to_float};
use freetype::freetype::bindgen::{FT_Get_Char_Index, FT_Get_Postscript_Name};
use freetype::freetype::bindgen::{FT_Load_Glyph, FT_Set_Char_Size};
use freetype::freetype::bindgen::{FT_New_Face, FT_Get_Sfnt_Table};
use freetype::freetype::bindgen::{FT_New_Memory_Face, FT_Done_Face};
use freetype::freetype::{FT_Get_Char_Index, FT_Get_Postscript_Name};
use freetype::freetype::{FT_Load_Glyph, FT_Set_Char_Size};
use freetype::freetype::{FT_New_Face, FT_Get_Sfnt_Table};
use freetype::freetype::{FT_New_Memory_Face, FT_Done_Face};
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_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::tt_os2::TT_OS2;
use std::cast;
use std::ptr;
use std::str;
use std::vec;
fn float_to_fixed_ft(f: float) -> i32 {
float_to_fixed(6, f)
}
@ -60,8 +65,10 @@ pub struct FontHandle {
impl Drop for FontHandle {
fn finalize(&self) {
assert!(self.face.is_not_null());
if !FT_Done_Face(self.face).succeeded() {
fail!(~"FT_Done_Face failed");
unsafe {
if !FT_Done_Face(self.face).succeeded() {
fail!(~"FT_Done_Face failed");
}
}
}
}
@ -97,18 +104,20 @@ impl FontHandleMethods for FontHandle {
cbuf: *u8, cbuflen: uint, pt_size: float)
-> Result<FT_Face, ()> {
let mut face: FT_Face = ptr::null();
let face_index = 0 as FT_Long;
let result = FT_New_Memory_Face(lib, cbuf, cbuflen as FT_Long,
face_index, ptr::to_mut_unsafe_ptr(&mut face));
unsafe {
let mut face: FT_Face = ptr::null();
let face_index = 0 as FT_Long;
let result = FT_New_Memory_Face(lib, cbuf, cbuflen as FT_Long,
face_index, ptr::to_mut_unsafe_ptr(&mut face));
if !result.succeeded() || face.is_null() {
return Err(());
}
if FontHandle::set_char_size(face, pt_size).is_ok() {
Ok(face)
} else {
Err(())
if !result.succeeded() || face.is_null() {
return Err(());
}
if FontHandle::set_char_size(face, pt_size).is_ok() {
Ok(face)
} else {
Err(())
}
}
}
}
@ -133,24 +142,26 @@ impl FontHandleMethods for FontHandle {
if unsafe { (*self.face).style_flags & FT_STYLE_FLAG_BOLD == 0 } {
default_weight
} else {
let os2 = FT_Get_Sfnt_Table(self.face, ft_sfnt_os2) as *TT_OS2;
let valid = os2.is_not_null() && unsafe { (*os2).version != 0xffff };
if valid {
let weight = unsafe { (*os2).usWeightClass };
match weight {
1 | 100..199 => FontWeight100,
2 | 200..299 => FontWeight200,
3 | 300..399 => FontWeight300,
4 | 400..499 => FontWeight400,
5 | 500..599 => FontWeight500,
6 | 600..699 => FontWeight600,
7 | 700..799 => FontWeight700,
8 | 800..899 => FontWeight800,
9 | 900..999 => FontWeight900,
_ => default_weight
unsafe {
let os2 = FT_Get_Sfnt_Table(self.face, ft_sfnt_os2) as *TT_OS2;
let valid = os2.is_not_null() && (*os2).version != 0xffff;
if valid {
let weight =(*os2).usWeightClass;
match weight {
1 | 100..199 => FontWeight100,
2 | 200..299 => FontWeight200,
3 | 300..399 => FontWeight300,
4 | 400..499 => FontWeight400,
5 | 500..599 => FontWeight500,
6 | 600..699 => FontWeight600,
7 | 700..799 => FontWeight700,
8 | 800..899 => FontWeight800,
9 | 900..999 => FontWeight900,
_ => default_weight
}
} else {
default_weight
}
} else {
default_weight
}
}
}
@ -162,8 +173,8 @@ impl FontHandleMethods for FontHandle {
FontSourceMem(ref buf) => {
FontHandleMethods::new_from_buffer(fctx, buf.clone(), style)
}
FontSourceFile(copy file) => {
FontHandle::new_from_file(fctx, file, style)
FontSourceFile(ref file) => {
FontHandle::new_from_file(fctx, copy *file, style)
}
}
}
@ -171,21 +182,23 @@ impl FontHandleMethods for FontHandle {
pub fn glyph_index(&self,
codepoint: char) -> Option<GlyphIndex> {
assert!(self.face.is_not_null());
let idx = FT_Get_Char_Index(self.face, codepoint as FT_ULong);
return if idx != 0 as FT_UInt {
Some(idx as GlyphIndex)
} else {
debug!("Invalid codepoint: %?", codepoint);
None
};
unsafe {
let idx = FT_Get_Char_Index(self.face, codepoint as FT_ULong);
return if idx != 0 as FT_UInt {
Some(idx as GlyphIndex)
} else {
debug!("Invalid codepoint: %?", codepoint);
None
};
}
}
pub fn glyph_h_advance(&self,
glyph: GlyphIndex) -> Option<FractionalPixel> {
assert!(self.face.is_not_null());
let res = FT_Load_Glyph(self.face, glyph as FT_UInt, 0);
if res.succeeded() {
unsafe {
unsafe {
let res = FT_Load_Glyph(self.face, glyph as FT_UInt, 0);
if res.succeeded() {
let void_glyph = (*self.face).glyph;
let slot: FT_GlyphSlot = cast::transmute(void_glyph);
assert!(slot.is_not_null());
@ -194,10 +207,10 @@ impl FontHandleMethods for FontHandle {
debug!("h_advance for %? is %?", glyph, advance);
let advance = advance as i32;
return Some(fixed_to_float_ft(advance) as FractionalPixel);
} else {
debug!("Unable to load glyph %?. reason: %?", glyph, res);
return None;
}
} else {
debug!("Unable to load glyph %?. reason: %?", glyph, res);
return None;
}
}
@ -229,62 +242,68 @@ impl FontHandleMethods for FontHandle {
}
}
pub impl<'self> FontHandle {
impl<'self> FontHandle {
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_height = float_to_fixed_ft(pt_size) as FT_F26Dot6;
let h_dpi = 72;
let v_dpi = 72;
let result = FT_Set_Char_Size(face, char_width, char_height, h_dpi, v_dpi);
if result.succeeded() { Ok(()) } else { Err(()) }
unsafe {
let result = FT_Set_Char_Size(face, char_width, char_height, h_dpi, v_dpi);
if result.succeeded() { Ok(()) } else { Err(()) }
}
}
pub fn new_from_file(fctx: &FontContextHandle, file: ~str,
style: &SpecifiedFontStyle) -> Result<FontHandle, ()> {
let ft_ctx: FT_Library = fctx.ctx.ctx;
if ft_ctx.is_null() { return Err(()); }
unsafe {
let ft_ctx: FT_Library = fctx.ctx.ctx;
if ft_ctx.is_null() { return Err(()); }
let mut face: FT_Face = ptr::null();
let face_index = 0 as FT_Long;
do str::as_c_str(file) |file_str| {
FT_New_Face(ft_ctx, file_str,
face_index, ptr::to_mut_unsafe_ptr(&mut face));
}
if face.is_null() {
return Err(());
}
if FontHandle::set_char_size(face, style.pt_size).is_ok() {
Ok(FontHandle {
source: FontSourceFile(file),
face: face,
handle: *fctx
})
} else {
Err(())
let mut face: FT_Face = ptr::null();
let face_index = 0 as FT_Long;
do str::as_c_str(file) |file_str| {
FT_New_Face(ft_ctx, file_str,
face_index, ptr::to_mut_unsafe_ptr(&mut face));
}
if face.is_null() {
return Err(());
}
if FontHandle::set_char_size(face, style.pt_size).is_ok() {
Ok(FontHandle {
source: FontSourceFile(file),
face: face,
handle: *fctx
})
} else {
Err(())
}
}
}
pub fn new_from_file_unstyled(fctx: &FontContextHandle, file: ~str)
-> Result<FontHandle, ()> {
let ft_ctx: FT_Library = fctx.ctx.ctx;
if ft_ctx.is_null() { return Err(()); }
unsafe {
let ft_ctx: FT_Library = fctx.ctx.ctx;
if ft_ctx.is_null() { return Err(()); }
let mut face: FT_Face = ptr::null();
let face_index = 0 as FT_Long;
do str::as_c_str(file) |file_str| {
FT_New_Face(ft_ctx, file_str,
face_index, ptr::to_mut_unsafe_ptr(&mut face));
}
if face.is_null() {
return Err(());
}
let mut face: FT_Face = ptr::null();
let face_index = 0 as FT_Long;
do str::as_c_str(file) |file_str| {
FT_New_Face(ft_ctx, file_str,
face_index, ptr::to_mut_unsafe_ptr(&mut face));
}
if face.is_null() {
return Err(());
}
Ok(FontHandle {
source: FontSourceFile(file),
face: face,
handle: *fctx
})
Ok(FontHandle {
source: FontSourceFile(file),
face: face,
handle: *fctx
})
}
}
priv fn get_face_rec(&'self self) -> &'self FT_FaceRec {

View file

@ -8,8 +8,9 @@ use font_context::FontContextHandleMethods;
use platform::font_list::path_from_identifier;
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 {
ctx: FT_Library,
@ -18,7 +19,9 @@ struct FreeTypeLibraryHandle {
impl Drop for FreeTypeLibraryHandle {
fn finalize(&self) {
assert!(self.ctx.is_not_null());
FT_Done_FreeType(self.ctx);
unsafe {
FT_Done_FreeType(self.ctx);
}
}
}
@ -26,14 +29,16 @@ pub struct FontContextHandle {
ctx: @FreeTypeLibraryHandle,
}
pub impl FontContextHandle {
impl FontContextHandle {
pub fn new() -> FontContextHandle {
let ctx: FT_Library = ptr::null();
let result = FT_Init_FreeType(ptr::to_unsafe_ptr(&ctx));
if !result.succeeded() { fail!(); }
unsafe {
let ctx: FT_Library = ptr::null();
let result = FT_Init_FreeType(ptr::to_unsafe_ptr(&ctx));
if !result.succeeded() { fail!(); }
FontContextHandle {
ctx: @FreeTypeLibraryHandle { ctx: ctx },
FontContextHandle {
ctx: @FreeTypeLibraryHandle { ctx: ctx },
}
}
}
}

View file

@ -9,7 +9,7 @@ use fontconfig::fontconfig::{
FcChar8, FcResultMatch, FcSetSystem, FcPattern,
FcResultNoMatch, FcMatchPattern, FC_SLANT_ITALIC, FC_WEIGHT_BOLD
};
use fontconfig::fontconfig::bindgen::{
use fontconfig::fontconfig::{
FcConfigGetCurrent, FcConfigGetFonts, FcPatternGetString,
FcPatternDestroy, FcFontSetDestroy, FcConfigSubstitute,
FcDefaultSubstitute, FcPatternCreate, FcPatternAddString, FcPatternAddInteger,
@ -24,20 +24,23 @@ use font_list::{FontEntry, FontFamily, FontFamilyMap};
use platform::font::FontHandle;
use platform::font_context::FontContextHandle;
use core::hashmap::HashMap;
use core::libc::c_int;
use core::ptr::Ptr;
use std::hashmap::HashMap;
use std::libc;
use std::libc::c_int;
use std::ptr;
use std::str;
use std::uint;
pub struct FontListHandle {
fctx: FontContextHandle,
}
pub impl FontListHandle {
impl FontListHandle {
pub fn new(fctx: &FontContextHandle) -> FontListHandle {
FontListHandle { fctx: fctx.clone() }
}
fn get_available_families(&self) -> FontFamilyMap {
pub fn get_available_families(&self) -> FontFamilyMap {
let mut family_map : FontFamilyMap = HashMap::new();
unsafe {
let config = FcConfigGetCurrent();
@ -60,12 +63,12 @@ pub impl FontListHandle {
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);
let config = FcConfigGetCurrent();
let font_set = FcConfigGetFonts(config, FcSetSystem);
let font_set_array_ptr = ptr::to_unsafe_ptr(&font_set);
unsafe {
let config = FcConfigGetCurrent();
let font_set = FcConfigGetFonts(config, FcSetSystem);
let font_set_array_ptr = ptr::to_unsafe_ptr(&font_set);
let pattern = FcPatternCreate();
assert!(pattern.is_not_null());
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"]
}
}
@ -137,7 +140,9 @@ struct AutoPattern {
impl Drop for AutoPattern {
fn finalize(&self) {
FcPatternDestroy(self.pattern);
unsafe {
FcPatternDestroy(self.pattern);
}
}
}

View file

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

View file

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

View file

@ -15,20 +15,21 @@ use core_text::font_collection::CTFontCollectionMethods;
use core_text::font_descriptor::CTFontDescriptorRef;
use core_text;
use core::hashmap::HashMap;
use std::hashmap::HashMap;
use std::result;
pub struct FontListHandle {
fctx: FontContextHandle,
}
pub impl FontListHandle {
fn new(fctx: &FontContextHandle) -> FontListHandle {
impl FontListHandle {
pub fn new(fctx: &FontContextHandle) -> FontListHandle {
FontListHandle {
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 mut family_map: FontFamilyMap = HashMap::new();
for family_names.each |&strref: &CFStringRef| {
@ -41,7 +42,7 @@ pub impl FontListHandle {
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);
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"]
}
}

View file

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

View file

@ -17,8 +17,9 @@ use geom::rect::Rect;
use opts::Opts;
use render_context::RenderContext;
use core::cell::Cell;
use core::comm::{Chan, Port, SharedChan};
use std::cell::Cell;
use std::comm::{Chan, Port, SharedChan};
use std::uint;
use servo_util::time::{ProfilerChan, profile};
use servo_util::time;
@ -62,9 +63,9 @@ pub fn create_render_task<C: RenderListener + Owned>(port: Port<Msg<C>>,
compositor: C,
opts: Opts,
profiler_chan: ProfilerChan) {
let compositor_cell = Cell(compositor);
let opts_cell = Cell(opts);
let port = Cell(port);
let compositor_cell = Cell::new(compositor);
let opts_cell = Cell::new(opts);
let port = Cell::new(port);
do spawn {
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
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use std::vec;
use geom::size::Size2D;
#[deriving(Eq)]

View file

@ -2,19 +2,20 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use servo_util::range::Range;
use servo_util::vec::*;
use servo_util::range::Range;
use geometry::Au;
use geometry;
use core::cmp::{Ord, Eq};
use core::num::NumCast;
use core::u16;
use core;
use std::cmp::{Ord, Eq};
use std::num::NumCast;
use std::u16;
use std::vec;
use std::uint;
use std::util;
use geom::point::Point2D;
use std::sort;
use extra::sort;
/// 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.)
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;
sort::quick_sort3(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;
}
@ -468,7 +469,8 @@ impl<'self> GlyphInfo<'self> {
}
#[inline(always)]
fn advance(self) -> Au {
// FIXME: Resolution conflicts with IteratorUtil trait so adding trailing _
fn advance_(self) -> Au {
match self {
SimpleGlyphInfo(store, entry_i) => store.entry_buffer[entry_i].advance(),
DetailGlyphInfo(store, entry_i, detail_j) => {
@ -507,10 +509,10 @@ pub struct GlyphStore {
detail_store: DetailedGlyphStore,
}
pub impl<'self> GlyphStore {
impl<'self> GlyphStore {
// Initializes the glyph store, but doesn't actually shape anything.
// 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);
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();
}
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 {
is_simple_glyph_id(data.index)
&& is_simple_advance(data.advance)
@ -547,7 +549,7 @@ pub impl<'self> GlyphStore {
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!(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.
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());
let entry = GlyphEntry::complex(cluster_start, ligature_start, 0);
@ -585,7 +587,7 @@ pub impl<'self> GlyphStore {
self.entry_buffer[i] = entry;
}
fn iter_glyphs_for_char_index(&'self self,
pub fn iter_glyphs_for_char_index(&'self self,
i: uint,
cb: &fn(uint, &GlyphInfo<'self>) -> bool)
-> bool {
@ -609,7 +611,7 @@ pub impl<'self> GlyphStore {
true
}
fn iter_glyphs_for_char_range(&'self self,
pub fn iter_glyphs_for_char_range(&'self self,
range: &Range,
callback: &fn(uint, &GlyphInfo<'self>) -> bool)
-> bool {
@ -631,7 +633,7 @@ pub impl<'self> GlyphStore {
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| {
if !self.iter_glyphs_for_char_index(i, cb) {
break;
@ -642,56 +644,56 @@ pub impl<'self> GlyphStore {
}
// 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());
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());
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());
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());
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());
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());
self.entry_buffer[i].can_break_before()
}
// 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());
let entry = self.entry_buffer[i];
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());
let entry = self.entry_buffer[i];
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());
let entry = self.entry_buffer[i];
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());
let entry = self.entry_buffer[i];
self.entry_buffer[i] = entry.set_can_break_before(t);

View file

@ -4,8 +4,6 @@
extern mod harfbuzz;
use geom::Point2D;
use font::{Font, FontHandleMethods, FontTableMethods, FontTableTag};
use geometry::Au;
use platform::font::FontTable;
@ -14,45 +12,37 @@ use text::shaping::ShaperMethods;
use servo_util::range::Range;
use text::util::{float_to_fixed, fixed_to_float, fixed_to_rounded_int};
use core::cast::transmute;
use core::libc::{c_uint, c_int, c_void, c_char};
use core::ptr::null;
use core::util::ignore;
use std::cast::transmute;
use std::libc::{c_uint, c_int, c_void, c_char};
use std::ptr;
use std::ptr::null;
use std::str;
use std::uint;
use std::util::ignore;
use std::vec;
use geom::Point2D;
use harfbuzz::bindgen::{hb_blob_create, hb_face_create_for_tables};
use harfbuzz::bindgen::{hb_buffer_add_utf8, hb_shape};
use harfbuzz::bindgen::{hb_buffer_create};
use harfbuzz::bindgen::{hb_buffer_destroy, hb_buffer_add_utf8};
use harfbuzz::bindgen::{hb_buffer_get_glyph_infos};
use harfbuzz::bindgen::{hb_buffer_get_glyph_positions};
use harfbuzz::bindgen::{hb_buffer_get_glyph_positions};
use harfbuzz::bindgen::{hb_buffer_set_direction};
use harfbuzz::bindgen::{hb_buffer_set_direction};
use harfbuzz::bindgen::{hb_face_destroy, hb_font_create};
use harfbuzz::bindgen::{hb_face_destroy};
use harfbuzz::bindgen::{hb_font_create, hb_font_destroy};
use harfbuzz::bindgen::{hb_font_destroy, hb_buffer_create};
use harfbuzz::bindgen::{hb_font_funcs_create, hb_font_funcs_destroy};
use harfbuzz::bindgen::{hb_font_funcs_create};
use harfbuzz::bindgen::{hb_font_funcs_destroy};
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_blob_create, hb_face_create_for_tables};
use harfbuzz::{hb_buffer_add_utf8};
use harfbuzz::{hb_buffer_get_glyph_positions};
use harfbuzz::{hb_buffer_set_direction};
use harfbuzz::{hb_buffer_destroy};
use harfbuzz::{hb_face_destroy};
use harfbuzz::{hb_font_create};
use harfbuzz::{hb_font_destroy, hb_buffer_create};
use harfbuzz::{hb_font_funcs_create};
use harfbuzz::{hb_font_funcs_destroy};
use harfbuzz::{hb_font_funcs_set_glyph_func};
use harfbuzz::{hb_font_funcs_set_glyph_h_advance_func};
use harfbuzz::{hb_font_set_funcs};
use harfbuzz::{hb_font_set_ppem};
use harfbuzz::{hb_font_set_scale};
use harfbuzz::{hb_shape, hb_buffer_get_glyph_infos};
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_buffer_t, hb_codepoint_t, hb_bool_t};
use harfbuzz::{hb_blob_t};
use harfbuzz::{hb_bool_t};
use harfbuzz::{hb_face_t, hb_font_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_position_t, hb_glyph_info_t};
use harfbuzz::{hb_glyph_info_t};
use harfbuzz::{hb_glyph_position_t};
use harfbuzz::{hb_position_t, hb_tag_t};
@ -74,19 +64,21 @@ pub struct ShapedGlyphEntry {
impl ShapedGlyphData {
pub fn new(buffer: *hb_buffer_t) -> ShapedGlyphData {
let glyph_count = 0;
let glyph_infos = hb_buffer_get_glyph_infos(buffer, &glyph_count);
let glyph_count = glyph_count as uint;
assert!(glyph_infos.is_not_null());
let pos_count = 0;
let pos_infos = hb_buffer_get_glyph_positions(buffer, &pos_count);
assert!(pos_infos.is_not_null());
assert!(glyph_count == pos_count as uint);
unsafe {
let glyph_count = 0;
let glyph_infos = hb_buffer_get_glyph_infos(buffer, &glyph_count);
let glyph_count = glyph_count as uint;
assert!(glyph_infos.is_not_null());
let pos_count = 0;
let pos_infos = hb_buffer_get_glyph_positions(buffer, &pos_count);
assert!(pos_infos.is_not_null());
assert!(glyph_count == pos_count as uint);
ShapedGlyphData {
count: glyph_count,
glyph_infos: glyph_infos,
pos_infos: pos_infos,
ShapedGlyphData {
count: glyph_count,
glyph_infos: glyph_infos,
pos_infos: pos_infos,
}
}
}
@ -152,50 +144,54 @@ pub struct Shaper {
#[unsafe_destructor]
impl Drop for Shaper {
fn finalize(&self) {
assert!(self.hb_face.is_not_null());
hb_face_destroy(self.hb_face);
unsafe {
assert!(self.hb_face.is_not_null());
hb_face_destroy(self.hb_face);
assert!(self.hb_font.is_not_null());
hb_font_destroy(self.hb_font);
assert!(self.hb_font.is_not_null());
hb_font_destroy(self.hb_font);
assert!(self.hb_funcs.is_not_null());
hb_font_funcs_destroy(self.hb_funcs);
assert!(self.hb_funcs.is_not_null());
hb_font_funcs_destroy(self.hb_funcs);
}
}
}
impl Shaper {
pub fn new(font: @mut Font) -> Shaper {
// Indirection for Rust Issue #6248, dynamic freeze scope artifically extended
let font_ptr = {
let borrowed_font= &mut *font;
borrowed_font as *mut Font
};
let hb_face: *hb_face_t = hb_face_create_for_tables(get_font_table_func,
font_ptr as *c_void,
null());
let hb_font: *hb_font_t = hb_font_create(hb_face);
unsafe {
// Indirection for Rust Issue #6248, dynamic freeze scope artifically extended
let font_ptr = {
let borrowed_font= &mut *font;
borrowed_font as *mut Font
};
let hb_face: *hb_face_t = hb_face_create_for_tables(get_font_table_func,
font_ptr as *c_void,
null());
let hb_font: *hb_font_t = hb_font_create(hb_face);
// Set points-per-em. if zero, performs no hinting in that direction.
let pt_size = font.style.pt_size;
hb_font_set_ppem(hb_font, pt_size as c_uint, pt_size as c_uint);
// Set points-per-em. if zero, performs no hinting in that direction.
let pt_size = font.style.pt_size;
hb_font_set_ppem(hb_font, pt_size as c_uint, pt_size as c_uint);
// Set scaling. Note that this takes 16.16 fixed point.
hb_font_set_scale(hb_font,
Shaper::float_to_fixed(pt_size) as c_int,
Shaper::float_to_fixed(pt_size) as c_int);
// Set scaling. Note that this takes 16.16 fixed point.
hb_font_set_scale(hb_font,
Shaper::float_to_fixed(pt_size) as c_int,
Shaper::float_to_fixed(pt_size) as c_int);
// configure static function callbacks.
// NB. This funcs structure could be reused globally, as it never changes.
let hb_funcs: *hb_font_funcs_t = hb_font_funcs_create();
hb_font_funcs_set_glyph_func(hb_funcs, glyph_func, null(), null());
hb_font_funcs_set_glyph_h_advance_func(hb_funcs, glyph_h_advance_func, null(), null());
hb_font_set_funcs(hb_font, hb_funcs, font_ptr as *c_void, null());
// configure static function callbacks.
// NB. This funcs structure could be reused globally, as it never changes.
let hb_funcs: *hb_font_funcs_t = hb_font_funcs_create();
hb_font_funcs_set_glyph_func(hb_funcs, glyph_func, null(), null());
hb_font_funcs_set_glyph_h_advance_func(hb_funcs, glyph_h_advance_func, null(), null());
hb_font_set_funcs(hb_font, hb_funcs, font_ptr as *c_void, null());
Shaper {
font: font,
hb_face: hb_face,
hb_font: hb_font,
hb_funcs: hb_funcs,
Shaper {
font: font,
hb_face: hb_face,
hb_font: hb_font,
hb_funcs: hb_funcs,
}
}
}
@ -216,21 +212,23 @@ impl ShaperMethods for Shaper {
/// Calculate the layout metrics associated with the given text when rendered in a specific
/// font.
fn shape_text(&self, text: &str, glyphs: &mut GlyphStore) {
let hb_buffer: *hb_buffer_t = hb_buffer_create();
hb_buffer_set_direction(hb_buffer, HB_DIRECTION_LTR);
unsafe {
let hb_buffer: *hb_buffer_t = hb_buffer_create();
hb_buffer_set_direction(hb_buffer, HB_DIRECTION_LTR);
// Using as_buf because it never does a copy - we don't need the trailing null
do str::as_buf(text) |ctext: *u8, _: uint| {
hb_buffer_add_utf8(hb_buffer,
ctext as *c_char,
text.len() as c_int,
0,
text.len() as c_int);
// Using as_buf because it never does a copy - we don't need the trailing null
do str::as_buf(text) |ctext: *u8, _: uint| {
hb_buffer_add_utf8(hb_buffer,
ctext as *c_char,
text.len() as c_int,
0,
text.len() as c_int);
}
hb_shape(self.hb_font, hb_buffer, null(), 0);
self.save_glyph_results(text, glyphs, hb_buffer);
hb_buffer_destroy(hb_buffer);
}
hb_shape(self.hb_font, hb_buffer, null(), 0);
self.save_glyph_results(text, glyphs, hb_buffer);
hb_buffer_destroy(hb_buffer);
}
}
@ -239,7 +237,7 @@ impl Shaper {
let glyph_data = ShapedGlyphData::new(buffer);
let glyph_count = glyph_data.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.
// so, we must be careful to increment this when saving glyph entries.
@ -267,7 +265,7 @@ impl Shaper {
let mut i = 0;
while i < byte_max {
byteToGlyph[i] = NO_GLYPH;
let range = str::char_range_at(text, i);
let range = text.char_range_at(i);
ignore(range.ch);
i = range.next;
}
@ -292,7 +290,7 @@ impl Shaper {
debug!("(char idx): char->(glyph index):");
let mut i = 0u;
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);
i = range.next;
}
@ -318,7 +316,7 @@ impl Shaper {
// find a range of chars corresponding to this glyph, plus
// any trailing chars that do not have associated glyphs.
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);
char_byte_span.extend_to(range.next);
@ -329,7 +327,7 @@ impl Shaper {
byteToGlyph[char_byte_span.end()] == NO_GLYPH {
debug!("Extending char byte span to include byte offset=%u with no associated \
glyph", char_byte_span.end());
let range = str::char_range_at(text, char_byte_span.end());
let range = text.char_range_at(char_byte_span.end());
ignore(range.ch);
char_byte_span.extend_to(range.next);
}
@ -404,7 +402,7 @@ impl Shaper {
// extend, clipping at end of text range.
while covered_byte_span.end() < byte_max
&& 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);
covered_byte_span.extend_to(range.next);
}
@ -457,7 +455,7 @@ impl Shaper {
// set the other chars, who have no glyphs
let mut i = covered_byte_span.begin();
loop {
let range = str::char_range_at(text, i);
let range = text.char_range_at(i);
ignore(range.ch);
i = range.next;
if i >= covered_byte_span.end() { break; }

View file

@ -42,9 +42,9 @@ impl SendableTextRun {
}
}
pub impl<'self> TextRun {
fn new(font: @mut Font, text: ~str, underline: bool) -> TextRun {
let mut glyph_store = GlyphStore::new(str::char_len(text));
impl<'self> TextRun {
pub fn new(font: @mut Font, text: ~str, underline: bool) -> TextRun {
let mut glyph_store = GlyphStore::new(text.char_len());
TextRun::compute_potential_breaks(text, &mut glyph_store);
do profile(time::LayoutShapingCategory, font.profiler_chan.clone()) {
font.shape_text(text, &mut glyph_store);
@ -59,18 +59,18 @@ pub impl<'self> TextRun {
return run;
}
fn teardown(&self) {
pub fn teardown(&self) {
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.
let mut byte_i = 0u;
let mut char_j = 0u;
let mut prev_is_whitespace = false;
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 next = range.next;
// set char properties.
@ -114,10 +114,10 @@ pub impl<'self> TextRun {
}
}
fn char_len(&self) -> uint { self.glyphs.entry_buffer.len() }
fn glyphs(&'self self) -> &'self GlyphStore { &self.glyphs }
pub fn char_len(&self) -> uint { self.glyphs.entry_buffer.len() }
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| {
if !self.glyphs.char_is_space(i) &&
!self.glyphs.char_is_tab(i) &&
@ -126,11 +126,11 @@ pub impl<'self> TextRun {
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)
}
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);
debug!("iterating outer range %?", range);
for self.iter_indivisible_pieces_for_range(range) |piece_range| {
@ -141,7 +141,7 @@ pub impl<'self> TextRun {
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 in_clump = false;
@ -168,7 +168,7 @@ pub impl<'self> TextRun {
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);
loop {

View file

@ -38,7 +38,7 @@ pub fn transform_text(text: &str, mode: CompressionMode, incoming_whitespace: bo
let mut out_str: ~str = ~"";
let out_whitespace = match mode {
CompressNone | DiscardNewline => {
for str::each_char(text) |ch: char| {
for text.iter().advance |ch: char| {
if is_discardable_char(ch, mode) {
// TODO: record skipped char
} else {
@ -46,7 +46,7 @@ pub fn transform_text(text: &str, mode: CompressionMode, incoming_whitespace: bo
if ch == '\t' {
// 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)
@ -54,7 +54,7 @@ pub fn transform_text(text: &str, mode: CompressionMode, incoming_whitespace: bo
CompressWhitespace | CompressWhitespaceNewline => {
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
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
} else {
// 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 */
if in_whitespace {
// TODO: record skipped char
} else {
// TODO: record kept char
str::push_char(&mut out_str, ' ');
out_str.push_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::AzGLContext;
use core::cell::Cell;
use core::comm::{Chan, SharedChan, Port};
use core::num::Orderable;
use core::util;
use std::cell::Cell;
use std::comm;
use std::comm::{Chan, SharedChan, Port};
use std::num::Orderable;
use std::task;
use std::util;
use geom::matrix::identity;
use geom::point::Point2D;
use geom::size::Size2D;
@ -137,8 +139,8 @@ impl CompositorTask {
pub fn create(port: Port<Msg>,
profiler_chan: ProfilerChan,
shutdown_chan: Chan<()>) {
let port = Cell(port);
let shutdown_chan = Cell(shutdown_chan);
let port = Cell::new(port);
let shutdown_chan = Cell::new(shutdown_chan);
do on_osmain {
let compositor_task = CompositorTask::new(port.take(),
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.
let context = rendergl::init_render_context();
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;
// 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.
do window.set_resize_callback |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))));
}

View file

@ -4,7 +4,7 @@
use layout::aux::LayoutAuxMethods;
use core::cast::transmute;
use std::cast::transmute;
use newcss::complete::CompleteSelectResults;
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
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use std::net::url::Url;
use url_from_str = std::net::url::from_str;
use core::cell::Cell;
use extra::net::url::Url;
use url_from_str = extra::net::url::from_str;
use std::cell::Cell;
use std::result;
use std::str;
use newcss::stylesheet::Stylesheet;
use newcss::select::SelectCtx;
use newcss::types::OriginUA;
@ -32,7 +34,7 @@ fn default_url(name: &str) -> Url {
}
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() {
Some(style.take())
} else {

View file

@ -6,7 +6,8 @@
/// 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 script::dom::node::{AbstractNode, LayoutView};
@ -104,7 +105,7 @@ impl SelectHandler<AbstractNode<LayoutView>> for NodeSelectHandler {
None => false,
Some(existing_classes) => {
let mut ret = false;
for str::each_split_char(existing_classes, ' ') |s| {
for existing_classes.split_iter(' ').advance |s| {
if s == class {
ret = true;
break;

View file

@ -5,8 +5,10 @@
use compositing::{CompositorChan, SetLayoutChan, SetRenderChan};
use layout::layout_task;
use core::cell::Cell;
use core::comm::Port;
use std::cell::Cell;
use std::comm;
use std::comm::Port;
use std::task;
use gfx::opts::Opts;
use gfx::render_task::RenderChan;
use gfx::render_task;
@ -43,7 +45,7 @@ impl Engine {
($Msg:ty, $Chan:ident) => (
{
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 (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(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();

View file

@ -40,21 +40,20 @@ pub trait LayoutAuxMethods {
}
impl LayoutAuxMethods for AbstractNode<LayoutView> {
// FIXME (Rust #3080): These unsafe blocks are *not* unused!
pub fn layout_data(self) -> @mut LayoutData {
/*unsafe {*/
unsafe {
self.unsafe_layout_data()
/*}*/
}
}
pub fn has_layout_data(self) -> bool {
/*unsafe {*/
unsafe {
self.unsafe_has_layout_data()
/*}*/
}
}
pub fn set_layout_data(self, data: @mut LayoutData) {
/*unsafe {*/
unsafe {
self.unsafe_set_layout_data(data)
/*}*/
}
}
/// 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::float_context::FloatContext;
use core::cell::Cell;
use std::cell::Cell;
use geom::point::Point2D;
use geom::rect::Rect;
use gfx::display_list::DisplayList;
@ -51,7 +51,7 @@ impl BlockFlowData {
pub fn teardown(&mut self) {
self.common.teardown();
for self.box.each |box| {
for self.box.iter().advance |box| {
box.teardown();
}
self.box = None;
@ -192,7 +192,7 @@ impl BlockFlowData {
let mut remaining_width = self.common.position.size.width;
let mut x_offset = Au(0);
for self.box.each |&box| {
for self.box.iter().advance |&box| {
let style = box.style();
do box.with_model |model| {
// Can compute padding here since we know containing block width.
@ -251,7 +251,7 @@ impl BlockFlowData {
let mut top_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| {
top_offset = model.margin.top + model.border.top + model.padding.top;
cur_y += top_offset;

View file

@ -11,10 +11,11 @@ use layout::flow::FlowContext;
use layout::model::{BoxModel, MaybeAuto};
use layout::text;
use core::cell::Cell;
use core::cmp::ApproxEq;
use core::managed;
use core::num::Zero;
use std::cell::Cell;
use std::cmp::ApproxEq;
use std::managed;
use std::num::Zero;
use std::uint;
use geom::{Point2D, Rect, Size2D};
use gfx::display_list::{BaseDisplayItem, BorderDisplayItem, BorderDisplayItemClass};
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::local_image_cache::LocalImageCache;
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
/// 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.
#[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 {
GenericRenderBoxClass(generic_box) => callback(generic_box),
ImageRenderBoxClass(image_box) => {
@ -198,7 +199,7 @@ pub impl RenderBox {
/// Borrows this render box mutably in order to work with its common data.
#[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 {
GenericRenderBoxClass(generic_box) => callback(generic_box),
ImageRenderBoxClass(image_box) => {
@ -214,14 +215,14 @@ pub impl RenderBox {
}
/// 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| {
base.position
}
}
/// 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| {
base.id
}
@ -229,7 +230,7 @@ pub impl RenderBox {
/// Returns true if this element is replaced content. This is true for images, form elements,
/// and so on.
fn is_replaced(&self) -> bool {
pub fn is_replaced(&self) -> bool {
match *self {
ImageRenderBoxClass(*) => true,
_ => false
@ -237,7 +238,7 @@ pub impl RenderBox {
}
/// 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 {
TextRenderBoxClass(*) => true,
_ => false
@ -245,7 +246,7 @@ pub impl RenderBox {
}
/// 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 {
UnscannedTextRenderBoxClass(unscanned_text_box) => {
unscanned_text_box.text.is_whitespace()
@ -255,7 +256,7 @@ pub impl RenderBox {
}
/// 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) {
(&UnscannedTextRenderBoxClass(*), &UnscannedTextRenderBoxClass(*)) => {
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
/// 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 {
match *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.
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
// 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.
fn get_pref_width(&self, _: &LayoutContext) -> Au {
pub fn get_pref_width(&self, _: &LayoutContext) -> Au {
self.guess_width() + match *self {
// 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
@ -451,7 +452,7 @@ pub impl RenderBox {
let mut line_width: Au = Au(0);
for text_box.run.glyphs.iter_glyphs_for_char_range(line_range)
|_, glyph| {
line_width += glyph.advance()
line_width += glyph.advance_()
}
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,
/// 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.
(Au(0), Au(0))
}
/// Returns the amount of left and right "fringe" used by this box. This should be based on
/// 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.
(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| {
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| {
base.model.border.left + base.model.padding.left +
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| {
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 owning flow.
fn content_box(&self) -> Rect<Au> {
pub fn content_box(&self) -> Rect<Au> {
do self.with_base |base| {
let origin = Point2D(base.position.origin.x +
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 owning flow.
fn border_box(&self) -> Rect<Au> {
pub fn border_box(&self) -> Rect<Au> {
// TODO: Actually compute the content box, padding, and border.
self.content_box()
}
/// The box formed by the margin edge as defined in CSS 2.1 § 8.1. Coordinates are relative to
/// 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.
self.content_box()
}
/// A convenience function to access the computed style of the DOM node that this render box
/// represents.
fn style(&self) -> CompleteStyle {
pub fn style(&self) -> CompleteStyle {
self.with_base(|base| base.node.style())
}
/// 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)
}
@ -540,7 +541,7 @@ pub impl RenderBox {
/// represents.
///
/// 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| {
let mut node = base.node;
while !node.is_element() {
@ -571,7 +572,7 @@ pub impl RenderBox {
/// 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
/// Appendix E. Finally, the builder flattens the list.
fn build_display_list<E:ExtraDisplayListData>(&self,
pub fn build_display_list<E:ExtraDisplayListData>(&self,
_: &DisplayListBuilder,
dirty: &Rect<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
/// list if necessary.
fn paint_background_if_applicable<E:ExtraDisplayListData>(&self,
pub fn paint_background_if_applicable<E:ExtraDisplayListData>(&self,
list: &Cell<DisplayList<E>>,
absolute_bounds: &Rect<Au>) {
// 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.
fn font_style(&self) -> FontStyle {
pub fn font_style(&self) -> FontStyle {
let my_style = self.nearest_ancestor_element().style();
debug!("(font style) start: %?", self.nearest_ancestor_element().type_id());
@ -757,7 +758,7 @@ pub impl RenderBox {
CSSFontFamilyGenericFamily(Monospace) => ~"monospace",
}
};
let font_families = str::connect(font_families, ~", ");
let font_families = font_families.connect(", ");
debug!("(font style) font families: `%s`", font_families);
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`
/// node.
fn text_align(&self) -> CSSTextAlign {
pub fn text_align(&self) -> CSSTextAlign {
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
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
/// TODO: make sure this works with anonymous box generation.
fn get_propagated_text_decoration(element: AbstractNode<LayoutView>) -> CSSTextDecoration {
@ -856,9 +857,10 @@ pub impl RenderBox {
GenericRenderBoxClass(*) => ~"GenericRenderBox",
ImageRenderBoxClass(*) => ~"ImageRenderBox",
TextRenderBoxClass(text_box) => {
fmt!("TextRenderBox(text=%s)", str::substr(text_box.run.text,
text_box.range.begin(),
text_box.range.length()))
fmt!("TextRenderBox(text=%s)",
text_box.run.text.slice(
text_box.range.begin(),
text_box.range.begin() + text_box.range.length()))
}
UnscannedTextRenderBoxClass(text_box) => {
fmt!("UnscannedTextRenderBox(%s)", text_box.text)

View file

@ -36,8 +36,8 @@ pub struct LayoutTreeBuilder {
next_bid: int,
}
pub impl LayoutTreeBuilder {
fn new() -> LayoutTreeBuilder {
impl LayoutTreeBuilder {
pub fn new() -> LayoutTreeBuilder {
LayoutTreeBuilder {
root_flow: None,
next_cid: -1,
@ -142,7 +142,8 @@ impl BoxGenerator {
inline.boxes.push(new_box);
} else if self.inline_spacers_needed_for_node(node) {
// 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| {
inline.boxes.push(*spacer);
}
@ -190,7 +191,7 @@ impl BoxGenerator {
// If this non-leaf box generates extra horizontal spacing, add a SpacerBox for
// it.
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;
boxes.push(*spacer);
}
@ -269,14 +270,14 @@ impl BoxGenerator {
}
pub impl LayoutTreeBuilder {
impl LayoutTreeBuilder {
/* Debug-only ids */
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_flow_id(&mut self) -> int { self.next_cid += 1; self.next_cid }
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,
/// and recurses on its children.
fn construct_recursively(&mut self,
pub fn construct_recursively(&mut self,
layout_ctx: &LayoutContext,
cur_node: AbstractNode<LayoutView>,
parent_generator: @mut BoxGenerator,
@ -319,7 +320,7 @@ pub impl LayoutTreeBuilder {
Some(this_generator)
}
fn box_generator_for_node(&mut self,
pub fn box_generator_for_node(&mut self,
node: AbstractNode<LayoutView>,
parent_generator: @mut BoxGenerator,
sibling_generator: Option<@mut BoxGenerator>)
@ -433,7 +434,7 @@ pub impl LayoutTreeBuilder {
Some(new_generator)
}
fn create_child_generator(&mut self,
pub fn create_child_generator(&mut self,
node: AbstractNode<LayoutView>,
parent_generator: @mut BoxGenerator,
ty: FlowContextType)
@ -445,7 +446,7 @@ pub impl LayoutTreeBuilder {
@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>,
parent_generator: @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
/// 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 {
InlineFlow(*) => {
let mut found_child_inline = false;
@ -493,7 +494,7 @@ pub impl LayoutTreeBuilder {
let first_child = do parent_flow.with_base |parent_node| {
parent_node.first_child
};
for first_child.each |&first_flow| {
for first_child.iter().advance |&first_flow| {
if first_flow.starts_inline_flow() {
// FIXME: workaround for rust#6393
let mut do_remove = false;
@ -516,7 +517,7 @@ pub impl LayoutTreeBuilder {
let last_child = do parent_flow.with_base |parent_node| {
parent_node.last_child
};
for last_child.each |&last_flow| {
for last_child.iter().advance |&last_flow| {
if last_flow.starts_inline_flow() {
// FIXME: workaround for rust#6393
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.
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.
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, ()> {
let new_flow = self.make_flow(Flow_Root, root);
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.
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 result = match ty {
Flow_Absolute => AbsoluteFlow(@mut info),

View file

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

View file

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

View file

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

View file

@ -2,8 +2,8 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use core::cell::Cell;
use core;
use std::cell::Cell;
use std;
use layout::box::{CannotSplit, GenericRenderBoxClass, ImageRenderBoxClass, RenderBox};
use layout::box::{SplitDidFit, SplitDidNotFit, TextRenderBoxClass, UnscannedTextRenderBoxClass};
use layout::context::LayoutContext;
@ -12,7 +12,10 @@ use layout::flow::{FlowContext, FlowData, InlineFlow};
use layout::text::{UnscannedMethods, adapt_textbox_with_range};
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 gfx::display_list::DisplayList;
use gfx::geometry::Au;
@ -25,8 +28,8 @@ use newcss::units::{Em, Px, Pt};
use newcss::values::{CSSLineHeightNormal, CSSLineHeightNumber, CSSLineHeightLength, CSSLineHeightPercentage};
use servo_util::range::Range;
use std::deque::Deque;
use servo_util::tree::{TreeNodeRef, TreeUtils};
use extra::deque::Deque;
/*
Lineboxes are represented as offsets into the child list, rather than
@ -55,8 +58,8 @@ pub struct NodeRange {
range: Range,
}
pub impl NodeRange {
fn new(node: AbstractNode<LayoutView>, range: &Range) -> NodeRange {
impl NodeRange {
pub fn new(node: AbstractNode<LayoutView>, range: &Range) -> NodeRange {
NodeRange { node: node, range: copy *range }
}
}
@ -326,9 +329,9 @@ impl TextRunScanner {
let mut new_ranges: ~[Range] = ~[];
let mut char_total = 0;
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));
str::push_str(&mut run_str, transformed_strs[i]);
run_str.push_str(transformed_strs[i]);
char_total += added_chars;
}
@ -415,7 +418,7 @@ impl LineboxScanner {
flow: inline,
new_boxes: ~[],
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: ~[],
}
}
@ -637,7 +640,7 @@ impl LineboxScanner {
debug!("LineboxScanner: Pushing box b%d to line %u", box.id(), self.line_spans.len());
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.extend_by(1);

View file

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

View file

@ -7,8 +7,8 @@
use layout::display_list_builder::{ExtraDisplayListData, ToGfxColor};
use layout::box::RenderBox;
use core::cell::Cell;
use core::num::Zero;
use std::cell::Cell;
use std::num::Zero;
use geom::point::Point2D;
use geom::rect::Rect;
use geom::size::Size2D;
@ -172,7 +172,8 @@ impl RenderBox {
// Are all the widths equal?
//
// 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 bounds = Rect {
origin: Point2D {

View file

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

View file

@ -27,7 +27,7 @@ extern mod servo_msg (name = "msg");
extern mod servo_util (name = "util");
extern mod sharegl;
extern mod stb_image;
extern mod std;
extern mod extra;
#[cfg(target_os="macos")]
extern mod core_graphics;
@ -42,11 +42,13 @@ use gfx::opts;
use servo_net::image_cache_task::ImageCacheTask;
use servo_net::resource_task::ResourceTask;
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::text;
pub use servo_util::url::make_url;
use std::comm;
use std::os;
#[path="compositing/mod.rs"]
pub mod compositing;
@ -102,7 +104,7 @@ fn run(opts: &Opts) {
let period = *period;
do spawn {
loop {
std::timer::sleep(&uv_global_loop::get(),
extra::timer::sleep(&uv_global_loop::get(),
(period * 1000f64) as uint);
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
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use core::cell::Cell;
use core::comm::{Chan, Port};
use core::task;
use std::cell::Cell;
use std::comm;
use std::comm::{Chan, Port};
use std::task;
pub fn spawn_listener<A: Owned>(f: ~fn(Port<A>)) -> Chan<A> {
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>) {
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| {
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
/// coupling between these two components
use core::comm::{Chan, SharedChan};
use std::net::url::Url;
use std::comm::{Chan, SharedChan};
use extra::net::url::Url;
#[deriving(Clone)]
pub struct EngineChan {

View file

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

View file

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

View file

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

View file

@ -2,6 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use std::vec;
use stb_image = stb_image::image;
// 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 local_image_cache::LocalImageCache;
use core::util::replace;
use std::util::replace;
use geom::size::Size2D;
use std::net::url::Url;
use std::arc::{ARC, clone, get};
use extra::net::url::Url;
use extra::arc::ARC;
// 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
@ -24,7 +24,7 @@ pub struct ImageHolder {
local_image_cache: @mut LocalImageCache,
}
pub impl ImageHolder {
impl ImageHolder {
pub fn new(url: Url, local_image_cache: @mut LocalImageCache) -> ImageHolder {
debug!("ImageHolder::new() %?", url.to_str());
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
/// computing layout.
fn size(&self) -> Size2D<int> {
pub fn size(&self) -> Size2D<int> {
self.cached_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);
match self.get_image() {
Some(img) => {
let img_ref = get(&img);
let img_ref = img.get();
self.cached_size = Size2D(img_ref.width as int,
img_ref.height as int);
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);
// 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 result = match image {
Some(ref image) => Some(clone(image)),
Some(ref image) => Some(image.clone()),
None => None
};

View file

@ -7,14 +7,14 @@ use resource_task;
use resource_task::ResourceTask;
use servo_util::url::{UrlMap, url_map};
use clone_arc = std::arc::clone;
use core::cell::Cell;
use core::comm::{Chan, Port, SharedChan, stream};
use core::task::spawn;
use core::to_str::ToStr;
use core::util::replace;
use std::arc::ARC;
use std::net::url::Url;
use std::cell::Cell;
use std::comm::{Chan, Port, SharedChan, stream};
use std::task::spawn;
use std::to_str::ToStr;
use std::util::replace;
use std::result;
use extra::arc::ARC;
use extra::net::url::Url;
pub enum Msg {
/// Tell the cache that we may need a particular image soon. Must be posted
@ -54,7 +54,7 @@ pub enum ImageResponseMsg {
impl ImageResponseMsg {
fn clone(&self) -> ImageResponseMsg {
match *self {
ImageReady(ref img) => ImageReady(clone_arc(img)),
ImageReady(ref img) => ImageReady(img.clone()),
ImageNotReady => ImageNotReady,
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
// version of which contains an uncopyable type which rust will currently
// copy unsoundly
let decoder_factory_cell = Cell(decoder_factory);
let decoder_factory_cell = Cell::new(decoder_factory);
let (port, chan) = stream();
let chan = SharedChan::new(chan);
let port_cell = Cell(port);
let chan_cell = Cell(chan.clone());
let port_cell = Cell::new(port);
let chan_cell = Cell::new(chan.clone());
do spawn {
let mut cache = ImageCache {
@ -116,7 +116,7 @@ pub fn ImageCacheTask_(resource_task: ResourceTask, decoder_factory: DecoderFact
fn SyncImageCacheTask(resource_task: ResourceTask) -> ImageCacheTask {
let (port, chan) = stream();
let port_cell = Cell(port);
let port_cell = Cell::new(port);
do spawn {
let port = port_cell.take();
@ -247,7 +247,7 @@ impl ImageCache {
Init => {
let to_cache = self.chan.clone();
let resource_task = self.resource_task.clone();
let url_cell = Cell(copy url);
let url_cell = Cell::new(copy url);
do spawn {
let url = url_cell.take();
@ -256,7 +256,7 @@ impl ImageCache {
let image = load_image_data(copy url, resource_task.clone());
let result = if image.is_ok() {
Ok(Cell(result::unwrap(image)))
Ok(Cell::new(result::unwrap(image)))
} else {
Err(())
};
@ -279,7 +279,7 @@ impl ImageCache {
match data {
Ok(data_cell) => {
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 {
DoDecode => self.decode(url),
_ => ()
@ -320,7 +320,7 @@ impl ImageCache {
let data = data_cell.take();
let to_cache = self.chan.clone();
let url_cell = Cell(copy url);
let url_cell = Cell::new(copy url);
let decode = (self.decoder_factory)();
do spawn {
@ -351,8 +351,8 @@ impl ImageCache {
Decoding => {
match image {
Some(image) => {
self.set_state(copy url, Decoded(@clone_arc(&image)));
self.purge_waiters(url, || ImageReady(clone_arc(&image)) );
self.set_state(copy url, Decoded(@image.clone()));
self.purge_waiters(url, || ImageReady(image.clone()) );
}
None => {
self.set_state(copy url, Failed);
@ -389,7 +389,7 @@ impl ImageCache {
Prefetching(DoDecode) => response.send(ImageNotReady),
Prefetching(DoNotDecode) | Prefetched(*) => fail!(~"request for image before decode"),
Decoding => response.send(ImageNotReady),
Decoded(image) => response.send(ImageReady(clone_arc(image))),
Decoded(image) => response.send(ImageReady((*image).clone())),
Failed => response.send(ImageFailed),
}
}
@ -411,7 +411,7 @@ impl ImageCache {
}
Decoded(image) => {
response.send(ImageReady(clone_arc(image)));
response.send(ImageReady((*image).clone()));
}
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::{ImageResponseMsg, Prefetch, WaitForImage};
use clone_arc = std::arc::clone;
use core::comm::Port;
use std::comm;
use std::comm::Port;
use std::task;
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 {
LocalImageCache {
image_cache_task: image_cache_task,
round_number: 1,
mut on_image_available: None,
on_image_available: None,
state_map: url_map()
}
}
@ -40,7 +41,7 @@ priv struct ImageState {
}
#[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
/// URL in each 'round'. Layout should call this each time it begins
pub fn next_round(&mut self, on_image_available: @fn() -> ~fn(ImageResponseMsg)) {
@ -76,7 +77,7 @@ pub impl LocalImageCache {
match state.last_response {
ImageReady(ref image) => {
let (port, chan) = comm::stream();
chan.send(ImageReady(clone_arc(image)));
chan.send(ImageReady(image.clone()));
return port;
}
ImageNotReady => {
@ -122,7 +123,7 @@ pub impl LocalImageCache {
// Put a copy of the response in the cache
let response_copy = match response {
ImageReady(ref image) => ImageReady(clone_arc(image)),
ImageReady(ref image) => ImageReady(image.clone()),
ImageNotReady => ImageNotReady,
ImageFailed => ImageFailed
};

View file

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

View file

@ -7,9 +7,9 @@
use file_loader;
use http_loader;
use core::cell::Cell;
use core::comm::{Chan, Port, SharedChan};
use std::net::url::{Url, to_str};
use std::cell::Cell;
use std::comm::{Chan, Port, SharedChan};
use extra::net::url::{Url, to_str};
use util::spawn_listener;
pub enum ControlMsg {
@ -52,7 +52,7 @@ pub fn ResourceTask() -> 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| {
// TODO: change copy to move once we can move out of closures
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
* 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> {
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 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) {
let script_context = global_script_context();
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};
pub impl ClientRectList {
fn init_wrapper(@mut self) {
use std::cast;
impl ClientRectList {
pub fn init_wrapper(@mut self) {
let script_context = global_script_context();
let cx = script_context.js_compartment.cx.ptr;
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,
extendedAttributes, descriptorProvider, nativeMethodName,
static, object="self", declareResult=True):
static, object="this", declareResult=True):
CGThing.__init__(self)
assert errorReport is None or isinstance(errorReport, CGThing)
@ -3070,7 +3070,7 @@ class CGAbstractBindingMethod(CGAbstractExternMethod):
unwrapThis = CGIndenter(CGGeneric(
str(CastableObjectUnwrapper(
FakeCastableDescriptor(self.descriptor),
"obj", "self", self.unwrapFailureCode))))
"obj", "this", self.unwrapFailureCode))))
return CGList([ self.getThis(), unwrapThis,
self.generate_code() ], "\n").define()
@ -3081,7 +3081,7 @@ class CGAbstractBindingMethod(CGAbstractExternMethod):
" return false as JSBool;\n"
"}\n"
"\n"
"let self: *rust_box<%s>;" % self.descriptor.nativeType))
"let this: *rust_box<%s>;" % self.descriptor.nativeType))
def generate_code(self):
assert(False) # Override me
@ -3098,7 +3098,7 @@ class CGGenericMethod(CGAbstractBindingMethod):
def generate_code(self):
return CGIndenter(CGGeneric(
"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):
"""
@ -3121,7 +3121,7 @@ class CGSpecializedMethod(CGAbstractExternMethod):
self.method = method
name = method.identifier.name
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')]
CGAbstractExternMethod.__init__(self, descriptor, name, 'JSBool', args)
@ -3154,7 +3154,7 @@ class CGGenericGetter(CGAbstractBindingMethod):
def generate_code(self):
return CGIndenter(CGGeneric(
"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):
"""
@ -3166,7 +3166,7 @@ class CGSpecializedGetter(CGAbstractExternMethod):
name = 'get_' + attr.identifier.name
args = [ Argument('*JSContext', 'cx'),
Argument('JSHandleObject', 'obj'),
Argument('*%s' % descriptor.nativeType, 'self'),
Argument('*%s' % descriptor.nativeType, 'this'),
Argument('*mut JSVal', 'vp') ]
CGAbstractExternMethod.__init__(self, descriptor, name, "JSBool", args)
@ -3466,7 +3466,7 @@ if expando.is_not_null() {
getIndexedOrExpando = ("let index = GetArrayIndexFromId(cx, id);\n" +
"if index.is_some() {\n" +
" let index = index.get();\n" +
" let self = UnwrapProxy(proxy);\n" +
" let this = UnwrapProxy(proxy);\n" +
CGIndenter(CGProxyIndexedGetter(self.descriptor, templateValues)).define())
getIndexedOrExpando += """
// 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" +
" }\n" +
"\n" +
" let self = UnwrapProxy(proxy);\n" +
" let this = UnwrapProxy(proxy);\n" +
CGIndenter(CGProxyNamedGetter(self.descriptor, templateValues)).define() +
"}\n") % (self.descriptor.nativeType)
else:
@ -3558,7 +3558,7 @@ class CGAbstractClassHook(CGAbstractExternMethod):
def definition_body_prologue(self):
return "" #XXXjdm we may want to do a proper unwrap here
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)
def definition_body(self):
@ -3570,8 +3570,8 @@ class CGAbstractClassHook(CGAbstractExternMethod):
def finalizeHook(descriptor, hookName, context):
if descriptor.customFinalize:
return """if (self) {
self->%s(%s);
return """if (this) {
this->%s(%s);
}""" % (hookName, context)
#clearWrapper = "ClearWrapper(self, self);\n" if descriptor.wrapperCache else ""
if descriptor.workers:
@ -4132,9 +4132,7 @@ class CGBindingRoot(CGThing):
dictionaries,
['js::*',
'js::jsapi::*',
'js::jsapi::bindgen::*',
'js::jsfriendapi::bindgen::*',
'js::glue::bindgen::*',
'js::glue::*',
'dom::node::AbstractNode', #XXXjdm
'dom::document::Document', #XXXjdm
@ -4150,6 +4148,11 @@ class CGBindingRoot(CGThing):
'script_task::task_from_context',
'dom::bindings::utils::EnumEntry',
'dom::node::ScriptView',
'std::cast',
'std::libc',
'std::ptr',
'std::vec',
'std::str'
],
[],
curr)

View file

@ -4,7 +4,7 @@
use js::jsapi::JSVal;
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 {
fn to_jsval(&self) -> JSVal;
@ -13,11 +13,15 @@ pub trait JSValConvertible {
impl JSValConvertible for u32 {
fn to_jsval(&self) -> JSVal {
RUST_UINT_TO_JSVAL(*self)
unsafe {
RUST_UINT_TO_JSVAL(*self)
}
}
fn from_jsval(val: JSVal) -> Option<u32> {
Some(RUST_JSVAL_TO_INT(val) as u32)
unsafe {
Some(RUST_JSVAL_TO_INT(val) as u32)
}
}
}

View file

@ -2,16 +2,21 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use std::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::{WrapperCache, DerivedWrapper};
use dom::bindings::utils::{jsval_to_str, WrapNewBindingObject, CacheableWrapper};
use dom::bindings::utils;
use dom::document::Document;
use dom::htmlcollection::HTMLCollection;
use js::glue::bindgen::*;
use js::glue::*;
use js::glue::{PROPERTY_STUB, STRICT_PROPERTY_STUB};
use js::jsapi::bindgen::{JS_DefineProperties};
use js::jsapi::bindgen::{JS_GetReservedSlot, JS_SetReservedSlot, JS_DefineFunctions};
use js::jsapi::{JS_DefineProperties};
use js::jsapi::{JS_GetReservedSlot, JS_SetReservedSlot, JS_DefineFunctions};
use js::jsapi::{JSContext, JSVal, JSObject, JSBool, JSFreeOp, JSPropertySpec, JSPropertyOpWrapper};
use js::jsapi::{JSStrictPropertyOpWrapper, JSNativeWrapper, JSFunctionSpec};
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 script_task::task_from_context;
use core::libc::c_uint;
use core::ptr::null;
use std::libc::c_uint;
use std::ptr::null;
extern fn getDocumentElement(cx: *JSContext, _argc: c_uint, vp: *mut JSVal) -> JSBool {
unsafe {
@ -96,9 +101,11 @@ pub fn init(compartment: @mut Compartment) {
flags: (JSPROP_SHARED | JSPROP_ENUMERATE | JSPROP_NATIVE_ACCESSORS) as u8,
getter: JSPropertyOpWrapper {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| {
assert!(JS_DefineProperties(compartment.cx.ptr, obj.ptr, specs) == 1);
unsafe {
assert!(JS_DefineProperties(compartment.cx.ptr, obj.ptr, specs) == 1);
}
});
let methods = @~[JSFunctionSpec {name: compartment.add_name(~"getElementsByTagName"),
@ -112,7 +119,9 @@ pub fn init(compartment: @mut Compartment) {
flags: 0,
selfHostedName: null()}];
vec::as_imm_buf(*methods, |fns, _len| {
JS_DefineFunctions(compartment.cx.ptr, obj.ptr, fns);
unsafe {
JS_DefineFunctions(compartment.cx.ptr, obj.ptr, fns);
}
});
compartment.register_class(utils::instance_jsclass(~"DocumentInstance",
@ -129,12 +138,12 @@ pub fn create(compartment: @mut Compartment, doc: @mut Document) -> *JSObject {
unsafe {
let raw_ptr: *libc::c_void = cast::transmute(squirrel_away(doc));
JS_SetReservedSlot(instance.ptr, 0, RUST_PRIVATE_TO_JSVAL(raw_ptr));
}
compartment.define_property(~"document", RUST_OBJECT_TO_JSVAL(instance.ptr),
GetJSClassHookStubPointer(PROPERTY_STUB) as *u8,
GetJSClassHookStubPointer(STRICT_PROPERTY_STUB) as *u8,
JSPROP_ENUMERATE);
compartment.define_property(~"document", RUST_OBJECT_TO_JSVAL(instance.ptr),
GetJSClassHookStubPointer(PROPERTY_STUB) as *u8,
GetJSClassHookStubPointer(STRICT_PROPERTY_STUB) as *u8,
JSPROP_ENUMERATE);
}
instance.ptr
}

View file

@ -8,7 +8,9 @@ use dom::bindings::utils::{BindingObject, DerivedWrapper};
use dom::domparser::DOMParser;
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 {
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 super::utils;
use core::libc::c_uint;
use core::ptr::null;
use js::glue::bindgen::*;
use js::jsapi::bindgen::*;
use std::cast;
use std::i32;
use std::libc;
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::{JSNativeWrapper, JSTracer, JSTRACE_OBJECT};
use js::jsapi::{JSPropertyOpWrapper, JSStrictPropertyOpWrapper, JSFunctionSpec};
@ -78,7 +85,9 @@ pub fn init(compartment: @mut Compartment) {
setter: JSStrictPropertyOpWrapper {op: null(), info: null()}}];
vec::push(&mut compartment.global_props, attrs);
vec::as_imm_buf(*attrs, |specs, _len| {
JS_DefineProperties(compartment.cx.ptr, obj.ptr, specs);
unsafe {
JS_DefineProperties(compartment.cx.ptr, obj.ptr, specs);
}
});
let methods = @~[JSFunctionSpec {name: compartment.add_name(~"getClientRects"),
@ -102,7 +111,9 @@ pub fn init(compartment: @mut Compartment) {
flags: 0,
selfHostedName: null()}];
vec::as_imm_buf(*methods, |fns, _len| {
JS_DefineFunctions(compartment.cx.ptr, obj.ptr, fns);
unsafe {
JS_DefineFunctions(compartment.cx.ptr, obj.ptr, fns);
}
});
compartment.register_class(utils::instance_jsclass(~"GenericElementInstance",
@ -127,7 +138,9 @@ pub fn init(compartment: @mut Compartment) {
setter: JSStrictPropertyOpWrapper {op: null(), info: null()}}];
vec::push(&mut compartment.global_props, attrs);
vec::as_imm_buf(*attrs, |specs, _len| {
JS_DefineProperties(compartment.cx.ptr, obj.ptr, specs);
unsafe {
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());
cache.set_wrapper(obj.ptr);
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));
unsafe {
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));
}
return obj;
}

View file

@ -2,15 +2,16 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use std::cast;
use dom::bindings::codegen::EventBinding;
use dom::bindings::utils::{CacheableWrapper, WrapperCache, BindingObject, DerivedWrapper};
use dom::event::Event_;
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};
pub impl Event_ {
impl Event_ {
pub fn init_wrapper(@mut self) {
let script_context = global_script_context();
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
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use std::cast;
use dom::bindings::codegen::EventTargetBinding;
use dom::bindings::utils::{CacheableWrapper, WrapperCache, BindingObject, DerivedWrapper};
use dom::eventtarget::EventTarget;
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};
pub impl EventTarget {
impl EventTarget {
pub fn init_wrapper(@mut self) {
let script_context = global_script_context();
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};
pub impl HTMLCollection {
fn init_wrapper(@mut self) {
use std::cast;
impl HTMLCollection {
pub fn init_wrapper(@mut self) {
let script_context = global_script_context();
let cx = script_context.js_compartment.cx.ptr;
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::{DoctypeNodeTypeId, ScriptView};
use core::libc::c_uint;
use core::ptr::null;
use js::jsapi::bindgen::*;
use std::cast;
use std::libc::c_uint;
use std::ptr;
use std::ptr::null;
use std::vec;
use js::jsapi::*;
use js::jsapi::{JSContext, JSVal, JSObject, JSBool, JSPropertySpec};
use js::jsapi::{JSPropertyOpWrapper, JSStrictPropertyOpWrapper};
use js::jsval::{INT_TO_JSVAL};
@ -53,7 +56,9 @@ pub fn init(compartment: @mut Compartment) {
setter: JSStrictPropertyOpWrapper {op: null(), info: null()}}];
vec::push(&mut compartment.global_props, attrs);
vec::as_imm_buf(*attrs, |specs, _len| {
JS_DefineProperties(compartment.cx.ptr, obj.ptr, specs);
unsafe {
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/. */
use js::jsapi::{JSContext, jsid, JSPropertyDescriptor, JSObject, JSString, jschar};
use js::jsapi::bindgen::{JS_GetPropertyDescriptorById, JS_NewUCString, JS_malloc, JS_free};
use js::glue::bindgen::{RUST_JSVAL_IS_VOID, RUST_JSVAL_TO_OBJECT, GetProxyExtra};
use js::glue::bindgen::{GetObjectProto};
use js::jsapi::{JS_GetPropertyDescriptorById, JS_NewUCString, JS_malloc, JS_free};
use js::glue::{RUST_JSVAL_IS_VOID, RUST_JSVAL_TO_OBJECT, GetProxyExtra};
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;
@ -68,7 +72,7 @@ pub fn _obj_toString(cx: *JSContext, className: *libc::c_char) -> *JSString {
}
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(nchars) = 0;

View file

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

View file

@ -6,20 +6,26 @@ use dom::bindings::node;
use dom::node::{AbstractNode, ScriptView};
use script_task::task_from_context;
use core::cast;
use core::hashmap::HashMap;
use core::ptr::{null, to_unsafe_ptr};
use js::glue::bindgen::*;
use js::glue::bindgen::{DefineFunctionWithReserved, GetObjectJSClass, RUST_OBJECT_TO_JSVAL};
use std::cast;
use std::hashmap::HashMap;
use std::libc;
use std::ptr;
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::jsapi::bindgen::{JS_AlreadyHasOwnProperty, JS_NewObject, JS_NewFunction};
use js::jsapi::bindgen::{JS_DefineProperties, JS_WrapValue, JS_ForwardGetPropertyTo};
use js::jsapi::bindgen::{JS_EncodeString, JS_free, JS_GetStringCharsAndLength};
use js::jsapi::bindgen::{JS_GetClass, JS_GetPrototype, JS_LinkConstructorAndPrototype};
use js::jsapi::bindgen::{JS_GetFunctionPrototype, JS_InternString, JS_GetFunctionObject};
use js::jsapi::bindgen::{JS_HasPropertyById, JS_GetPrototype, JS_GetGlobalForObject};
use js::jsapi::bindgen::{JS_NewStringCopyN, JS_DefineFunctions, JS_DefineProperty};
use js::jsapi::bindgen::{JS_ValueToString, JS_GetReservedSlot, JS_SetReservedSlot};
use js::jsapi::{JS_AlreadyHasOwnProperty, JS_NewObject, JS_NewFunction};
use js::jsapi::{JS_DefineProperties, JS_WrapValue, JS_ForwardGetPropertyTo};
use js::jsapi::{JS_EncodeString, JS_free, JS_GetStringCharsAndLength};
use js::jsapi::{JS_GetClass, JS_GetPrototype, JS_LinkConstructorAndPrototype};
use js::jsapi::{JS_GetFunctionPrototype, JS_InternString, JS_GetFunctionObject};
use js::jsapi::{JS_HasPropertyById, JS_GetPrototype, JS_GetGlobalForObject};
use js::jsapi::{JS_NewStringCopyN, JS_DefineFunctions, JS_DefineProperty};
use js::jsapi::{JS_ValueToString, JS_GetReservedSlot, JS_SetReservedSlot};
use js::jsapi::{JSContext, JSVal, JSObject, JSBool, jsid, JSClass, JSNative};
use js::jsapi::{JSFunctionSpec, JSPropertySpec, JSVal, JSPropertyDescriptor};
use js::jsfriendapi::bindgen::JS_NewObjectWithUniqueType;
@ -88,8 +94,8 @@ pub enum DOMString {
null_string
}
pub impl DOMString {
fn to_str(&self) -> ~str {
impl DOMString {
pub fn to_str(&self) -> ~str {
match *self {
str(ref s) => s.clone(),
null_string => ~""
@ -129,17 +135,17 @@ pub unsafe fn squirrel_away<T>(x: @mut T) -> *rust_box<T> {
//XXX very incomplete
pub fn jsval_to_str(cx: *JSContext, v: JSVal) -> Result<~str, ()> {
let jsstr;
if RUST_JSVAL_IS_STRING(v) == 1 {
jsstr = RUST_JSVAL_TO_STRING(v)
} else {
jsstr = JS_ValueToString(cx, v);
if jsstr.is_null() {
return Err(());
}
}
unsafe {
let jsstr;
if RUST_JSVAL_IS_STRING(v) == 1 {
jsstr = RUST_JSVAL_TO_STRING(v)
} else {
jsstr = JS_ValueToString(cx, v);
if jsstr.is_null() {
return Err(());
}
}
let strbuf = JS_EncodeString(cx, jsstr);
let buf = str::raw::from_buf(strbuf as *u8);
JS_free(cx, strbuf as *libc::c_void);
@ -172,45 +178,49 @@ pub fn get_compartment(cx: *JSContext) -> @mut Compartment {
extern fn has_instance(_cx: *JSContext, obj: **JSObject, v: *JSVal, bp: *mut JSBool) -> JSBool {
//XXXjdm this is totally broken for non-object values
let mut o = RUST_JSVAL_TO_OBJECT(unsafe {*v});
let obj = unsafe {*obj};
unsafe { *bp = 0; }
while o.is_not_null() {
if o == obj {
unsafe { *bp = 1; }
break;
unsafe {
let mut o = RUST_JSVAL_TO_OBJECT(unsafe {*v});
let obj = unsafe {*obj};
unsafe { *bp = 0; }
while o.is_not_null() {
if o == obj {
unsafe { *bp = 1; }
break;
}
o = JS_GetPrototype(o);
}
o = JS_GetPrototype(o);
return 1;
}
return 1;
}
pub fn prototype_jsclass(name: ~str) -> @fn(compartment: @mut Compartment) -> JSClass {
let f: @fn(@mut Compartment) -> JSClass = |compartment: @mut Compartment| {
JSClass {
name: compartment.add_name(copy name),
flags: 0,
addProperty: GetJSClassHookStubPointer(PROPERTY_STUB) as *u8,
delProperty: GetJSClassHookStubPointer(PROPERTY_STUB) as *u8,
getProperty: GetJSClassHookStubPointer(PROPERTY_STUB) as *u8,
setProperty: GetJSClassHookStubPointer(STRICT_PROPERTY_STUB) as *u8,
enumerate: GetJSClassHookStubPointer(ENUMERATE_STUB) as *u8,
resolve: GetJSClassHookStubPointer(RESOLVE_STUB) as *u8,
convert: GetJSClassHookStubPointer(CONVERT_STUB) as *u8,
finalize: null(),
checkAccess: null(),
call: null(),
hasInstance: has_instance,
construct: null(),
trace: null(),
reserved: (null(), null(), null(), null(), null(), // 05
null(), null(), null(), null(), null(), // 10
null(), null(), null(), null(), null(), // 15
null(), null(), null(), null(), null(), // 20
null(), null(), null(), null(), null(), // 25
null(), null(), null(), null(), null(), // 30
null(), null(), null(), null(), null(), // 35
null(), null(), null(), null(), null()) // 40
unsafe {
JSClass {
name: compartment.add_name(copy name),
flags: 0,
addProperty: GetJSClassHookStubPointer(PROPERTY_STUB) as *u8,
delProperty: GetJSClassHookStubPointer(PROPERTY_STUB) as *u8,
getProperty: GetJSClassHookStubPointer(PROPERTY_STUB) as *u8,
setProperty: GetJSClassHookStubPointer(STRICT_PROPERTY_STUB) as *u8,
enumerate: GetJSClassHookStubPointer(ENUMERATE_STUB) as *u8,
resolve: GetJSClassHookStubPointer(RESOLVE_STUB) as *u8,
convert: GetJSClassHookStubPointer(CONVERT_STUB) as *u8,
finalize: null(),
checkAccess: null(),
call: null(),
hasInstance: has_instance,
construct: null(),
trace: null(),
reserved: (null(), null(), null(), null(), null(), // 05
null(), null(), null(), null(), null(), // 10
null(), null(), null(), null(), null(), // 15
null(), null(), null(), null(), null(), // 20
null(), null(), null(), null(), null(), // 25
null(), null(), null(), null(), null(), // 30
null(), null(), null(), null(), null(), // 35
null(), null(), null(), null(), null()) // 40
}
}
};
return f;
@ -219,30 +229,32 @@ pub fn prototype_jsclass(name: ~str) -> @fn(compartment: @mut Compartment) -> JS
pub fn instance_jsclass(name: ~str, finalize: *u8, trace: *u8)
-> @fn(compartment: @mut Compartment) -> JSClass {
let f: @fn(@mut Compartment) -> JSClass = |compartment: @mut Compartment| {
JSClass {
name: compartment.add_name(copy name),
flags: JSCLASS_HAS_RESERVED_SLOTS(1) | js::JSCLASS_IS_DOMJSCLASS,
addProperty: GetJSClassHookStubPointer(PROPERTY_STUB) as *u8,
delProperty: GetJSClassHookStubPointer(PROPERTY_STUB) as *u8,
getProperty: GetJSClassHookStubPointer(PROPERTY_STUB) as *u8,
setProperty: GetJSClassHookStubPointer(STRICT_PROPERTY_STUB) as *u8,
enumerate: GetJSClassHookStubPointer(ENUMERATE_STUB) as *u8,
resolve: GetJSClassHookStubPointer(RESOLVE_STUB) as *u8,
convert: GetJSClassHookStubPointer(CONVERT_STUB) as *u8,
finalize: finalize,
checkAccess: null(),
call: null(),
hasInstance: has_instance,
construct: null(),
trace: trace,
reserved: (null(), null(), null(), null(), null(), // 05
null(), null(), null(), null(), null(), // 10
null(), null(), null(), null(), null(), // 15
null(), null(), null(), null(), null(), // 20
null(), null(), null(), null(), null(), // 25
null(), null(), null(), null(), null(), // 30
null(), null(), null(), null(), null(), // 35
null(), null(), null(), null(), null()) // 40
unsafe {
JSClass {
name: compartment.add_name(copy name),
flags: JSCLASS_HAS_RESERVED_SLOTS(1) | js::JSCLASS_IS_DOMJSCLASS,
addProperty: GetJSClassHookStubPointer(PROPERTY_STUB) as *u8,
delProperty: GetJSClassHookStubPointer(PROPERTY_STUB) as *u8,
getProperty: GetJSClassHookStubPointer(PROPERTY_STUB) as *u8,
setProperty: GetJSClassHookStubPointer(STRICT_PROPERTY_STUB) as *u8,
enumerate: GetJSClassHookStubPointer(ENUMERATE_STUB) as *u8,
resolve: GetJSClassHookStubPointer(RESOLVE_STUB) as *u8,
convert: GetJSClassHookStubPointer(CONVERT_STUB) as *u8,
finalize: finalize,
checkAccess: null(),
call: null(),
hasInstance: has_instance,
construct: null(),
trace: trace,
reserved: (null(), null(), null(), null(), null(), // 05
null(), null(), null(), null(), null(), // 10
null(), null(), null(), null(), null(), // 15
null(), null(), null(), null(), null(), // 20
null(), null(), null(), null(), null(), // 25
null(), null(), null(), null(), null(), // 30
null(), null(), null(), null(), null(), // 35
null(), null(), null(), null(), null()) // 40
}
}
};
return f;
@ -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)
});
compartment.define_property(copy name, RUST_OBJECT_TO_JSVAL(obj.ptr),
GetJSClassHookStubPointer(PROPERTY_STUB) as *u8,
GetJSClassHookStubPointer(STRICT_PROPERTY_STUB) as *u8,
JSPROP_ENUMERATE);
compartment.stash_global_proto(name, obj);
return obj;
unsafe {
compartment.define_property(copy name, RUST_OBJECT_TO_JSVAL(obj.ptr),
GetJSClassHookStubPointer(PROPERTY_STUB) as *u8,
GetJSClassHookStubPointer(STRICT_PROPERTY_STUB) as *u8,
JSPROP_ENUMERATE);
compartment.stash_global_proto(name, obj);
return obj;
}
}
// We use slot 0 for holding the raw object. This is safe for both
@ -390,8 +404,10 @@ pub fn CreateInterfaceObjects2(cx: *JSContext, global: *JSObject, receiver: *JSO
return ptr::null();
}
JS_SetReservedSlot(proto, DOM_PROTO_INSTANCE_CLASS_SLOT,
RUST_PRIVATE_TO_JSVAL(domClass as *libc::c_void));
unsafe {
JS_SetReservedSlot(proto, DOM_PROTO_INSTANCE_CLASS_SLOT,
RUST_PRIVATE_TO_JSVAL(domClass as *libc::c_void));
}
}
let mut interface = ptr::null();
@ -419,75 +435,77 @@ fn CreateInterfaceObject(cx: *JSContext, global: *JSObject, receiver: *JSObject,
staticMethods: *JSFunctionSpec,
constants: *ConstantSpec,
name: *libc::c_char) -> *JSObject {
let constructor = if constructorClass.is_not_null() {
let functionProto = JS_GetFunctionPrototype(cx, global);
if functionProto.is_null() {
ptr::null()
unsafe {
let constructor = if constructorClass.is_not_null() {
let functionProto = JS_GetFunctionPrototype(cx, global);
if functionProto.is_null() {
ptr::null()
} else {
JS_NewObject(cx, constructorClass, functionProto, global)
}
} else {
JS_NewObject(cx, constructorClass, functionProto, global)
}
} else {
assert!(constructorNative.is_not_null());
let fun = JS_NewFunction(cx, constructorNative, ctorNargs,
JSFUN_CONSTRUCTOR, global, name);
if fun.is_null() {
ptr::null()
} else {
JS_GetFunctionObject(fun)
}
};
if constructor.is_null() {
return ptr::null();
}
if staticMethods.is_not_null() &&
!DefineMethods(cx, constructor, staticMethods) {
return ptr::null();
}
if constructorClass.is_not_null() {
let toString = do str::as_c_str("toString") |s| {
DefineFunctionWithReserved(cx, constructor, s,
InterfaceObjectToString,
0, 0)
assert!(constructorNative.is_not_null());
let fun = JS_NewFunction(cx, constructorNative, ctorNargs,
JSFUN_CONSTRUCTOR, global, name);
if fun.is_null() {
ptr::null()
} else {
JS_GetFunctionObject(fun)
}
};
if toString.is_null() {
if constructor.is_null() {
return ptr::null();
}
let toStringObj = JS_GetFunctionObject(toString);
SetFunctionNativeReserved(toStringObj, TOSTRING_CLASS_RESERVED_SLOT,
&RUST_PRIVATE_TO_JSVAL(constructorClass as *libc::c_void));
let s = JS_InternString(cx, name);
if s.is_null() {
if staticMethods.is_not_null() &&
!DefineMethods(cx, constructor, staticMethods) {
return ptr::null();
}
SetFunctionNativeReserved(toStringObj, TOSTRING_NAME_RESERVED_SLOT,
&RUST_STRING_TO_JSVAL(s));
}
if constants.is_not_null() &&
!DefineConstants(cx, constructor, constants) {
return ptr::null();
}
if constructorClass.is_not_null() {
let toString = do str::as_c_str("toString") |s| {
DefineFunctionWithReserved(cx, constructor, s,
InterfaceObjectToString,
0, 0)
};
if toString.is_null() {
return ptr::null();
}
if proto.is_not_null() && JS_LinkConstructorAndPrototype(cx, constructor, proto) == 0 {
return ptr::null();
}
let toStringObj = JS_GetFunctionObject(toString);
SetFunctionNativeReserved(toStringObj, TOSTRING_CLASS_RESERVED_SLOT,
&RUST_PRIVATE_TO_JSVAL(constructorClass as *libc::c_void));
let s = JS_InternString(cx, name);
if s.is_null() {
return ptr::null();
}
SetFunctionNativeReserved(toStringObj, TOSTRING_NAME_RESERVED_SLOT,
&RUST_STRING_TO_JSVAL(s));
}
let alreadyDefined = 0;
if JS_AlreadyHasOwnProperty(cx, receiver, name, &alreadyDefined) == 0 {
return ptr::null();
}
if constants.is_not_null() &&
!DefineConstants(cx, constructor, constants) {
return ptr::null();
}
if alreadyDefined == 0 &&
JS_DefineProperty(cx, receiver, name, RUST_OBJECT_TO_JSVAL(constructor),
ptr::null(), ptr::null(), 0) == 0 {
return ptr::null();
}
if proto.is_not_null() && JS_LinkConstructorAndPrototype(cx, constructor, proto) == 0 {
return ptr::null();
}
return constructor;
let alreadyDefined = 0;
if JS_AlreadyHasOwnProperty(cx, receiver, name, &alreadyDefined) == 0 {
return ptr::null();
}
if alreadyDefined == 0 &&
JS_DefineProperty(cx, receiver, name, RUST_OBJECT_TO_JSVAL(constructor),
ptr::null(), ptr::null(), 0) == 0 {
return ptr::null();
}
return constructor;
}
}
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 {
JS_DefineFunctions(cx, obj, methods) != 0
unsafe {
JS_DefineFunctions(cx, obj, methods) != 0
}
}
fn DefineProperties(cx: *JSContext, obj: *JSObject, properties: *JSPropertySpec) -> bool {
JS_DefineProperties(cx, obj, properties) != 0
unsafe {
JS_DefineProperties(cx, obj, properties) != 0
}
}
fn CreateInterfacePrototypeObject(cx: *JSContext, global: *JSObject,
@ -532,24 +554,26 @@ fn CreateInterfacePrototypeObject(cx: *JSContext, global: *JSObject,
methods: *JSFunctionSpec,
properties: *JSPropertySpec,
constants: *ConstantSpec) -> *JSObject {
let ourProto = JS_NewObjectWithUniqueType(cx, protoClass, parentProto, global);
if ourProto.is_null() {
return ptr::null();
}
unsafe {
let ourProto = JS_NewObjectWithUniqueType(cx, protoClass, parentProto, global);
if ourProto.is_null() {
return ptr::null();
}
if methods.is_not_null() && !DefineMethods(cx, ourProto, methods) {
return ptr::null();
}
if methods.is_not_null() && !DefineMethods(cx, ourProto, methods) {
return ptr::null();
}
if properties.is_not_null() && !DefineProperties(cx, ourProto, properties) {
return ptr::null();
}
if properties.is_not_null() && !DefineProperties(cx, ourProto, properties) {
return ptr::null();
}
if constants.is_not_null() && !DefineConstants(cx, ourProto, constants) {
return ptr::null();
}
if constants.is_not_null() && !DefineConstants(cx, ourProto, constants) {
return ptr::null();
}
return ourProto;
return ourProto;
}
}
pub extern fn ThrowingConstructor(_cx: *JSContext, _argc: uint, _vp: *JSVal) -> JSBool {
@ -578,20 +602,20 @@ pub struct WrapperCache {
wrapper: *JSObject
}
pub impl WrapperCache {
fn get_wrapper(&self) -> *JSObject {
impl WrapperCache {
pub fn get_wrapper(&self) -> *JSObject {
unsafe { cast::transmute(self.wrapper) }
}
fn set_wrapper(&mut self, wrapper: *JSObject) {
pub fn set_wrapper(&mut self, wrapper: *JSObject) {
self.wrapper = wrapper;
}
fn get_rootable(&self) -> **JSObject {
pub fn get_rootable(&self) -> **JSObject {
return to_unsafe_ptr(&self.wrapper);
}
fn new() -> WrapperCache {
pub fn new() -> WrapperCache {
WrapperCache {
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> {
if RUST_JSID_IS_INT(id) != 0 {
return Some(RUST_JSID_TO_INT(id) as u32);
unsafe {
if RUST_JSID_IS_INT(id) != 0 {
return Some(RUST_JSID_TO_INT(id) as u32);
}
return None;
}
return None;
// if id is length atom, -1, otherwise
/*return if JSID_IS_ATOM(id) {
let atom = JSID_TO_ATOM(id);
@ -730,11 +756,13 @@ pub fn XrayResolveProperty(cx: *JSContext,
}
fn InternJSString(cx: *JSContext, chars: *libc::c_char) -> Option<jsid> {
let s = JS_InternString(cx, chars);
if s.is_not_null() {
Some(RUST_INTERNED_STRING_TO_JSID(cx, s))
} else {
None
unsafe {
let s = JS_InternString(cx, chars);
if s.is_not_null() {
Some(RUST_INTERNED_STRING_TO_JSID(cx, s))
} else {
None
}
}
}

View file

@ -9,16 +9,19 @@ use dom::bindings::utils::{WrapperCache};
use dom::window::Window;
use super::utils;
use core::libc::c_uint;
use core::ptr::null;
use core::ptr;
use std::cast;
use std::libc;
use std::libc::c_uint;
use std::ptr::null;
use std::ptr;
use std::result;
use js::crust::{JS_PropertyStub, JS_StrictPropertyStub};
use js::global::jsval_to_rust_str;
use js::glue::bindgen::*;
use js::glue::bindgen::RUST_JSVAL_TO_INT;
use js::jsapi::bindgen::{JS_DefineFunctions, JS_GC, JS_GetRuntime};
use js::jsapi::bindgen::{JS_GetReservedSlot, JS_SetReservedSlot};
use js::jsapi::bindgen::{JS_ValueToString};
use js::glue::*;
use js::glue::RUST_JSVAL_TO_INT;
use js::jsapi::{JS_DefineFunctions, JS_GC, JS_GetRuntime};
use js::jsapi::{JS_GetReservedSlot, JS_SetReservedSlot};
use js::jsapi::{JS_ValueToString};
use js::jsapi::{JSContext, JSVal, JSObject, JSBool, JSFreeOp, JSFunctionSpec};
use js::jsapi::{JSNativeWrapper};
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 {
let runtime = JS_GetRuntime(cx);
JS_GC(runtime);
return 1;
unsafe {
let runtime = JS_GetRuntime(cx);
JS_GC(runtime);
return 1;
}
}
unsafe fn unwrap(obj: *JSObject) -> *rust_box<Window> {
@ -128,7 +133,9 @@ pub fn init(compartment: @mut Compartment) {
}
];
JS_DefineFunctions(compartment.cx.ptr, proto.ptr, &methods[0]);
unsafe {
JS_DefineFunctions(compartment.cx.ptr, proto.ptr, &methods[0]);
}
}
pub fn create(compartment: @mut Compartment, win: @mut Window) {
@ -141,13 +148,13 @@ pub fn create(compartment: @mut Compartment, win: @mut Window) {
unsafe {
let raw_ptr: *libc::c_void = cast::transmute(squirrel_away(win));
JS_SetReservedSlot(obj.ptr, 0, RUST_PRIVATE_TO_JSVAL(raw_ptr));
}
//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.
compartment.define_property(~"window", RUST_OBJECT_TO_JSVAL(obj.ptr),
JS_PropertyStub, JS_StrictPropertyStub,
JSPROP_ENUMERATE);
//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.
compartment.define_property(~"window", RUST_OBJECT_TO_JSVAL(obj.ptr),
JS_PropertyStub, JS_StrictPropertyStub,
JSPROP_ENUMERATE);
}
}
impl CacheableWrapper for Window {

View file

@ -7,7 +7,7 @@
use dom::bindings::utils::{DOMString, null_string, str};
use dom::node::{Node, NodeTypeId, ScriptView};
use core::str;
use std::str;
pub struct CharacterData {
parent: Node<ScriptView>,
@ -46,7 +46,7 @@ impl CharacterData {
pub fn AppendData(&mut self, arg: DOMString) {
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) {

View file

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

View file

@ -10,8 +10,8 @@ pub struct ClientRectList {
rects: ~[@mut ClientRect]
}
pub impl ClientRectList {
fn new(rects: ~[@mut ClientRect]) -> @mut ClientRectList {
impl ClientRectList {
pub fn new(rects: ~[@mut ClientRect]) -> @mut ClientRectList {
let list = @mut ClientRectList {
wrapper: WrapperCache::new(),
rects: rects
@ -20,11 +20,11 @@ pub impl ClientRectList {
list
}
fn Length(&self) -> u32 {
pub fn Length(&self) -> 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 {
Some(self.rects[index])
} 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;
self.Item(index)
}

View file

@ -9,7 +9,7 @@ use dom::node::{AbstractNode, ScriptView};
use dom::window::Window;
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};
pub struct Document {
@ -19,23 +19,25 @@ pub struct Document {
}
pub fn Document(root: AbstractNode<ScriptView>, window: Option<@mut Window>) -> @mut Document {
let doc = @mut Document {
root: root,
wrapper: WrapperCache::new(),
window: window
};
let compartment = global_script_context().js_compartment;
do root.with_base |base| {
assert!(base.wrapper.get_wrapper().is_not_null());
let rootable = base.wrapper.get_rootable();
JS_AddObjectRoot(compartment.cx.ptr, rootable);
unsafe {
let doc = @mut Document {
root: root,
wrapper: WrapperCache::new(),
window: window
};
let compartment = global_script_context().js_compartment;
do root.with_base |base| {
assert!(base.wrapper.get_wrapper().is_not_null());
let rootable = base.wrapper.get_rootable();
JS_AddObjectRoot(compartment.cx.ptr, rootable);
}
document::create(compartment, doc);
doc
}
document::create(compartment, doc);
doc
}
pub impl Document {
fn getElementsByTagName(&self, tag: DOMString) -> Option<@mut HTMLCollection> {
impl Document {
pub fn getElementsByTagName(&self, tag: DOMString) -> Option<@mut HTMLCollection> {
let mut elements = ~[];
let tag = tag.to_str();
let _ = for self.root.traverse_preorder |child| {
@ -50,18 +52,20 @@ pub impl Document {
Some(HTMLCollection::new(elements))
}
fn content_changed(&self) {
for self.window.each |window| {
pub fn content_changed(&self) {
for self.window.iter().advance |window| {
window.content_changed()
}
}
fn teardown(&self) {
let compartment = global_script_context().js_compartment;
do self.root.with_base |node| {
assert!(node.wrapper.get_wrapper().is_not_null());
let rootable = node.wrapper.get_rootable();
JS_RemoveObjectRoot(compartment.cx.ptr, rootable);
pub fn teardown(&self) {
unsafe {
let compartment = global_script_context().js_compartment;
do self.root.with_base |node| {
assert!(node.wrapper.get_wrapper().is_not_null());
let rootable = node.wrapper.get_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::{ContentBoxesResponse};
use core::cell::Cell;
use core::str::eq_slice;
use std::net::url::Url;
use std::cell::Cell;
use std::uint;
use std::str::eq_slice;
use extra::net::url::Url;
pub struct Element {
parent: Node<ScriptView>,
@ -114,7 +115,7 @@ pub struct HTMLImageElement {
// Element methods
//
pub impl<'self> Element {
impl<'self> Element {
pub fn new(type_id: ElementTypeId, tag_name: ~str) -> Element {
Element {
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.
for uint::range(0, self.attrs.len()) |i| {
if eq_slice(self.attrs[i].name, name) {
@ -134,11 +135,11 @@ pub impl<'self> Element {
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 value = value.to_str();
// 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;
for uint::range(0, self.attrs.len()) |i| {
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 {
Some(doc) => {
match doc.window {
@ -199,7 +200,7 @@ pub impl<'self> Element {
Some(ClientRectList::new(rects))
}
fn getBoundingClientRect(&self) -> Option<@mut ClientRect> {
pub fn getBoundingClientRect(&self) -> Option<@mut ClientRect> {
match self.parent.owner_doc {
Some(doc) => {
match doc.window {

View file

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

View file

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

View file

@ -8,13 +8,15 @@ use dom::node::{AbstractNode, ScriptView};
use js::jsapi::{JSObject, JSContext};
use std::ptr;
pub struct HTMLCollection {
elements: ~[AbstractNode<ScriptView>],
wrapper: WrapperCache
}
pub impl HTMLCollection {
fn new(elements: ~[AbstractNode<ScriptView>]) -> @mut HTMLCollection {
impl HTMLCollection {
pub fn new(elements: ~[AbstractNode<ScriptView>]) -> @mut HTMLCollection {
let collection = @mut HTMLCollection {
elements: elements,
wrapper: WrapperCache::new()
@ -23,11 +25,11 @@ pub impl HTMLCollection {
collection
}
fn Length(&self) -> u32 {
pub fn Length(&self) -> 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() {
Some(self.elements[index])
} 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(());
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;
self.Item(index)
}

View file

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

View file

@ -8,10 +8,15 @@ use dom::bindings::window;
use layout_interface::ReflowForScriptQuery;
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 std::timer;
use std::uv_global_loop;
use extra::timer;
use extra::uv_global_loop;
pub enum TimerControlMsg {
TimerMessage_Fire(~TimerData),
@ -61,17 +66,17 @@ pub fn TimerData(argc: libc::c_uint, argv: *JSVal) -> TimerData {
// FIXME: delayed_send shouldn't require Copy
#[allow(non_implicitly_copyable_typarams)]
pub impl Window {
fn alert(&self, s: &str) {
impl Window {
pub fn alert(&self, s: &str) {
// Right now, just print to the console
io::println(fmt!("ALERT: %s", s));
}
fn close(&self) {
pub fn close(&self) {
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;
// 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)));
}
fn content_changed(&self) {
pub fn content_changed(&self) {
unsafe {
(*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.
use core::cell::Cell;
use core::comm::Port;
use core::str;
use std::cell::Cell;
use std::comm;
use std::comm::Port;
use std::task;
use std::str;
use newcss::stylesheet::Stylesheet;
use newcss::util::DataStream;
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.
pub enum StylesheetProvenance {
@ -23,12 +25,12 @@ pub fn spawn_css_parser(provenance: StylesheetProvenance,
-> Port<Stylesheet> {
let (result_port, result_chan) = comm::stream();
let provenance_cell = Cell(provenance);
let provenance_cell = Cell::new(provenance);
do task::spawn {
let url = do provenance_cell.with_ref |p| {
match *p {
UrlProvenance(copy the_url) => the_url,
InlineProvenance(copy the_url, _) => the_url
UrlProvenance(ref the_url) => copy *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 {
let data_cell = Cell(data);
let data_cell = Cell::new(data);
return || {
if data_cell.is_empty() {
None
} else {
// 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 newcss::stylesheet::Stylesheet;
use core::cell::Cell;
use core::comm::{Chan, Port, SharedChan};
use core::str::eq_slice;
use std::cast;
use std::cell::Cell;
use std::comm;
use std::comm::{Chan, Port, SharedChan};
use std::str::eq_slice;
use std::result;
use std::task;
use hubbub::hubbub;
use servo_net::image_cache_task::ImageCacheTask;
use servo_net::image_cache_task;
use servo_net::resource_task::{Done, Load, Payload, ResourceTask};
use servo_util::tree::TreeUtils;
use servo_util::url::make_url;
use std::net::url::Url;
use std::net::url;
use extra::net::url::Url;
use extra::net::url;
macro_rules! handle_element(
($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
// 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(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 => {
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);
}
@ -211,9 +215,9 @@ pub fn parse_html(url: Url,
let resource_task2 = resource_task.clone();
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 = Cell(css_msg_port);
let css_msg_port = Cell::new(css_msg_port);
do spawn {
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.
let resource_task2 = resource_task.clone();
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 = Cell(js_msg_port);
let js_msg_port = Cell::new(js_msg_port);
do spawn {
js_script_listener(js_result_chan.take(), js_msg_port.take(), resource_task2.clone());
}
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.
let root = ~HTMLHtmlElement { parent: Element::new(HTMLHtmlElementTypeId, ~"html") };
@ -239,7 +244,7 @@ pub fn parse_html(url: Url,
debug!("created new node");
let mut parser = hubbub::Parser("UTF-8", false);
debug!("created parser");
parser.set_document_node(root.to_hubbub_node());
parser.set_document_node(unsafe { root.to_hubbub_node() });
parser.enable_scripting(true);
// 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() {
debug!("found inline CSS stylesheet");
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| {
let data = text_node.parent.data.to_str(); // FIXME: Bad copy.
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| {
debug!("create text");

View file

@ -9,13 +9,13 @@
use dom::node::{AbstractNode, ScriptView, LayoutView};
use script_task::{ScriptMsg, ScriptChan};
use core::comm::{Chan, SharedChan};
use std::comm::{Chan, SharedChan};
use geom::rect::Rect;
use geom::size::Size2D;
use geom::point::Point2D;
use gfx::geometry::Au;
use newcss::stylesheet::Stylesheet;
use std::net::url::Url;
use extra::net::url::Url;
/// 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_util (name = "util");
extern mod servo_msg (name = "msg");
extern mod std;
extern mod extra;
pub mod dom {
pub mod bindings {

View file

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

View file

@ -13,8 +13,8 @@ pub struct MonoCache<K, V> {
entry: Option<(K,V)>,
}
pub impl<K: Copy + Eq, V: Copy> MonoCache<K,V> {
fn new(_size: uint) -> MonoCache<K,V> {
impl<K: Copy + Eq, V: Copy> MonoCache<K,V> {
pub fn new(_size: uint) -> MonoCache<K,V> {
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> {
match self.entry {
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,
}
pub impl<K: Copy + Eq, V: Copy> LRUCache<K,V> {
fn new(size: uint) -> LRUCache<K, V> {
impl<K: Copy + Eq, V: Copy> LRUCache<K,V> {
pub fn new(size: uint) -> LRUCache<K, V> {
LRUCache {
entries: ~[],
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];
if pos != self.cache_size {
self.entries.remove(pos);
self.entries.push((key, val));
self.entries.push((key, copy val));
}
val
}
@ -103,7 +103,7 @@ impl<K: Copy + Eq, V: Copy> Cache<K,V> for LRUCache<K,V> {
Some(pos) => self.touch(pos),
None => {
let val = blk(key);
self.insert(key, val);
self.insert(key, copy val);
val
}
}

View file

@ -2,6 +2,8 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use std::uint;
enum RangeRelation {
OverlapsBegin(/* overlap */ uint),
OverlapsEnd(/* overlap */ uint),
@ -17,7 +19,7 @@ pub struct Range {
priv len: uint
}
pub impl Range {
impl Range {
pub fn new(off: uint, len: uint) -> Range {
Range { off: off, len: len }
}
@ -27,12 +29,12 @@ pub impl Range {
}
}
pub impl Range {
fn begin(&self) -> uint { self.off }
fn length(&self) -> uint { self.len }
fn end(&self) -> uint { self.off + self.len }
impl Range {
pub fn begin(&self) -> uint { self.off }
pub fn length(&self) -> uint { 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| {
if !callback(i) {
break
@ -41,32 +43,32 @@ pub impl Range {
true
}
fn contains(&self, i: uint) -> bool {
pub fn contains(&self, i: uint) -> bool {
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()
}
fn shift_by(&mut self, i: int) {
pub fn shift_by(&mut self, i: int) {
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;
}
fn extend_to(&mut self, i: uint) {
pub fn extend_to(&mut self, i: uint) {
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.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.len = len_i;
}
@ -74,7 +76,7 @@ pub impl Range {
/// Computes the relationship between two ranges (`self` and `other`),
/// from the point of view of `self`. So, 'EntirelyBefore' means
/// 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() {
return EntirelyBefore;
}
@ -102,7 +104,7 @@ pub impl Range {
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);
debug!("repair_after_coalesced_range: possibly repairing range %?", self);
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/. */
// Timing functions.
use std::time::precise_time_ns;
use core::cell::Cell;
use core::comm::{Port, SharedChan};
use std::sort::tim_sort;
use extra::time::precise_time_ns;
use std::cell::Cell;
use std::comm::{Port, SharedChan};
use extra::sort::tim_sort;
// front-end representation of the profiler used to communicate with the profiler
#[deriving(Clone)]
@ -111,7 +111,7 @@ impl ProfilerCategory {
impl Profiler {
pub fn create(port: Port<ProfilerMsg>) {
let port = Cell(port);
let port = Cell::new(port);
do spawn {
let mut profiler = Profiler::new(port.take());
profiler.start();
@ -154,7 +154,7 @@ impl Profiler {
println(fmt!("%31s %15s %15s %15s %15s %15s",
"_category (ms)_", "_mean (ms)_", "_median (ms)_",
"_min (ms)_", "_max (ms)_", "_bucket size_"));
for vec::each_mut(self.buckets) |bucket| {
for self.buckets.mut_iter().advance |bucket| {
match *bucket {
(category, ref mut data) => {
tim_sort(*data);
@ -163,8 +163,8 @@ impl Profiler {
let (mean, median, min, max) =
(data.foldl(0f64, |a, b| a + *b) / (data_len as f64),
data[data_len / 2],
data.min(),
data.max());
data.iter().min(),
data.iter().max());
println(fmt!("%-30s: %15.4? %15.4? %15.4? %15.4? %15u",
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
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use std::net::url;
use std::net::url::Url;
use core::hashmap::HashMap;
use extra::net::url;
use extra::net::url::Url;
use std::hashmap::HashMap;
use std::os;
use std::result;
/**
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("/") {
current_url.scheme + "://" +
current_url.host + "/" +
str_url.trim_left_chars([ '/' ])
str_url.trim_left_chars(&'/')
} else {
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());
}
let path = path; // FIXME: borrow checker workaround
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
}

View file

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

View file

@ -2,7 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use core::cmp::{Ord, Eq};
use std::cmp::{Ord, Eq};
pub trait BinarySearchMethods<'self, T: Ord + Eq> {
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