mirror of
https://github.com/servo/servo.git
synced 2025-06-25 01:24:37 +01:00
auto merge of #546 : brson/servo/master, r=metajack
This commit is contained in:
commit
bc520e0143
109 changed files with 1182 additions and 988 deletions
|
@ -1 +1 @@
|
|||
Subproject commit 1b883365bc0813f5775c8207e414b7973e947a76
|
||||
Subproject commit f348465283d6cd85b69bcdc1711d14985d154c39
|
|
@ -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> {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -96,19 +103,21 @@ impl FontHandleMethods for FontHandle {
|
|||
fn create_face_from_buffer(lib: FT_Library,
|
||||
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));
|
||||
|
||||
if !result.succeeded() || face.is_null() {
|
||||
return Err(());
|
||||
}
|
||||
if FontHandle::set_char_size(face, pt_size).is_ok() {
|
||||
Ok(face)
|
||||
} else {
|
||||
Err(())
|
||||
|
||||
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(())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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 {
|
||||
|
|
|
@ -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 },
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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 => {
|
||||
|
|
|
@ -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: () }
|
||||
|
|
|
@ -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"]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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)]
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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; }
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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))));
|
||||
}
|
||||
|
||||
|
|
|
@ -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};
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 &&
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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())
|
||||
};
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
||||
|
|
|
@ -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 => {
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
|
|
@ -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.
|
||||
///
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
|
||||
use dom::bindings::utils::WrapperCache;
|
||||
|
||||
use std::f32;
|
||||
|
||||
pub struct ClientRect {
|
||||
wrapper: WrapperCache,
|
||||
top: f32,
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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};
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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.
|
||||
///
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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(%?): %?",
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
url = "http://servo.org/")];
|
||||
#[crate_type = "lib"];
|
||||
|
||||
extern mod std;
|
||||
extern mod extra;
|
||||
|
||||
pub mod cache;
|
||||
pub mod range;
|
||||
|
|
|
@ -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
Loading…
Add table
Add a link
Reference in a new issue