Language changes.

This commit is contained in:
Josh Matthews 2013-03-11 15:20:09 -04:00
parent a77fe19eea
commit e85b3798f2
78 changed files with 733 additions and 672 deletions

@ -1 +1 @@
Subproject commit 28dbde9f94091de97035246155b5bff08f768fdc Subproject commit 433fcc2d6862bea202ad2e3acfd1fe4041064edc

@ -1 +1 @@
Subproject commit c90b66a7ec392a231ce26c717a7e11de219f4bd8 Subproject commit a0257b8d6d81ead5aeb018e48b37c456177cd92e

@ -1 +1 @@
Subproject commit 0d2d600ecafdccda56c54f9f693d83592b2ec4d4 Subproject commit 6eba2da0919e6d47458d8d4e002aaa7a17a66f77

@ -1 +1 @@
Subproject commit 72af03130bf21acc52810ae642095677efd6b1cf Subproject commit 1d966254065c59d0c108f3207c4646184fc85635

@ -1 +1 @@
Subproject commit ebfb866ff36203de9f76a852be986ac5df895483 Subproject commit e185c9ad59eb42250db8a1c5d1d1e078265d933d

@ -1 +1 @@
Subproject commit 5a9e5a84a2b4061fc7f72b5d50e47272da910ae9 Subproject commit f382fa4ca9bd2b13805156b821d1a8242f9873a1

@ -1 +1 @@
Subproject commit 916004c3f4bc30515085fe4bb888338805a06aa9 Subproject commit 84684665c678d35057296cdfdfaa4389a23d1d9b

@ -1 +1 @@
Subproject commit 2de7e3f2c404d3691212cac40a73986f4e65743c Subproject commit 5d00c01fb4798722b5e5a27f55fccc726068ad08

@ -1 +1 @@
Subproject commit 3bd2b9e7194eb39efc036a4a982027b56b1717e1 Subproject commit 4714bc7a8f7a3d4168b297c4568b38acd5b7a8c9

@ -1 +1 @@
Subproject commit 584299c9d2c7a48bb31bbb8a64a1d20d99083796 Subproject commit 9bf7ae289c9fdbc82d0a8f45a54f18e281fc6875

@ -1 +1 @@
Subproject commit 677c6cec147ffb33abf8e8a25aa589dd03a8665f Subproject commit f796ad48dae00987ab6bc0c64031ecb8358a9c08

@ -1 +1 @@
Subproject commit 0e50f2459cbcefd516c5bfe25552821f1a2d5991 Subproject commit ea93796f5c0675d50fa1e92bfd76709a601fe9fe

@ -1 +1 @@
Subproject commit 23ba9e84d5cd849a406ee22f37db5babdff10bc9 Subproject commit 7e127420530640c7ec3c79883b702041dfe13b14

@ -1 +1 @@
Subproject commit 8d512d5944c11bba56182970548a67ebbcdafc21 Subproject commit 485845b44db19558c8c911a4a4a864144a85f72b

@ -1 +1 @@
Subproject commit 5be46dce95aad3e0dc2773045bf3d163da51e41d Subproject commit 6cec2ef974c10669d127d19509ae595ce2b76135

@ -1 +1 @@
Subproject commit 93052ecb04a1a7bedd2ed635d60f900716cd2474 Subproject commit 0adab98b6bc352fa689320ce8cd14ca6d92a88d3

View file

@ -22,7 +22,7 @@ The interface used to by the renderer to aquire draw targets for
each rendered frame and submit them to be drawn to the display each rendered frame and submit them to be drawn to the display
*/ */
pub trait Compositor { pub trait Compositor {
fn begin_drawing(next_dt: comm::Chan<LayerBufferSet>); fn begin_drawing(&self, next_dt: comm::Chan<LayerBufferSet>);
fn draw(next_dt: comm::Chan<LayerBufferSet>, +draw_me: LayerBufferSet); fn draw(&self, next_dt: comm::Chan<LayerBufferSet>, +draw_me: LayerBufferSet);
} }

View file

@ -106,7 +106,7 @@ pub impl DisplayList {
self.list.push(item); self.list.push(item);
} }
fn draw_into_context(ctx: &RenderContext) { fn draw_into_context(&self, ctx: &RenderContext) {
debug!("beginning display list"); debug!("beginning display list");
for self.list.each |item| { for self.list.each |item| {
// FIXME(Issue #150): crashes // FIXME(Issue #150): crashes

View file

@ -33,17 +33,17 @@ pub type FontHandle/& = freetype_impl::font::FreeTypeFontHandle;
pub trait FontHandleMethods { pub trait FontHandleMethods {
// an identifier usable by FontContextHandle to recreate this FontHandle. // an identifier usable by FontContextHandle to recreate this FontHandle.
pure fn face_identifier() -> ~str; pure fn face_identifier(&self) -> ~str;
pure fn family_name() -> ~str; pure fn family_name(&self) -> ~str;
pure fn face_name() -> ~str; pure fn face_name(&self) -> ~str;
pure fn is_italic() -> bool; pure fn is_italic(&self) -> bool;
pure fn boldness() -> CSSFontWeight; pure fn boldness(&self) -> CSSFontWeight;
fn clone_with_style(fctx: &native::FontContextHandle, style: &UsedFontStyle) -> Result<FontHandle, ()>; fn clone_with_style(&self, fctx: &native::FontContextHandle, style: &UsedFontStyle) -> Result<FontHandle, ()>;
fn glyph_index(codepoint: char) -> Option<GlyphIndex>; fn glyph_index(&self, codepoint: char) -> Option<GlyphIndex>;
fn glyph_h_advance(GlyphIndex) -> Option<FractionalPixel>; fn glyph_h_advance(&self, GlyphIndex) -> Option<FractionalPixel>;
fn get_metrics() -> FontMetrics; fn get_metrics(&self) -> FontMetrics;
fn get_table_for_tag(FontTableTag) -> Option<FontTable>; fn get_table_for_tag(&self, FontTableTag) -> Option<FontTable>;
} }
// TODO(Issue #163): this is a workaround for static methods and // TODO(Issue #163): this is a workaround for static methods and
@ -75,13 +75,13 @@ pub type FractionalPixel = float;
pub type FontTableTag = u32; pub type FontTableTag = u32;
trait FontTableTagConversions { trait FontTableTagConversions {
pub pure fn tag_to_str() -> ~str; pub pure fn tag_to_str(&self) -> ~str;
} }
impl FontTableTagConversions for FontTableTag { impl FontTableTagConversions for FontTableTag {
pub pure fn tag_to_str() -> ~str { pub pure fn tag_to_str(&self) -> ~str {
unsafe { unsafe {
let reversed = str::raw::from_buf_len(cast::transmute(&self), 4); let reversed = str::raw::from_buf_len(cast::transmute(self), 4);
return str::from_chars([reversed.char_at(3), return str::from_chars([reversed.char_at(3),
reversed.char_at(2), reversed.char_at(2),
reversed.char_at(1), reversed.char_at(1),
@ -97,7 +97,7 @@ pub type FontTable/& = quartz::font::QuartzFontTable;
pub type FontTable/& = freetype_impl::font::FreeTypeFontTable; pub type FontTable/& = freetype_impl::font::FreeTypeFontTable;
pub trait FontTableMethods { pub trait FontTableMethods {
fn with_buffer(fn&(*u8, uint)); fn with_buffer(&self, &fn(*u8, uint));
} }
pub struct FontMetrics { pub struct FontMetrics {
@ -126,7 +126,7 @@ pub enum CSSFontWeight {
} }
pub impl CSSFontWeight { pub impl CSSFontWeight {
pub pure fn is_bold() -> bool { pub pure fn is_bold(self) -> bool {
match self { match self {
FontWeight900 | FontWeight800 | FontWeight700 | FontWeight600 => true, FontWeight900 | FontWeight800 | FontWeight700 | FontWeight600 => true,
_ => false _ => false
@ -199,11 +199,11 @@ pub struct FontGroup {
// style of the first western font in group, which is // style of the first western font in group, which is
// used for purposes of calculating text run metrics. // used for purposes of calculating text run metrics.
style: UsedFontStyle, style: UsedFontStyle,
fonts: ~[@Font], fonts: ~[@mut Font],
} }
pub impl FontGroup { pub impl FontGroup {
static fn new(families: @str, style: &UsedFontStyle, fonts: ~[@Font]) -> FontGroup { static fn new(families: @str, style: &UsedFontStyle, fonts: ~[@mut Font]) -> FontGroup {
FontGroup { FontGroup {
families: families, families: families,
style: copy *style, style: copy *style,
@ -211,7 +211,7 @@ pub impl FontGroup {
} }
} }
fn create_textrun(text: ~str) -> TextRun { fn create_textrun(&self, text: ~str) -> TextRun {
assert self.fonts.len() > 0; assert self.fonts.len() > 0;
// TODO(Issue #177): Actually fall back through the FontGroup when a font is unsuitable. // TODO(Issue #177): Actually fall back through the FontGroup when a font is unsuitable.
@ -235,8 +235,8 @@ and the renderer can use it to render text.
*/ */
pub struct Font { pub struct Font {
priv handle: FontHandle, priv handle: FontHandle,
priv mut azure_font: Option<ScaledFont>, priv azure_font: Option<ScaledFont>,
priv mut shaper: Option<@Shaper>, priv shaper: Option<@Shaper>,
style: UsedFontStyle, style: UsedFontStyle,
metrics: FontMetrics, metrics: FontMetrics,
backend: BackendType, backend: BackendType,
@ -247,7 +247,7 @@ pub impl Font {
buffer: ~[u8], buffer: ~[u8],
style: &SpecifiedFontStyle, style: &SpecifiedFontStyle,
backend: BackendType) backend: BackendType)
-> Result<@Font, ()> { -> Result<@mut Font, ()> {
let handle = FontHandle::new_from_buffer(&ctx.handle, buffer, style); let handle = FontHandle::new_from_buffer(&ctx.handle, buffer, style);
let handle = if handle.is_ok() { let handle = if handle.is_ok() {
result::unwrap(handle) result::unwrap(handle)
@ -258,7 +258,7 @@ pub impl Font {
let metrics = handle.get_metrics(); let metrics = handle.get_metrics();
// TODO(Issue #179): convert between specified and used font style here? // TODO(Issue #179): convert between specified and used font style here?
return Ok(@Font { return Ok(@mut Font {
handle: handle, handle: handle,
azure_font: None, azure_font: None,
shaper: None, shaper: None,
@ -269,10 +269,10 @@ pub impl Font {
} }
static fn new_from_adopted_handle(_fctx: &FontContext, handle: FontHandle, static fn new_from_adopted_handle(_fctx: &FontContext, handle: FontHandle,
style: &SpecifiedFontStyle, backend: BackendType) -> @Font { style: &SpecifiedFontStyle, backend: BackendType) -> @mut Font {
let metrics = handle.get_metrics(); let metrics = handle.get_metrics();
@Font { @mut Font {
handle: handle, handle: handle,
azure_font: None, azure_font: None,
shaper: None, shaper: None,
@ -283,7 +283,7 @@ pub impl Font {
} }
static fn new_from_existing_handle(fctx: &FontContext, handle: &FontHandle, static fn new_from_existing_handle(fctx: &FontContext, handle: &FontHandle,
style: &SpecifiedFontStyle, backend: BackendType) -> Result<@Font,()> { style: &SpecifiedFontStyle, backend: BackendType) -> Result<@mut Font,()> {
// TODO(Issue #179): convert between specified and used font style here? // TODO(Issue #179): convert between specified and used font style here?
let styled_handle = match handle.clone_with_style(&fctx.handle, style) { let styled_handle = match handle.clone_with_style(&fctx.handle, style) {
@ -294,7 +294,7 @@ pub impl Font {
return Ok(Font::new_from_adopted_handle(fctx, styled_handle, style, backend)); return Ok(Font::new_from_adopted_handle(fctx, styled_handle, style, backend));
} }
priv fn get_shaper(@self) -> @Shaper { priv fn get_shaper(@mut self) -> @Shaper {
// fast path: already created a shaper // fast path: already created a shaper
match self.shaper { match self.shaper {
Some(shaper) => { return shaper; }, Some(shaper) => { return shaper; },
@ -306,7 +306,7 @@ pub impl Font {
shaper shaper
} }
fn get_table_for_tag(tag: FontTableTag) -> Option<FontTable> { fn get_table_for_tag(&self, tag: FontTableTag) -> Option<FontTable> {
let result = self.handle.get_table_for_tag(tag); let result = self.handle.get_table_for_tag(tag);
let status = if result.is_some() { "Found" } else { "Didn't find" }; let status = if result.is_some() { "Found" } else { "Didn't find" };
@ -320,7 +320,7 @@ pub impl Font {
// TODO: this should return a borrowed pointer, but I can't figure // TODO: this should return a borrowed pointer, but I can't figure
// out why borrowck doesn't like my implementation. // out why borrowck doesn't like my implementation.
priv fn get_azure_font(&self) -> AzScaledFontRef { priv fn get_azure_font(&mut self) -> AzScaledFontRef {
// fast path: we've already created the azure font resource // fast path: we've already created the azure font resource
match self.azure_font { match self.azure_font {
Some(ref azfont) => return azfont.get_ref(), Some(ref azfont) => return azfont.get_ref(),
@ -341,7 +341,7 @@ pub impl Font {
} }
#[cfg(target_os="linux")] #[cfg(target_os="linux")]
priv fn create_azure_font() -> ScaledFont { priv fn create_azure_font(&self) -> ScaledFont {
let cairo_font = self.handle.face; let cairo_font = self.handle.face;
let size = self.style.pt_size as AzFloat; let size = self.style.pt_size as AzFloat;
ScaledFont::new(self.backend, cairo_font, size) ScaledFont::new(self.backend, cairo_font, size)
@ -350,7 +350,8 @@ pub impl Font {
pub impl Font { pub impl Font {
fn draw_text_into_context(rctx: &RenderContext, fn draw_text_into_context(&mut self,
rctx: &RenderContext,
run: &TextRun, run: &TextRun,
range: &const Range, range: &const Range,
baseline_origin: Point2D<Au>, baseline_origin: Point2D<Au>,
@ -411,7 +412,7 @@ pub impl Font {
ptr::null()); ptr::null());
} }
fn measure_text(run: &TextRun, range: &const Range) -> RunMetrics { fn measure_text(&self, run: &TextRun, range: &const Range) -> RunMetrics {
// TODO(Issue #199): alter advance direction for RTL // TODO(Issue #199): alter advance direction for RTL
// TODO(Issue #98): using inter-char and inter-word spacing settings when measuring text // TODO(Issue #98): using inter-char and inter-word spacing settings when measuring text
let mut advance = Au(0); let mut advance = Au(0);
@ -433,22 +434,22 @@ pub impl Font {
} }
} }
fn shape_text(@self, text: &str, store: &mut GlyphStore) { fn shape_text(@mut self, text: &str, store: &mut GlyphStore) {
// TODO(Issue #229): use a more efficient strategy for repetitive shaping. // TODO(Issue #229): use a more efficient strategy for repetitive shaping.
// For example, Gecko uses a per-"word" hashtable of shaper results. // For example, Gecko uses a per-"word" hashtable of shaper results.
let shaper = self.get_shaper(); let shaper = self.get_shaper();
shaper.shape_text(text, store); shaper.shape_text(text, store);
} }
fn get_descriptor() -> FontDescriptor { fn get_descriptor(&self) -> FontDescriptor {
FontDescriptor::new(copy self.style, SelectorPlatformIdentifier(self.handle.face_identifier())) FontDescriptor::new(copy self.style, SelectorPlatformIdentifier(self.handle.face_identifier()))
} }
fn glyph_index(codepoint: char) -> Option<GlyphIndex> { fn glyph_index(&self, codepoint: char) -> Option<GlyphIndex> {
self.handle.glyph_index(codepoint) self.handle.glyph_index(codepoint)
} }
fn glyph_h_advance(glyph: GlyphIndex) -> FractionalPixel { fn glyph_h_advance(&self, glyph: GlyphIndex) -> FractionalPixel {
match self.handle.glyph_h_advance(glyph) { match self.handle.glyph_h_advance(glyph) {
Some(adv) => adv, Some(adv) => adv,
None => /* FIXME: Need fallback strategy */ 10f as FractionalPixel None => /* FIXME: Need fallback strategy */ 10f as FractionalPixel

View file

@ -44,7 +44,7 @@ type FontContextHandle/& = freetype_impl::font_context::FreeTypeFontContextHandl
pub trait FontContextHandleMethods { pub trait FontContextHandleMethods {
pure fn clone(&const self) -> FontContextHandle; pure fn clone(&const self) -> FontContextHandle;
fn create_font_from_identifier(~str, UsedFontStyle) -> Result<FontHandle, ()>; fn create_font_from_identifier(&self, ~str, UsedFontStyle) -> Result<FontHandle, ()>;
} }
// TODO(Issue #163): this is a workaround for static methods, traits, // TODO(Issue #163): this is a workaround for static methods, traits,
@ -63,7 +63,7 @@ pub impl FontContextHandle {
#[allow(non_implicitly_copyable_typarams)] #[allow(non_implicitly_copyable_typarams)]
pub struct FontContext { pub struct FontContext {
instance_cache: MonoCache<FontDescriptor, @Font>, instance_cache: MonoCache<FontDescriptor, @mut Font>,
font_list: Option<FontList>, // only needed by layout font_list: Option<FontList>, // only needed by layout
handle: FontContextHandle, handle: FontContextHandle,
backend: BackendType, backend: BackendType,
@ -87,7 +87,7 @@ pub impl FontContext {
FontContext { FontContext {
// TODO(Rust #3902): remove extraneous type parameters once they are inferred correctly. // TODO(Rust #3902): remove extraneous type parameters once they are inferred correctly.
instance_cache: instance_cache:
Cache::new::<FontDescriptor,@Font,MonoCache<FontDescriptor,@Font>>(10), Cache::new::<FontDescriptor,@mut Font,MonoCache<FontDescriptor,@mut Font>>(10),
font_list: font_list, font_list: font_list,
handle: handle, handle: handle,
backend: backend, backend: backend,
@ -99,12 +99,12 @@ pub impl FontContext {
option::get_ref(&self.font_list) option::get_ref(&self.font_list)
} }
fn get_resolved_font_for_style(style: &SpecifiedFontStyle) -> @FontGroup { fn get_resolved_font_for_style(&mut self, style: &SpecifiedFontStyle) -> @FontGroup {
// TODO(Issue #178, E): implement a cache of FontGroup instances. // TODO(Issue #178, E): implement a cache of FontGroup instances.
self.create_font_group(style) self.create_font_group(style)
} }
fn get_font_by_descriptor(desc: &FontDescriptor) -> Result<@Font, ()> { fn get_font_by_descriptor(&mut self, desc: &FontDescriptor) -> Result<@mut Font, ()> {
match self.instance_cache.find(desc) { match self.instance_cache.find(desc) {
Some(f) => Ok(f), Some(f) => Ok(f),
None => { None => {
@ -130,7 +130,7 @@ pub impl FontContext {
} }
// TODO:(Issue #196): cache font groups on the font context. // TODO:(Issue #196): cache font groups on the font context.
priv fn create_font_group(style: &SpecifiedFontStyle) -> @FontGroup { priv fn create_font_group(&mut self, style: &SpecifiedFontStyle) -> @FontGroup {
let fonts = DVec(); let fonts = DVec();
debug!("(create font group) --- starting ---"); debug!("(create font group) --- starting ---");
@ -145,11 +145,11 @@ pub impl FontContext {
let result = list.find_font_in_family(transformed_family_name, style); let result = list.find_font_in_family(transformed_family_name, style);
let mut found = false; let mut found = false;
do result.iter |font_entry| { for result.each |font_entry| {
found = true; found = true;
// TODO(Issue #203): route this instantion through FontContext's Font instance cache. // TODO(Issue #203): route this instantion through FontContext's Font instance cache.
let instance = Font::new_from_existing_handle(&self, &font_entry.handle, style, self.backend); let instance = Font::new_from_existing_handle(self, &font_entry.handle, style, self.backend);
do result::iter(&instance) |font: &@Font| { fonts.push(*font); } do result::iter(&instance) |font: &@mut Font| { fonts.push(*font); }
}; };
if !found { if !found {
@ -178,17 +178,17 @@ pub impl FontContext {
@FontGroup::new(style.families.to_managed(), &used_style, dvec::unwrap(fonts)) @FontGroup::new(style.families.to_managed(), &used_style, dvec::unwrap(fonts))
} }
priv fn create_font_instance(desc: &FontDescriptor) -> Result<@Font, ()> { priv fn create_font_instance(&self, desc: &FontDescriptor) -> Result<@mut Font, ()> {
return match &desc.selector { return match &desc.selector {
&SelectorStubDummy => { &SelectorStubDummy => {
Font::new_from_buffer(&self, test_font_bin(), &desc.style, self.backend) Font::new_from_buffer(self, test_font_bin(), &desc.style, self.backend)
}, },
// TODO(Issue #174): implement by-platform-name font selectors. // TODO(Issue #174): implement by-platform-name font selectors.
&SelectorPlatformIdentifier(ref identifier) => { &SelectorPlatformIdentifier(ref identifier) => {
let result_handle = self.handle.create_font_from_identifier(copy *identifier, let result_handle = self.handle.create_font_from_identifier(copy *identifier,
copy desc.style); copy desc.style);
result::chain(result_handle, |handle| { result::chain(result_handle, |handle| {
Ok(Font::new_from_adopted_handle(&self, Ok(Font::new_from_adopted_handle(self,
handle, handle,
&desc.style, &desc.style,
self.backend)) self.backend))

View file

@ -2,7 +2,6 @@ use font::{CSSFontWeight, SpecifiedFontStyle, UsedFontStyle};
use gfx_font::FontHandleMethods; use gfx_font::FontHandleMethods;
use native::FontHandle; use native::FontHandle;
use dvec::DVec;
use core::hashmap::linear; use core::hashmap::linear;
#[cfg(target_os = "linux")] #[cfg(target_os = "linux")]
@ -30,22 +29,22 @@ pub impl FontListHandle {
} }
} }
pub type FontFamilyMap = linear::LinearMap<~str, @FontFamily>; pub type FontFamilyMap = linear::LinearMap<~str, @mut FontFamily>;
trait FontListHandleMethods { trait FontListHandleMethods {
fn get_available_families(&const self, fctx: &native::FontContextHandle) -> FontFamilyMap; fn get_available_families(&const self, fctx: &native::FontContextHandle) -> FontFamilyMap;
fn load_variations_for_family(&const self, family: @FontFamily); fn load_variations_for_family(&const self, family: @mut FontFamily);
} }
pub struct FontList { pub struct FontList {
mut family_map: FontFamilyMap, family_map: FontFamilyMap,
handle: FontListHandle, handle: FontListHandle,
} }
pub impl FontList { pub impl FontList {
static fn new(fctx: &native::FontContextHandle) -> FontList { static fn new(fctx: &native::FontContextHandle) -> FontList {
let handle = result::unwrap(FontListHandle::new(fctx)); let handle = result::unwrap(FontListHandle::new(fctx));
let list = FontList { let mut list = FontList {
handle: handle, handle: handle,
family_map: linear::LinearMap::new(), family_map: linear::LinearMap::new(),
}; };
@ -53,7 +52,7 @@ pub impl FontList {
return list; return list;
} }
priv fn refresh(_fctx: &native::FontContextHandle) { priv fn refresh(&mut self, _fctx: &native::FontContextHandle) {
// TODO(Issue #186): don't refresh unless something actually // TODO(Issue #186): don't refresh unless something actually
// changed. Does OSX have a notification for this event? // changed. Does OSX have a notification for this event?
// //
@ -63,7 +62,8 @@ pub impl FontList {
} }
} }
fn find_font_in_family(family_name: &str, fn find_font_in_family(&self,
family_name: &str,
style: &SpecifiedFontStyle) -> Option<@FontEntry> { style: &SpecifiedFontStyle) -> Option<@FontEntry> {
let family = self.find_family(family_name); let family = self.find_family(family_name);
let mut result : Option<@FontEntry> = None; let mut result : Option<@FontEntry> = None;
@ -71,7 +71,7 @@ pub impl FontList {
// TODO(Issue #192: handle generic font families, like 'serif' and 'sans-serif'. // TODO(Issue #192: handle generic font families, like 'serif' and 'sans-serif'.
// if such family exists, try to match style to a font // if such family exists, try to match style to a font
do family.iter |fam| { for family.each |fam| {
result = fam.find_font_for_style(&self.handle, style); result = fam.find_font_for_style(&self.handle, style);
} }
@ -81,7 +81,7 @@ pub impl FontList {
return result; return result;
} }
priv fn find_family(family_name: &str) -> Option<@FontFamily> { priv fn find_family(&self, family_name: &str) -> Option<@mut FontFamily> {
// look up canonical name // look up canonical name
let family = self.family_map.find(&str::from_slice(family_name)); let family = self.family_map.find(&str::from_slice(family_name));
@ -96,24 +96,24 @@ pub impl FontList {
// Holds a specific font family, and the various // Holds a specific font family, and the various
pub struct FontFamily { pub struct FontFamily {
family_name: ~str, family_name: ~str,
entries: DVec<@FontEntry>, entries: ~[@FontEntry],
} }
pub impl FontFamily { pub impl FontFamily {
static fn new(family_name: &str) -> FontFamily { static fn new(family_name: &str) -> FontFamily {
FontFamily { FontFamily {
family_name: str::from_slice(family_name), family_name: str::from_slice(family_name),
entries: DVec(), entries: ~[],
} }
} }
priv fn load_family_variations(@self, list: &native::FontListHandle) { priv fn load_family_variations(@mut self, list: &native::FontListHandle) {
if self.entries.len() > 0 { return; } if self.entries.len() > 0 { return; }
list.load_variations_for_family(self); list.load_variations_for_family(self);
assert self.entries.len() > 0; assert self.entries.len() > 0;
} }
fn find_font_for_style(@self, list: &native::FontListHandle, style: &SpecifiedFontStyle) -> Option<@FontEntry> { fn find_font_for_style(@mut self, list: &native::FontListHandle, style: &SpecifiedFontStyle) -> Option<@FontEntry> {
self.load_family_variations(list); self.load_family_variations(list);
@ -141,7 +141,7 @@ pub impl FontFamily {
// In the common case, each FontFamily will have a singleton FontEntry, or // In the common case, each FontFamily will have a singleton FontEntry, or
// it will have the standard four faces: Normal, Bold, Italic, BoldItalic. // it will have the standard four faces: Normal, Bold, Italic, BoldItalic.
pub struct FontEntry { pub struct FontEntry {
family: @FontFamily, family: @mut FontFamily,
face_name: ~str, face_name: ~str,
priv weight: CSSFontWeight, priv weight: CSSFontWeight,
priv italic: bool, priv italic: bool,
@ -150,7 +150,7 @@ pub struct FontEntry {
} }
pub impl FontEntry { pub impl FontEntry {
static fn new(family: @FontFamily, handle: FontHandle) -> FontEntry { static fn new(family: @mut FontFamily, handle: FontHandle) -> FontEntry {
FontEntry { FontEntry {
family: family, family: family,
face_name: handle.face_name(), face_name: handle.face_name(),
@ -160,9 +160,9 @@ pub impl FontEntry {
} }
} }
pure fn is_bold() -> bool { pure fn is_bold(&self) -> bool {
self.weight.is_bold() self.weight.is_bold()
} }
pure fn is_italic() -> bool { self.italic } pure fn is_italic(&self) -> bool { self.italic }
} }

View file

@ -1,9 +1,6 @@
extern mod freetype; extern mod freetype;
extern mod fontconfig; extern mod fontconfig;
use fc = fontconfig;
use ft = freetype;
use gfx_font::{FontHandle, FontHandleMethods}; use gfx_font::{FontHandle, FontHandleMethods};
use gfx_font_list::{FontEntry, FontFamily, FontFamilyMap}; use gfx_font_list::{FontEntry, FontFamily, FontFamilyMap};
use gfx_font_context::FontContextHandleMethods; use gfx_font_context::FontContextHandleMethods;
@ -24,8 +21,8 @@ use self::fontconfig::fontconfig::bindgen::{
use core::dvec::DVec; use core::dvec::DVec;
use core::hashmap::linear; use core::hashmap::linear;
use libc::c_int; use core::libc::c_int;
use ptr::Ptr; use core::ptr::Ptr;
use native; use native;
pub struct FontconfigFontListHandle { pub struct FontconfigFontListHandle {
@ -37,7 +34,7 @@ pub impl FontconfigFontListHandle {
FontconfigFontListHandle { fctx: fctx.clone() } FontconfigFontListHandle { fctx: fctx.clone() }
} }
fn get_available_families() -> FontFamilyMap { fn get_available_families(&self) -> FontFamilyMap {
let mut family_map : FontFamilyMap = linear::LinearMap::new(); let mut family_map : FontFamilyMap = linear::LinearMap::new();
unsafe { unsafe {
let config = FcConfigGetCurrent(); let config = FcConfigGetCurrent();
@ -50,7 +47,7 @@ pub impl FontconfigFontListHandle {
while FcPatternGetString(*font, FC_FAMILY, v, &family) == FcResultMatch { while FcPatternGetString(*font, FC_FAMILY, v, &family) == FcResultMatch {
let family_name = str::raw::from_buf(family as *u8); let family_name = str::raw::from_buf(family as *u8);
debug!("Creating new FontFamily for family: %s", family_name); debug!("Creating new FontFamily for family: %s", family_name);
let new_family = @FontFamily::new(family_name); let new_family = @mut FontFamily::new(family_name);
family_map.insert(family_name, new_family); family_map.insert(family_name, new_family);
v += 1; v += 1;
} }
@ -60,7 +57,7 @@ pub impl FontconfigFontListHandle {
return family_map; return family_map;
} }
fn load_variations_for_family(family: @FontFamily) { fn load_variations_for_family(&self, family: @mut FontFamily) {
debug!("getting variations for %?", family); debug!("getting variations for %?", family);
let config = FcConfigGetCurrent(); let config = FcConfigGetCurrent();
let font_set = FcConfigGetFonts(config, FcSetSystem); let font_set = FcConfigGetFonts(config, FcSetSystem);

View file

@ -72,8 +72,8 @@ pub struct FreeTypeFontTable {
bogus: () bogus: ()
} }
pub impl FontTableMethods for FreeTypeFontTable { impl FontTableMethods for FreeTypeFontTable {
fn with_buffer(_blk: fn&(*u8, uint)) { fn with_buffer(&self, _blk: &fn(*u8, uint)) {
fail!() fail!()
} }
} }
@ -185,23 +185,23 @@ pub impl FreeTypeFontHandle {
} }
} }
pub impl FontHandleMethods for FreeTypeFontHandle { impl FontHandleMethods for FreeTypeFontHandle {
// an identifier usable by FontContextHandle to recreate this FontHandle. // an identifier usable by FontContextHandle to recreate this FontHandle.
pure fn face_identifier() -> ~str { pure fn face_identifier(&self) -> ~str {
/* FT_Get_Postscript_Name seems like a better choice here, but it /* FT_Get_Postscript_Name seems like a better choice here, but it
doesn't give usable results for fontconfig when deserializing. */ doesn't give usable results for fontconfig when deserializing. */
unsafe { str::raw::from_c_str((*self.face).family_name) } unsafe { str::raw::from_c_str((*self.face).family_name) }
} }
pure fn family_name() -> ~str { pure fn family_name(&self) -> ~str {
unsafe { str::raw::from_c_str((*self.face).family_name) } unsafe { str::raw::from_c_str((*self.face).family_name) }
} }
pure fn face_name() -> ~str { pure fn face_name(&self) -> ~str {
unsafe { str::raw::from_c_str(FT_Get_Postscript_Name(self.face)) } unsafe { str::raw::from_c_str(FT_Get_Postscript_Name(self.face)) }
} }
pure fn is_italic() -> bool { pure fn is_italic(&self) -> bool {
unsafe { (*self.face).style_flags & FT_STYLE_FLAG_ITALIC != 0 } unsafe { (*self.face).style_flags & FT_STYLE_FLAG_ITALIC != 0 }
} }
pure fn boldness() -> CSSFontWeight { pure fn boldness(&self) -> CSSFontWeight {
let default_weight = FontWeight400; let default_weight = FontWeight400;
if unsafe { (*self.face).style_flags & FT_STYLE_FLAG_BOLD == 0 } { if unsafe { (*self.face).style_flags & FT_STYLE_FLAG_BOLD == 0 } {
default_weight default_weight
@ -228,7 +228,8 @@ pub impl FontHandleMethods for FreeTypeFontHandle {
} }
} }
fn clone_with_style(fctx: &native::FontContextHandle, fn clone_with_style(&self,
fctx: &native::FontContextHandle,
style: &UsedFontStyle) -> Result<FreeTypeFontHandle, ()> { style: &UsedFontStyle) -> Result<FreeTypeFontHandle, ()> {
match self.source { match self.source {
FontSourceMem(buf) => { FontSourceMem(buf) => {
@ -240,7 +241,8 @@ pub impl FontHandleMethods for FreeTypeFontHandle {
} }
} }
pub fn glyph_index(codepoint: char) -> Option<GlyphIndex> { pub fn glyph_index(&self,
codepoint: char) -> Option<GlyphIndex> {
assert self.face.is_not_null(); assert self.face.is_not_null();
let idx = FT_Get_Char_Index(self.face, codepoint as FT_ULong); let idx = FT_Get_Char_Index(self.face, codepoint as FT_ULong);
return if idx != 0 as FT_UInt { return if idx != 0 as FT_UInt {
@ -251,7 +253,8 @@ pub impl FontHandleMethods for FreeTypeFontHandle {
}; };
} }
pub fn glyph_h_advance(glyph: GlyphIndex) -> Option<FractionalPixel> { pub fn glyph_h_advance(&self,
glyph: GlyphIndex) -> Option<FractionalPixel> {
assert self.face.is_not_null(); assert self.face.is_not_null();
let res = FT_Load_Glyph(self.face, glyph as FT_UInt, 0); let res = FT_Load_Glyph(self.face, glyph as FT_UInt, 0);
if res.succeeded() { if res.succeeded() {
@ -271,7 +274,7 @@ pub impl FontHandleMethods for FreeTypeFontHandle {
} }
} }
pub fn get_metrics() -> FontMetrics { pub fn get_metrics(&self) -> FontMetrics {
/* TODO(Issue #76): complete me */ /* TODO(Issue #76): complete me */
let face = self.get_face_rec(); let face = self.get_face_rec();
@ -294,19 +297,19 @@ pub impl FontHandleMethods for FreeTypeFontHandle {
} }
} }
fn get_table_for_tag(_tag: FontTableTag) -> Option<FontTable> { fn get_table_for_tag(&self, _tag: FontTableTag) -> Option<FontTable> {
None None
} }
} }
pub impl FreeTypeFontHandle { pub impl FreeTypeFontHandle {
priv fn get_face_rec() -> &self/FT_FaceRec { priv fn get_face_rec(&self) -> &self/FT_FaceRec {
unsafe { unsafe {
&(*self.face) &(*self.face)
} }
} }
priv fn font_units_to_au(value: float) -> Au { priv fn font_units_to_au(&self, value: float) -> Au {
let face = self.get_face_rec(); let face = self.get_face_rec();

View file

@ -44,16 +44,16 @@ pub impl FreeTypeFontContextHandle {
} }
} }
pub impl FontContextHandleMethods for FreeTypeFontContextHandle { impl FontContextHandleMethods for FreeTypeFontContextHandle {
pure fn clone(&const self) -> FreeTypeFontContextHandle { pure fn clone(&const self) -> FreeTypeFontContextHandle {
FreeTypeFontContextHandle { ctx: self.ctx } FreeTypeFontContextHandle { ctx: self.ctx }
} }
fn create_font_from_identifier(name: ~str, style: UsedFontStyle) -> Result<FontHandle, ()> { fn create_font_from_identifier(&self, name: ~str, style: UsedFontStyle) -> Result<FontHandle, ()> {
debug!("Creating font handle for %s", name); debug!("Creating font handle for %s", name);
do path_from_identifier(name).chain |file_name| { do path_from_identifier(name).chain |file_name| {
debug!("Opening font face %s", file_name); debug!("Opening font face %s", file_name);
FreeTypeFontHandle::new_from_file(&self, file_name, &style) FreeTypeFontHandle::new_from_file(self, file_name, &style)
} }
} }
} }

View file

@ -6,38 +6,38 @@ use core::num::NumCast;
pub struct Au(i32); pub struct Au(i32);
pub impl Add<Au,Au> for Au { impl Add<Au,Au> for Au {
pure fn add(&self, other: &Au) -> Au { Au(**self + **other) } pure fn add(&self, other: &Au) -> Au { Au(**self + **other) }
} }
pub impl Sub<Au,Au> for Au { impl Sub<Au,Au> for Au {
pure fn sub(&self, other: &Au) -> Au { Au(**self - **other) } pure fn sub(&self, other: &Au) -> Au { Au(**self - **other) }
} }
pub impl Mul<Au,Au> for Au { impl Mul<Au,Au> for Au {
pure fn mul(&self, other: &Au) -> Au { Au(**self * **other) } pure fn mul(&self, other: &Au) -> Au { Au(**self * **other) }
} }
pub impl Div<Au,Au> for Au { impl Div<Au,Au> for Au {
pure fn div(&self, other: &Au) -> Au { Au(**self / **other) } pure fn div(&self, other: &Au) -> Au { Au(**self / **other) }
} }
pub impl Modulo<Au,Au> for Au { impl Modulo<Au,Au> for Au {
pure fn modulo(&self, other: &Au) -> Au { Au(**self % **other) } pure fn modulo(&self, other: &Au) -> Au { Au(**self % **other) }
} }
pub impl Neg<Au> for Au { impl Neg<Au> for Au {
pure fn neg(&self) -> Au { Au(-**self) } pure fn neg(&self) -> Au { Au(-**self) }
} }
pub impl cmp::Ord for Au { impl cmp::Ord for Au {
pure fn lt(&self, other: &Au) -> bool { **self < **other } pure fn lt(&self, other: &Au) -> bool { **self < **other }
pure fn le(&self, other: &Au) -> bool { **self <= **other } pure fn le(&self, other: &Au) -> bool { **self <= **other }
pure fn ge(&self, other: &Au) -> bool { **self >= **other } pure fn ge(&self, other: &Au) -> bool { **self >= **other }
pure fn gt(&self, other: &Au) -> bool { **self > **other } pure fn gt(&self, other: &Au) -> bool { **self > **other }
} }
pub impl cmp::Eq for Au { impl cmp::Eq for Au {
pure fn eq(&self, other: &Au) -> bool { **self == **other } pure fn eq(&self, other: &Au) -> bool { **self == **other }
pure fn ne(&self, other: &Au) -> bool { **self != **other } pure fn ne(&self, other: &Au) -> bool { **self != **other }
} }
@ -70,7 +70,7 @@ pub fn box<T:Copy + Ord + Add<T,T> + Sub<T,T>>(x: T, y: T, w: T, h: T) -> Rect<T
} }
pub impl Au { pub impl Au {
pub pure fn scale_by(factor: float) -> Au { pub pure fn scale_by(self, factor: float) -> Au {
Au(((*self as float) * factor) as i32) Au(((*self as float) * factor) as i32)
} }

View file

@ -1,4 +1,4 @@
use io::WriterUtil; use core::io::WriterUtil;
use surface; use surface;
fn encode(writer: io::Writer, surface: &surface::ImageSurface) { fn encode(writer: io::Writer, surface: &surface::ImageSurface) {

View file

@ -17,13 +17,13 @@ use std::arc::{ARC, clone, get};
*/ */
pub struct ImageHolder { pub struct ImageHolder {
url: Url, url: Url,
mut image: Option<ARC<~Image>>, image: Option<ARC<~Image>>,
mut cached_size: Size2D<int>, cached_size: Size2D<int>,
local_image_cache: @LocalImageCache, local_image_cache: @mut LocalImageCache,
} }
impl ImageHolder { pub impl ImageHolder {
static pub fn new(url: Url, local_image_cache: @LocalImageCache) -> ImageHolder { static pub fn new(url: Url, local_image_cache: @mut LocalImageCache) -> ImageHolder {
debug!("ImageHolder::new() %?", url.to_str()); debug!("ImageHolder::new() %?", url.to_str());
let holder = ImageHolder { let holder = ImageHolder {
url: url, url: url,
@ -50,12 +50,12 @@ impl ImageHolder {
The intent is that the impure version is used during layout when The intent is that the impure version is used during layout when
dimensions are used for computing layout. dimensions are used for computing layout.
*/ */
pure fn size() -> Size2D<int> { pure fn size(&self) -> Size2D<int> {
self.cached_size self.cached_size
} }
/** Query and update current image size */ /** Query and update current image size */
fn get_size() -> Option<Size2D<int>> { fn get_size(&mut self) -> Option<Size2D<int>> {
debug!("get_size() %?", self.url); debug!("get_size() %?", self.url);
match self.get_image() { match self.get_image() {
Some(img) => { Some(img) => {
@ -68,7 +68,7 @@ impl ImageHolder {
} }
} }
fn get_image() -> Option<ARC<~Image>> { fn get_image(&mut self) -> Option<ARC<~Image>> {
debug!("get_image() %?", self.url); debug!("get_image() %?", self.url);
// If this is the first time we've called this function, load // If this is the first time we've called this function, load

View file

@ -39,8 +39,8 @@ pub impl QuartzFontTable {
} }
} }
pub impl FontTableMethods for QuartzFontTable { impl FontTableMethods for QuartzFontTable {
fn with_buffer(blk: fn&(*u8, uint)) { fn with_buffer(blk: &fn(*u8, uint)) {
blk(self.data.bytes(), self.data.len()); blk(self.data.bytes(), self.data.len());
} }
} }
@ -129,7 +129,7 @@ impl FontHandleMethods for QuartzFontHandle {
fn glyph_index(codepoint: char) -> Option<GlyphIndex> { fn glyph_index(codepoint: char) -> Option<GlyphIndex> {
let characters: [UniChar * 1] = [codepoint as UniChar]; let characters: [UniChar * 1] = [codepoint as UniChar];
let glyphs: [mut CGGlyph * 1] = [mut 0 as CGGlyph]; let glyphs: [CGGlyph * 1] = [0 as CGGlyph];
let count: CFIndex = 1; let count: CFIndex = 1;
let result = self.ctfont.get_glyphs_for_characters(ptr::to_unsafe_ptr(&characters[0]), let result = self.ctfont.get_glyphs_for_characters(ptr::to_unsafe_ptr(&characters[0]),

View file

@ -22,7 +22,7 @@ pub impl QuartzFontContextHandle {
} }
} }
pub impl FontContextHandleMethods for QuartzFontContextHandle { impl FontContextHandleMethods for QuartzFontContextHandle {
pure fn clone(&const self) -> QuartzFontContextHandle { pure fn clone(&const self) -> QuartzFontContextHandle {
QuartzFontContextHandle { ctx: self.ctx } QuartzFontContextHandle { ctx: self.ctx }
} }

View file

@ -18,12 +18,12 @@ use std::arc;
use std::arc::ARC; use std::arc::ARC;
pub struct RenderContext { pub struct RenderContext {
canvas: &LayerBuffer, canvas: &'self LayerBuffer,
font_ctx: @FontContext, font_ctx: @mut FontContext,
opts: &Opts opts: &'self Opts
} }
impl RenderContext { pub impl<'self> RenderContext<'self> {
pub fn get_draw_target(&self) -> &self/DrawTarget { pub fn get_draw_target(&self) -> &self/DrawTarget {
&self.canvas.draw_target &self.canvas.draw_target
} }
@ -79,27 +79,27 @@ impl RenderContext {
} }
trait to_float { trait to_float {
fn to_float() -> float; fn to_float(self) -> float;
} }
impl to_float for u8 { impl to_float for u8 {
fn to_float() -> float { fn to_float(self) -> float {
(self as float) / 255f (self as float) / 255f
} }
} }
trait ToAzureRect { trait ToAzureRect {
fn to_azure_rect() -> Rect<AzFloat>; fn to_azure_rect(&self) -> Rect<AzFloat>;
fn to_azure_snapped_rect() -> Rect<AzFloat>; fn to_azure_snapped_rect(&self) -> Rect<AzFloat>;
} }
impl ToAzureRect for Rect<Au> { impl ToAzureRect for Rect<Au> {
fn to_azure_rect() -> Rect<AzFloat> { fn to_azure_rect(&self) -> Rect<AzFloat> {
Rect(Point2D(self.origin.x.to_px() as AzFloat, self.origin.y.to_px() as AzFloat), Rect(Point2D(self.origin.x.to_px() as AzFloat, self.origin.y.to_px() as AzFloat),
Size2D(self.size.width.to_px() as AzFloat, self.size.height.to_px() as AzFloat)) Size2D(self.size.width.to_px() as AzFloat, self.size.height.to_px() as AzFloat))
} }
fn to_azure_snapped_rect() -> Rect<AzFloat> { fn to_azure_snapped_rect(&self) -> Rect<AzFloat> {
Rect(Point2D(self.origin.x.to_px() as AzFloat + 0.5f as AzFloat, Rect(Point2D(self.origin.x.to_px() as AzFloat + 0.5f as AzFloat,
self.origin.y.to_px() as AzFloat + 0.5f as AzFloat), self.origin.y.to_px() as AzFloat + 0.5f as AzFloat),
Size2D(self.size.width.to_px() as AzFloat, Size2D(self.size.width.to_px() as AzFloat,

View file

@ -19,9 +19,9 @@ pub struct RenderLayer {
size: Size2D<uint> size: Size2D<uint>
} }
type RenderFn = &fn(layer: *RenderLayer, type RenderFn = &'self fn(layer: *RenderLayer,
buffer: LayerBuffer, buffer: LayerBuffer,
return_buffer: Chan<LayerBuffer>); return_buffer: Chan<LayerBuffer>);
/// Given a layer and a buffer, either reuses the buffer (if it's of the right size and format) /// Given a layer and a buffer, either reuses the buffer (if it's of the right size and format)
/// or creates a new buffer (if it's not of the appropriate size and format) and invokes the /// or creates a new buffer (if it's not of the appropriate size and format) and invokes the

View file

@ -12,11 +12,11 @@ use util::time::time;
use core::libc::size_t; use core::libc::size_t;
use core::libc::types::common::c99::uint16_t; use core::libc::types::common::c99::uint16_t;
use core::cell::Cell;
use core::comm::{Chan, Port, SharedChan}; use core::comm::{Chan, Port, SharedChan};
use core::task::SingleThreaded; use core::task::SingleThreaded;
use std::arc::ARC; use std::arc::ARC;
use std::arc; use std::arc;
use std::cell::Cell;
use std::task_pool::TaskPool; use std::task_pool::TaskPool;
pub enum Msg { pub enum Msg {
@ -45,7 +45,7 @@ pub fn RenderTask<C:Compositor + Owned>(compositor: C, opts: Opts) -> RenderTask
let f: ~fn(uint) -> ThreadRenderContext = |thread_index| { let f: ~fn(uint) -> ThreadRenderContext = |thread_index| {
ThreadRenderContext { ThreadRenderContext {
thread_index: thread_index, thread_index: thread_index,
font_ctx: @FontContext::new(opts_cell.with_ref(|o| o.render_backend), false), font_ctx: @mut FontContext::new(opts_cell.with_ref(|o| o.render_backend), false),
opts: opts_cell.with_ref(|o| copy *o), opts: opts_cell.with_ref(|o| copy *o),
} }
}; };
@ -66,7 +66,7 @@ pub fn RenderTask<C:Compositor + Owned>(compositor: C, opts: Opts) -> RenderTask
/// Data that needs to be kept around for each render thread. /// Data that needs to be kept around for each render thread.
priv struct ThreadRenderContext { priv struct ThreadRenderContext {
thread_index: uint, thread_index: uint,
font_ctx: @FontContext, font_ctx: @mut FontContext,
opts: Opts, opts: Opts,
} }
@ -79,7 +79,7 @@ priv struct Renderer<C> {
} }
impl<C: Compositor + Owned> Renderer<C> { impl<C: Compositor + Owned> Renderer<C> {
fn start() { fn start(&self) {
debug!("renderer: beginning rendering loop"); debug!("renderer: beginning rendering loop");
loop { loop {
@ -93,7 +93,7 @@ impl<C: Compositor + Owned> Renderer<C> {
} }
} }
fn render(render_layer: RenderLayer) { fn render(&self, render_layer: RenderLayer) {
debug!("renderer: got render request"); debug!("renderer: got render request");
let layer_buffer_set_port = self.layer_buffer_set_port.take(); let layer_buffer_set_port = self.layer_buffer_set_port.take();

View file

@ -1,8 +1,8 @@
use comm::Chan; use core::comm::Chan;
use task::spawn; use core::task::spawn;
use resource::resource_task::{ProgressMsg, Payload, Done, LoaderTask}; use resource::resource_task::{ProgressMsg, Payload, Done, LoaderTask};
use std::net::url::Url; use std::net::url::Url;
use io::{file_reader, ReaderUtil}; use core::io::{file_reader, ReaderUtil};
const READ_SIZE: uint = 1024; const READ_SIZE: uint = 1024;

View file

@ -1,7 +1,7 @@
use comm::{Chan, SharedChan}; use core::comm::{Chan, SharedChan};
use task::spawn; use core::task::spawn;
use resource::resource_task::{ProgressMsg, Payload, Done, LoaderTask}; use resource::resource_task::{ProgressMsg, Payload, Done, LoaderTask};
use std::cell::Cell; use core::cell::Cell;
use std::net::url::Url; use std::net::url::Url;
use http_client; use http_client;
use http_client::{uv_http_request}; use http_client::{uv_http_request};
@ -13,7 +13,7 @@ pub fn factory() -> LoaderTask {
let progress_chan = SharedChan(progress_chan); let progress_chan = SharedChan(progress_chan);
do spawn { do spawn {
debug!("http_loader: requesting via http: %?", copy url); debug!("http_loader: requesting via http: %?", copy url);
let request = uv_http_request(copy url); let mut request = uv_http_request(copy url);
let errored = @mut false; let errored = @mut false;
let url = copy url; let url = copy url;
{ {
@ -24,9 +24,8 @@ pub fn factory() -> LoaderTask {
http_client::Status(*) => { } http_client::Status(*) => { }
http_client::Payload(data) => { http_client::Payload(data) => {
debug!("http_loader: got data from %?", url); debug!("http_loader: got data from %?", url);
let mut junk = None; let data = data.take();
*data <-> junk; progress_chan.send(Payload(data));
progress_chan.send(Payload(option::unwrap(junk)));
} }
http_client::Error(*) => { http_client::Error(*) => {
debug!("http_loader: error loading %?", url); debug!("http_loader: error loading %?", url);

View file

@ -11,7 +11,7 @@ use core::to_str::ToStr;
use core::util::replace; use core::util::replace;
use std::arc::ARC; use std::arc::ARC;
use std::net::url::Url; use std::net::url::Url;
use std::cell::Cell; use core::cell::Cell;
pub enum Msg { pub enum Msg {
/// Tell the cache that we may need a particular image soon. Must be posted /// Tell the cache that we may need a particular image soon. Must be posted
@ -36,7 +36,7 @@ pub enum Msg {
pub WaitForImage(Url, Chan<ImageResponseMsg>), pub WaitForImage(Url, Chan<ImageResponseMsg>),
/// For testing /// For testing
priv OnMsg(fn~(msg: &Msg)), priv OnMsg(~fn(msg: &Msg)),
/// Clients must wait for a response before shutting down the ResourceTask /// Clients must wait for a response before shutting down the ResourceTask
pub Exit(Chan<()>) pub Exit(Chan<()>)
@ -49,11 +49,11 @@ pub enum ImageResponseMsg {
} }
impl ImageResponseMsg { impl ImageResponseMsg {
pure fn clone() -> ImageResponseMsg { pure fn clone(&self) -> ImageResponseMsg {
match &self { match *self {
&ImageReady(ref img) => ImageReady(unsafe { clone_arc(img) }), ImageReady(ref img) => ImageReady(unsafe { clone_arc(img) }),
&ImageNotReady => ImageNotReady, ImageNotReady => ImageNotReady,
&ImageFailed => ImageFailed ImageFailed => ImageFailed
} }
} }
} }
@ -98,7 +98,7 @@ pub fn ImageCacheTask_(resource_task: ResourceTask,
let chan_cell = Cell(chan.clone()); let chan_cell = Cell(chan.clone());
do spawn { do spawn {
ImageCache { let mut cache = ImageCache {
resource_task: resource_task.clone(), resource_task: resource_task.clone(),
decoder_factory: decoder_factory_cell.take(), decoder_factory: decoder_factory_cell.take(),
port: port_cell.take(), port: port_cell.take(),
@ -106,7 +106,8 @@ pub fn ImageCacheTask_(resource_task: ResourceTask,
state_map: url_map(), state_map: url_map(),
wait_map: url_map(), wait_map: url_map(),
need_exit: None need_exit: None
}.run(); };
cache.run();
} }
chan chan
@ -152,7 +153,7 @@ struct ImageCache {
state_map: UrlMap<ImageState>, state_map: UrlMap<ImageState>,
/// List of clients waiting on a WaitForImage response /// List of clients waiting on a WaitForImage response
wait_map: UrlMap<@mut ~[Chan<ImageResponseMsg>]>, wait_map: UrlMap<@mut ~[Chan<ImageResponseMsg>]>,
mut need_exit: Option<Chan<()>>, need_exit: Option<Chan<()>>,
} }
enum ImageState { enum ImageState {
@ -172,9 +173,9 @@ enum AfterPrefetch {
#[allow(non_implicitly_copyable_typarams)] #[allow(non_implicitly_copyable_typarams)]
impl ImageCache { impl ImageCache {
pub fn run() { pub fn run(&mut self) {
let mut msg_handlers: ~[fn~(msg: &Msg)] = ~[]; let mut msg_handlers: ~[~fn(msg: &Msg)] = ~[];
loop { loop {
let msg = self.port.recv(); let msg = self.port.recv();
@ -231,18 +232,18 @@ impl ImageCache {
} }
} }
priv fn get_state(url: Url) -> ImageState { priv fn get_state(&self, url: Url) -> ImageState {
match self.state_map.find(&url) { match self.state_map.find(&url) {
Some(state) => state, Some(state) => state,
None => Init None => Init
} }
} }
priv fn set_state(url: Url, state: ImageState) { priv fn set_state(&self, url: Url, state: ImageState) {
self.state_map.insert(url, state); self.state_map.insert(url, state);
} }
priv fn prefetch(url: Url) { priv fn prefetch(&self, url: Url) {
match self.get_state(copy url) { match self.get_state(copy url) {
Init => { Init => {
let to_cache = self.chan.clone(); let to_cache = self.chan.clone();
@ -273,7 +274,7 @@ impl ImageCache {
} }
} }
priv fn store_prefetched_image_data(url: Url, data: Result<Cell<~[u8]>, ()>) { priv fn store_prefetched_image_data(&self, url: Url, data: Result<Cell<~[u8]>, ()>) {
match self.get_state(copy url) { match self.get_state(copy url) {
Prefetching(next_step) => { Prefetching(next_step) => {
match data { match data {
@ -302,7 +303,7 @@ impl ImageCache {
} }
} }
priv fn decode(url: Url) { priv fn decode(&self, url: Url) {
match self.get_state(copy url) { match self.get_state(copy url) {
Init => fail!(~"decoding image before prefetch"), Init => fail!(~"decoding image before prefetch"),
@ -345,7 +346,7 @@ impl ImageCache {
} }
} }
priv fn store_image(url: Url, image: Option<ARC<~Image>>) { priv fn store_image(&self, url: Url, image: Option<ARC<~Image>>) {
match self.get_state(copy url) { match self.get_state(copy url) {
Decoding => { Decoding => {
@ -372,7 +373,7 @@ impl ImageCache {
} }
priv fn purge_waiters(url: Url, f: fn() -> ImageResponseMsg) { priv fn purge_waiters(&self, url: Url, f: fn() -> ImageResponseMsg) {
match self.wait_map.find(&url) { match self.wait_map.find(&url) {
Some(waiters) => { Some(waiters) => {
let waiters = &mut *waiters; let waiters = &mut *waiters;
@ -391,7 +392,7 @@ impl ImageCache {
} }
priv fn get_image(url: Url, response: Chan<ImageResponseMsg>) { priv fn get_image(&self, url: Url, response: Chan<ImageResponseMsg>) {
match self.get_state(copy url) { match self.get_state(copy url) {
Init => fail!(~"request for image before prefetch"), Init => fail!(~"request for image before prefetch"),
@ -416,7 +417,7 @@ impl ImageCache {
} }
} }
priv fn wait_for_image(url: Url, response: Chan<ImageResponseMsg>) { priv fn wait_for_image(&self, url: Url, response: Chan<ImageResponseMsg>) {
match self.get_state(copy url) { match self.get_state(copy url) {
Init => fail!(~"request for image before prefetch"), Init => fail!(~"request for image before prefetch"),
@ -448,11 +449,11 @@ impl ImageCache {
trait ImageCacheTaskClient { trait ImageCacheTaskClient {
fn exit(); fn exit(&self);
} }
impl ImageCacheTaskClient for ImageCacheTask { impl ImageCacheTaskClient for ImageCacheTask {
fn exit() { fn exit(&self) {
let (response_port, response_chan) = stream(); let (response_port, response_chan) = stream();
self.send(Exit(response_chan)); self.send(Exit(response_chan));
response_port.recv(); response_port.recv();
@ -481,7 +482,8 @@ fn load_image_data(url: Url, resource_task: ResourceTask) -> Result<~[u8], ()> {
} }
fn default_decoder_factory() -> ~fn(&[u8]) -> Option<Image> { fn default_decoder_factory() -> ~fn(&[u8]) -> Option<Image> {
fn~(data: &[u8]) -> Option<Image> { load_from_memory(data) } let foo: ~fn(&[u8]) -> Option<Image> = |data: &[u8]| { load_from_memory(data) };
foo
} }
#[cfg(test)] #[cfg(test)]
@ -892,9 +894,9 @@ fn should_return_not_ready_if_image_is_still_decoding() {
}; };
let wait_to_decode_port_cell = Cell(wait_to_decode_port); let wait_to_decode_port_cell = Cell(wait_to_decode_port);
let decoder_factory = fn~() -> ~fn(&[u8]) -> Option<Image> { let decoder_factory = || {
let wait_to_decode_port = wait_to_decode_port_cell.take(); let wait_to_decode_port = wait_to_decode_port_cell.take();
fn~(data: &[u8]) -> Option<Image> { |data: &[u8]| {
// Don't decode until after the client requests the image // Don't decode until after the client requests the image
wait_to_decode_port.recv(); wait_to_decode_port.recv();
load_from_memory(data) load_from_memory(data)

View file

@ -6,7 +6,7 @@ multiple times and thus triggering reflows multiple times.
use clone_arc = std::arc::clone; use clone_arc = std::arc::clone;
use std::net::url::Url; use std::net::url::Url;
use comm::{Port, Chan, stream}; use core::comm::{Port, Chan, stream};
use resource::image_cache_task::{ImageCacheTask, ImageResponseMsg, Prefetch, Decode, GetImage}; use resource::image_cache_task::{ImageCacheTask, ImageResponseMsg, Prefetch, Decode, GetImage};
use resource::image_cache_task::{ WaitForImage, ImageReady, ImageNotReady, ImageFailed}; use resource::image_cache_task::{ WaitForImage, ImageReady, ImageNotReady, ImageFailed};
use util::url::{UrlMap, url_map}; use util::url::{UrlMap, url_map};
@ -22,16 +22,16 @@ pub fn LocalImageCache(image_cache_task: ImageCacheTask) -> LocalImageCache {
pub struct LocalImageCache { pub struct LocalImageCache {
priv image_cache_task: ImageCacheTask, priv image_cache_task: ImageCacheTask,
priv mut round_number: uint, priv round_number: uint,
priv mut on_image_available: Option<@fn() -> ~fn(ImageResponseMsg)>, priv on_image_available: Option<@fn() -> ~fn(ImageResponseMsg)>,
priv state_map: UrlMap<@ImageState> priv state_map: UrlMap<@mut ImageState>
} }
priv struct ImageState { priv struct ImageState {
mut prefetched: bool, prefetched: bool,
mut decoded: bool, decoded: bool,
mut last_request_round: uint, last_request_round: uint,
mut last_response: ImageResponseMsg last_response: ImageResponseMsg
} }
#[allow(non_implicitly_copyable_typarams)] // Using maps of Urls #[allow(non_implicitly_copyable_typarams)] // Using maps of Urls
@ -39,12 +39,12 @@ pub impl LocalImageCache {
/// The local cache will only do a single remote request for a given /// The local cache will only do a single remote request for a given
/// URL in each 'round'. Layout should call this each time it begins /// URL in each 'round'. Layout should call this each time it begins
// FIXME: 'pub' is an unexpected token? // FIXME: 'pub' is an unexpected token?
/* pub */ fn next_round(on_image_available: @fn() -> ~fn(ImageResponseMsg)) { /* pub */ fn next_round(&mut self, on_image_available: @fn() -> ~fn(ImageResponseMsg)) {
self.round_number += 1; self.round_number += 1;
self.on_image_available = Some(on_image_available); self.on_image_available = Some(on_image_available);
} }
pub fn prefetch(url: &Url) { pub fn prefetch(&self, url: &Url) {
let state = self.get_state(url); let state = self.get_state(url);
if !state.prefetched { if !state.prefetched {
self.image_cache_task.send(Prefetch(copy *url)); self.image_cache_task.send(Prefetch(copy *url));
@ -52,7 +52,7 @@ pub impl LocalImageCache {
} }
} }
pub fn decode(url: &Url) { pub fn decode(&self, url: &Url) {
let state = self.get_state(url); let state = self.get_state(url);
if !state.decoded { if !state.decoded {
self.image_cache_task.send(Decode(copy *url)); self.image_cache_task.send(Decode(copy *url));
@ -61,7 +61,7 @@ pub impl LocalImageCache {
} }
// FIXME: Should return a Future // FIXME: Should return a Future
pub fn get_image(url: &Url) -> Port<ImageResponseMsg> { pub fn get_image(&self, url: &Url) -> Port<ImageResponseMsg> {
let state = self.get_state(url); let state = self.get_state(url);
// Save the previous round number for comparison // Save the previous round number for comparison
@ -132,11 +132,11 @@ pub impl LocalImageCache {
return port; return port;
} }
priv fn get_state(url: &Url) -> @ImageState { priv fn get_state(&self, url: &Url) -> @mut ImageState {
match self.state_map.find(url) { match self.state_map.find(url) {
Some(state) => state, Some(state) => state,
None => { None => {
let new_state = @ImageState { let new_state = @mut ImageState {
prefetched: false, prefetched: false,
decoded: false, decoded: false,
last_request_round: 0, last_request_round: 0,

View file

@ -4,9 +4,9 @@ A task that takes a URL and streams back the binary data
*/ */
use comm::{Chan, Port, SharedChan}; use core::cell::Cell;
use core::comm::{Chan, Port, SharedChan};
use resource::util::spawn_listener; use resource::util::spawn_listener;
use std::cell::Cell;
use std::net::url; use std::net::url;
use std::net::url::{Url, to_str}; use std::net::url::{Url, to_str};
use super::{file_loader, http_loader}; use super::{file_loader, http_loader};
@ -76,7 +76,7 @@ pub fn ResourceManager(from_client: Port<ControlMsg>,
impl ResourceManager { impl ResourceManager {
fn start() { fn start(&self) {
loop { loop {
match self.from_client.recv() { match self.from_client.recv() {
Load(url, progress_chan) => { Load(url, progress_chan) => {
@ -89,7 +89,7 @@ impl ResourceManager {
} }
} }
fn load(url: Url, progress_chan: Chan<ProgressMsg>) { fn load(&self, url: Url, progress_chan: Chan<ProgressMsg>) {
match self.get_loader_factory(&url) { match self.get_loader_factory(&url) {
Some(loader_factory) => { Some(loader_factory) => {
@ -103,7 +103,7 @@ impl ResourceManager {
} }
} }
fn get_loader_factory(url: &Url) -> Option<LoaderTask> { fn get_loader_factory(&self, url: &Url) -> Option<LoaderTask> {
for self.loaders.each |scheme_loader| { for self.loaders.each |scheme_loader| {
match *scheme_loader { match *scheme_loader {
(ref scheme, ref loader_factory) => { (ref scheme, ref loader_factory) => {
@ -140,7 +140,7 @@ fn test_bad_scheme() {
#[allow(non_implicitly_copyable_typarams)] #[allow(non_implicitly_copyable_typarams)]
fn should_delegate_to_scheme_loader() { fn should_delegate_to_scheme_loader() {
let payload = ~[1, 2, 3]; let payload = ~[1, 2, 3];
let loader_factory = fn~(_url: Url, progress_chan: Chan<ProgressMsg>, copy payload) { let loader_factory = |_url: Url, progress_chan: Chan<ProgressMsg>| {
progress_chan.send(Payload(copy payload)); progress_chan.send(Payload(copy payload));
progress_chan.send(Done(Ok(()))); progress_chan.send(Done(Ok(())));
}; };

View file

@ -83,10 +83,10 @@ pub mod util {
pub mod vec; pub mod vec;
} }
use servo_util = util; pub use servo_util = util;
use gfx_font = font; pub use gfx_font = font;
use gfx_font_context = font_context; pub use gfx_font_context = font_context;
use gfx_font_list = font_list; pub use gfx_font_list = font_list;
pub use servo_gfx_font = font; pub use servo_gfx_font = font;
pub use servo_gfx_font_list = font_list; pub use servo_gfx_font_list = font_list;
pub use servo_gfx_util = util; pub use servo_gfx_util = util;

View file

@ -7,7 +7,7 @@ pub enum format {
} }
impl format { impl format {
fn bpp() -> uint { fn bpp(self) -> uint {
match self { match self {
fo_rgba_8888 => 32u fo_rgba_8888 => 32u
} }

View file

@ -159,91 +159,91 @@ pure fn MissingGlyphsEntry(glyphCount: uint) -> GlyphEntry {
impl GlyphEntry { impl GlyphEntry {
// getter methods // getter methods
#[inline(always)] #[inline(always)]
pure fn advance() -> Au { pure fn advance(&self) -> Au {
//assert self.is_simple(); //assert self.is_simple();
NumCast::from((self.value & GLYPH_ADVANCE_MASK) >> GLYPH_ADVANCE_SHIFT) NumCast::from((self.value & GLYPH_ADVANCE_MASK) >> GLYPH_ADVANCE_SHIFT)
} }
pure fn index() -> GlyphIndex { pure fn index(&self) -> GlyphIndex {
//assert self.is_simple(); //assert self.is_simple();
self.value & GLYPH_ID_MASK self.value & GLYPH_ID_MASK
} }
pure fn offset() -> Point2D<Au> { pure fn offset(&self) -> Point2D<Au> {
//assert self.is_simple(); //assert self.is_simple();
Point2D(Au(0), Au(0)) Point2D(Au(0), Au(0))
} }
pure fn is_ligature_start() -> bool { pure fn is_ligature_start(&self) -> bool {
self.has_flag(!FLAG_NOT_LIGATURE_GROUP_START) self.has_flag(!FLAG_NOT_LIGATURE_GROUP_START)
} }
pure fn is_cluster_start() -> bool { pure fn is_cluster_start(&self) -> bool {
self.has_flag(!FLAG_NOT_CLUSTER_START) self.has_flag(!FLAG_NOT_CLUSTER_START)
} }
// True if original char was normal (U+0020) space. Other chars may // True if original char was normal (U+0020) space. Other chars may
// map to space glyph, but this does not account for them. // map to space glyph, but this does not account for them.
pure fn char_is_space() -> bool { pure fn char_is_space(&self) -> bool {
self.has_flag(FLAG_CHAR_IS_SPACE) self.has_flag(FLAG_CHAR_IS_SPACE)
} }
pure fn char_is_tab() -> bool { pure fn char_is_tab(&self) -> bool {
!self.is_simple() && self.has_flag(FLAG_CHAR_IS_TAB) !self.is_simple() && self.has_flag(FLAG_CHAR_IS_TAB)
} }
pure fn char_is_newline() -> bool { pure fn char_is_newline(&self) -> bool {
!self.is_simple() && self.has_flag(FLAG_CHAR_IS_NEWLINE) !self.is_simple() && self.has_flag(FLAG_CHAR_IS_NEWLINE)
} }
pure fn can_break_before() -> BreakType { pure fn can_break_before(&self) -> BreakType {
let flag = ((self.value & FLAG_CAN_BREAK_MASK) >> FLAG_CAN_BREAK_SHIFT) as u8; let flag = ((self.value & FLAG_CAN_BREAK_MASK) >> FLAG_CAN_BREAK_SHIFT) as u8;
break_flag_to_enum(flag) break_flag_to_enum(flag)
} }
// setter methods // setter methods
#[inline(always)] #[inline(always)]
pure fn set_char_is_space() -> GlyphEntry { pure fn set_char_is_space(&self) -> GlyphEntry {
GlyphEntry(self.value | FLAG_CHAR_IS_SPACE) GlyphEntry(self.value | FLAG_CHAR_IS_SPACE)
} }
#[inline(always)] #[inline(always)]
pure fn set_char_is_tab() -> GlyphEntry { pure fn set_char_is_tab(&self) -> GlyphEntry {
assert !self.is_simple(); assert !self.is_simple();
GlyphEntry(self.value | FLAG_CHAR_IS_TAB) GlyphEntry(self.value | FLAG_CHAR_IS_TAB)
} }
#[inline(always)] #[inline(always)]
pure fn set_char_is_newline() -> GlyphEntry { pure fn set_char_is_newline(&self) -> GlyphEntry {
assert !self.is_simple(); assert !self.is_simple();
GlyphEntry(self.value | FLAG_CHAR_IS_NEWLINE) GlyphEntry(self.value | FLAG_CHAR_IS_NEWLINE)
} }
#[inline(always)] #[inline(always)]
pure fn set_can_break_before(e: BreakType) -> GlyphEntry { pure fn set_can_break_before(&self, e: BreakType) -> GlyphEntry {
let flag = (break_enum_to_flag(e) as u32) << FLAG_CAN_BREAK_SHIFT; let flag = (break_enum_to_flag(e) as u32) << FLAG_CAN_BREAK_SHIFT;
GlyphEntry(self.value | flag) GlyphEntry(self.value | flag)
} }
// helper methods // helper methods
/*priv*/ pure fn glyph_count() -> u16 { /*priv*/ pure fn glyph_count(&self) -> u16 {
assert !self.is_simple(); assert !self.is_simple();
((self.value & GLYPH_COUNT_MASK) >> GLYPH_COUNT_SHIFT) as u16 ((self.value & GLYPH_COUNT_MASK) >> GLYPH_COUNT_SHIFT) as u16
} }
#[inline(always)] #[inline(always)]
pure fn is_simple() -> bool { pure fn is_simple(&self) -> bool {
self.has_flag(FLAG_IS_SIMPLE_GLYPH) self.has_flag(FLAG_IS_SIMPLE_GLYPH)
} }
#[inline(always)] #[inline(always)]
/*priv*/ pure fn has_flag(flag: u32) -> bool { /*priv*/ pure fn has_flag(&self, flag: u32) -> bool {
(self.value & flag) != 0 (self.value & flag) != 0
} }
#[inline(always)] #[inline(always)]
pure fn adapt_character_flags_of_entry(other: GlyphEntry) -> GlyphEntry { pure fn adapt_character_flags_of_entry(&self, other: GlyphEntry) -> GlyphEntry {
GlyphEntry { value: self.value | other.value } GlyphEntry { value: self.value | other.value }
} }
} }
@ -398,9 +398,9 @@ impl DetailedGlyphStore {
// Thar be dragons here. You have been warned. (Tips accepted.) // Thar be dragons here. You have been warned. (Tips accepted.)
let mut unsorted_records : ~[DetailedGlyphRecord] = ~[]; let mut unsorted_records : ~[DetailedGlyphRecord] = ~[];
core::util::swap(&mut self.detail_lookup, &mut unsorted_records); core::util::swap(&mut self.detail_lookup, &mut unsorted_records);
let mut_records : ~[mut DetailedGlyphRecord] = vec::cast_to_mut(unsorted_records); let mut mut_records : ~[DetailedGlyphRecord] = unsorted_records;
sort::quick_sort3(mut_records); sort::quick_sort3(mut_records);
let mut sorted_records = vec::cast_from_mut(mut_records); let mut sorted_records = mut_records;
core::util::swap(&mut self.detail_lookup, &mut sorted_records); core::util::swap(&mut self.detail_lookup, &mut sorted_records);
self.lookup_is_sorted = true; self.lookup_is_sorted = true;
@ -445,12 +445,12 @@ pub pure fn GlyphData(index: GlyphIndex,
// Rather than eagerly assembling and copying glyph data, it only retrieves // Rather than eagerly assembling and copying glyph data, it only retrieves
// values as they are needed from the GlyphStore, using provided offsets. // values as they are needed from the GlyphStore, using provided offsets.
enum GlyphInfo { enum GlyphInfo {
SimpleGlyphInfo(&GlyphStore, uint), SimpleGlyphInfo(&'self GlyphStore, uint),
DetailGlyphInfo(&GlyphStore, uint, u16) DetailGlyphInfo(&'self GlyphStore, uint, u16)
} }
impl GlyphInfo { impl<'self> GlyphInfo<'self> {
fn index() -> GlyphIndex { fn index(self) -> GlyphIndex {
match self { match self {
SimpleGlyphInfo(store, entry_i) => store.entry_buffer[entry_i].index(), SimpleGlyphInfo(store, entry_i) => store.entry_buffer[entry_i].index(),
DetailGlyphInfo(store, entry_i, detail_j) => store.detail_store.get_detailed_glyph_with_index(entry_i, detail_j).index DetailGlyphInfo(store, entry_i, detail_j) => store.detail_store.get_detailed_glyph_with_index(entry_i, detail_j).index
@ -458,28 +458,28 @@ impl GlyphInfo {
} }
#[inline(always)] #[inline(always)]
fn advance() -> Au { fn advance(self) -> Au {
match self { match self {
SimpleGlyphInfo(store, entry_i) => store.entry_buffer[entry_i].advance(), SimpleGlyphInfo(store, entry_i) => store.entry_buffer[entry_i].advance(),
DetailGlyphInfo(store, entry_i, detail_j) => store.detail_store.get_detailed_glyph_with_index(entry_i, detail_j).advance DetailGlyphInfo(store, entry_i, detail_j) => store.detail_store.get_detailed_glyph_with_index(entry_i, detail_j).advance
} }
} }
fn offset() -> Option<Point2D<Au>> { fn offset(self) -> Option<Point2D<Au>> {
match self { match self {
SimpleGlyphInfo(_, _) => None, SimpleGlyphInfo(_, _) => None,
DetailGlyphInfo(store, entry_i, detail_j) => Some(store.detail_store.get_detailed_glyph_with_index(entry_i, detail_j).offset) DetailGlyphInfo(store, entry_i, detail_j) => Some(store.detail_store.get_detailed_glyph_with_index(entry_i, detail_j).offset)
} }
} }
fn is_ligature_start() -> bool { fn is_ligature_start(self) -> bool {
match self { match self {
SimpleGlyphInfo(store, entry_i) => store.entry_buffer[entry_i].is_ligature_start(), SimpleGlyphInfo(store, entry_i) => store.entry_buffer[entry_i].is_ligature_start(),
DetailGlyphInfo(store, entry_i, _) => store.entry_buffer[entry_i].is_ligature_start() DetailGlyphInfo(store, entry_i, _) => store.entry_buffer[entry_i].is_ligature_start()
} }
} }
fn is_cluster_start() -> bool { fn is_cluster_start(self) -> bool {
match self { match self {
SimpleGlyphInfo(store, entry_i) => store.entry_buffer[entry_i].is_cluster_start(), SimpleGlyphInfo(store, entry_i) => store.entry_buffer[entry_i].is_cluster_start(),
DetailGlyphInfo(store, entry_i, _) => store.entry_buffer[entry_i].is_cluster_start() DetailGlyphInfo(store, entry_i, _) => store.entry_buffer[entry_i].is_cluster_start()
@ -573,20 +573,20 @@ pub impl GlyphStore {
self.entry_buffer[i] = entry; self.entry_buffer[i] = entry;
} }
pure fn iter_glyphs_for_char_index(i: uint, cb: fn&(uint, GlyphInfo/&) -> bool) -> bool { pure fn iter_glyphs_for_char_index(&self, i: uint, cb: &fn(uint, GlyphInfo/&) -> bool) -> bool {
assert i < self.entry_buffer.len(); assert i < self.entry_buffer.len();
let entry = &self.entry_buffer[i]; let entry = &self.entry_buffer[i];
match entry.is_simple() { match entry.is_simple() {
true => { true => {
let proxy = SimpleGlyphInfo(&self, i); let proxy = SimpleGlyphInfo(self, i);
cb(i, proxy); cb(i, proxy);
}, },
false => { false => {
let glyphs = self.detail_store.get_detailed_glyphs_for_entry(i, let glyphs = self.detail_store.get_detailed_glyphs_for_entry(i,
entry.glyph_count()); entry.glyph_count());
for uint::range(0, glyphs.len()) |j| { for uint::range(0, glyphs.len()) |j| {
let proxy = DetailGlyphInfo(&self, i, j as u16); let proxy = DetailGlyphInfo(self, i, j as u16);
cb(i, proxy); cb(i, proxy);
} }
} }
@ -594,7 +594,7 @@ pub impl GlyphStore {
return true; return true;
} }
pure fn iter_glyphs_for_char_range(range: &const Range, cb: fn&(uint, GlyphInfo/&) -> bool) { pure fn iter_glyphs_for_char_range(&self, range: &const Range, cb: &fn(uint, GlyphInfo/&) -> bool) {
if range.begin() >= self.entry_buffer.len() { if range.begin() >= self.entry_buffer.len() {
error!("iter_glyphs_for_range: range.begin beyond length!"); error!("iter_glyphs_for_range: range.begin beyond length!");
return; return;
@ -609,39 +609,39 @@ pub impl GlyphStore {
} }
} }
pure fn iter_all_glyphs(cb: fn&(uint, GlyphInfo/&) -> bool) { pure fn iter_all_glyphs(&self, cb: &fn(uint, GlyphInfo/&) -> bool) {
for uint::range(0, self.entry_buffer.len()) |i| { for uint::range(0, self.entry_buffer.len()) |i| {
if !self.iter_glyphs_for_char_index(i, cb) { break; } if !self.iter_glyphs_for_char_index(i, cb) { break; }
} }
} }
// getter methods // getter methods
pure fn char_is_space(i: uint) -> bool { pure fn char_is_space(&self, i: uint) -> bool {
assert i < self.entry_buffer.len(); assert i < self.entry_buffer.len();
self.entry_buffer[i].char_is_space() self.entry_buffer[i].char_is_space()
} }
pure fn char_is_tab(i: uint) -> bool { pure fn char_is_tab(&self, i: uint) -> bool {
assert i < self.entry_buffer.len(); assert i < self.entry_buffer.len();
self.entry_buffer[i].char_is_tab() self.entry_buffer[i].char_is_tab()
} }
pure fn char_is_newline(i: uint) -> bool { pure fn char_is_newline(&self, i: uint) -> bool {
assert i < self.entry_buffer.len(); assert i < self.entry_buffer.len();
self.entry_buffer[i].char_is_newline() self.entry_buffer[i].char_is_newline()
} }
pure fn is_ligature_start(i: uint) -> bool { pure fn is_ligature_start(&self, i: uint) -> bool {
assert i < self.entry_buffer.len(); assert i < self.entry_buffer.len();
self.entry_buffer[i].is_ligature_start() self.entry_buffer[i].is_ligature_start()
} }
pure fn is_cluster_start(i: uint) -> bool { pure fn is_cluster_start(&self, i: uint) -> bool {
assert i < self.entry_buffer.len(); assert i < self.entry_buffer.len();
self.entry_buffer[i].is_cluster_start() self.entry_buffer[i].is_cluster_start()
} }
pure fn can_break_before(i: uint) -> BreakType { pure fn can_break_before(&self, i: uint) -> BreakType {
assert i < self.entry_buffer.len(); assert i < self.entry_buffer.len();
self.entry_buffer[i].can_break_before() self.entry_buffer[i].can_break_before()
} }

View file

@ -15,7 +15,7 @@ use util::range::Range;
use core::libc::types::common::c99::int32_t; use core::libc::types::common::c99::int32_t;
use core::libc::{c_uint, c_int, c_void, c_char}; use core::libc::{c_uint, c_int, c_void, c_char};
use core::util::ignore; use core::util::ignore;
use dvec::DVec; //use dvec::DVec;
use std::arc; use std::arc;
use text::harfbuzz::shaper::harfbuzz::{HB_MEMORY_MODE_READONLY, HB_DIRECTION_LTR, hb_blob_t}; use text::harfbuzz::shaper::harfbuzz::{HB_MEMORY_MODE_READONLY, HB_DIRECTION_LTR, hb_blob_t};
@ -106,10 +106,10 @@ pub impl ShapedGlyphData {
} }
} }
pure fn len() -> uint { self.count } pure fn len(&self) -> uint { self.count }
// Returns shaped glyph data for one glyph, and updates the y-position of the pen. // Returns shaped glyph data for one glyph, and updates the y-position of the pen.
fn get_entry_for_glyph(i: uint, y_pos: &mut Au) -> ShapedGlyphEntry { fn get_entry_for_glyph(&self, i: uint, y_pos: &mut Au) -> ShapedGlyphEntry {
assert i < self.count; assert i < self.count;
let glyph_info_i = ptr::offset(self.glyph_infos, i); let glyph_info_i = ptr::offset(self.glyph_infos, i);
@ -142,7 +142,7 @@ pub impl ShapedGlyphData {
} }
pub struct HarfbuzzShaper { pub struct HarfbuzzShaper {
font: @Font, font: @mut Font,
priv hb_face: *hb_face_t, priv hb_face: *hb_face_t,
priv hb_font: *hb_font_t, priv hb_font: *hb_font_t,
priv hb_funcs: *hb_font_funcs_t, priv hb_funcs: *hb_font_funcs_t,
@ -160,7 +160,7 @@ pub struct HarfbuzzShaper {
} }
pub impl HarfbuzzShaper { pub impl HarfbuzzShaper {
static pub fn new(font: @Font) -> HarfbuzzShaper { static pub fn new(font: @mut Font) -> HarfbuzzShaper {
let hb_face: *hb_face_t = hb_face_create_for_tables(get_font_table_func, ptr::to_unsafe_ptr(font) as *c_void, ptr::null()); let hb_face: *hb_face_t = hb_face_create_for_tables(get_font_table_func, ptr::to_unsafe_ptr(font) as *c_void, ptr::null());
let hb_font: *hb_font_t = hb_font_create(hb_face); let hb_font: *hb_font_t = hb_font_create(hb_face);
// Set points-per-em. if zero, performs no hinting in that direction. // Set points-per-em. if zero, performs no hinting in that direction.
@ -207,7 +207,7 @@ impl ShaperMethods for HarfbuzzShaper {
Calculate the layout metrics associated with a some given text Calculate the layout metrics associated with a some given text
when rendered in a specific font. when rendered in a specific font.
*/ */
fn shape_text(text: &str, glyphs: &mut GlyphStore) { fn shape_text(&self, text: &str, glyphs: &mut GlyphStore) {
let hb_buffer: *hb_buffer_t = hb_buffer_create(); let hb_buffer: *hb_buffer_t = hb_buffer_create();
hb_buffer_set_direction(hb_buffer, HB_DIRECTION_LTR); hb_buffer_set_direction(hb_buffer, HB_DIRECTION_LTR);
@ -228,7 +228,7 @@ impl ShaperMethods for HarfbuzzShaper {
pub impl HarfbuzzShaper { pub impl HarfbuzzShaper {
priv fn save_glyph_results(text: &str, glyphs: &mut GlyphStore, buffer: *hb_buffer_t) { priv fn save_glyph_results(&self, text: &str, glyphs: &mut GlyphStore, buffer: *hb_buffer_t) {
let glyph_data = ShapedGlyphData::new(buffer); let glyph_data = ShapedGlyphData::new(buffer);
let glyph_count = glyph_data.len(); let glyph_count = glyph_data.len();
let byte_max = text.len(); let byte_max = text.len();
@ -403,7 +403,7 @@ pub impl HarfbuzzShaper {
glyphs.add_glyph_for_char_index(char_idx, &data); glyphs.add_glyph_for_char_index(char_idx, &data);
} else { } else {
// collect all glyphs to be assigned to the first character. // collect all glyphs to be assigned to the first character.
let datas = DVec(); let mut datas = ~[];
for glyph_span.eachi |glyph_i| { for glyph_span.eachi |glyph_i| {
let shape = glyph_data.get_entry_for_glyph(glyph_i, &mut y_pos); let shape = glyph_data.get_entry_for_glyph(glyph_i, &mut y_pos);
@ -417,7 +417,7 @@ pub impl HarfbuzzShaper {
} }
// now add the detailed glyph entry. // now add the detailed glyph entry.
glyphs.add_glyphs_for_char_index(char_idx, dvec::unwrap(datas)); glyphs.add_glyphs_for_char_index(char_idx, datas);
// set the other chars, who have no glyphs // set the other chars, who have no glyphs
let mut i = covered_byte_span.begin(); let mut i = covered_byte_span.begin();

View file

@ -6,18 +6,18 @@ Currently, only harfbuzz bindings are implemented.
*/ */
use gfx_font::Font; use gfx_font::Font;
use text::glyph::GlyphStore; use text::glyph::GlyphStore;
use harfbuzz; use text::harfbuzz;
pub type Shaper/& = harfbuzz::shaper::HarfbuzzShaper; pub type Shaper/& = harfbuzz::shaper::HarfbuzzShaper;
pub trait ShaperMethods { pub trait ShaperMethods {
fn shape_text(text: &str, glyphs: &mut GlyphStore); fn shape_text(&self, text: &str, glyphs: &mut GlyphStore);
} }
// TODO(Issue #163): this is a workaround for static methods and // TODO(Issue #163): this is a workaround for static methods and
// typedefs not working well together. It should be removed. // typedefs not working well together. It should be removed.
pub impl Shaper { pub impl Shaper {
static pub fn new(font: @Font) -> Shaper { static pub fn new(font: @mut Font) -> Shaper {
harfbuzz::shaper::HarfbuzzShaper::new(font) harfbuzz::shaper::HarfbuzzShaper::new(font)
} }
} }

View file

@ -12,7 +12,7 @@ use std::arc::ARC;
pub struct TextRun { pub struct TextRun {
text: ~str, text: ~str,
font: @Font, font: @mut Font,
glyphs: GlyphStore, glyphs: GlyphStore,
} }
@ -25,7 +25,7 @@ pub struct SendableTextRun {
} }
impl SendableTextRun { impl SendableTextRun {
pub fn deserialize(&self, fctx: @FontContext) -> TextRun { pub fn deserialize(&self, fctx: @mut FontContext) -> TextRun {
let font = match fctx.get_font_by_descriptor(&self.font) { let font = match fctx.get_font_by_descriptor(&self.font) {
Ok(f) => f, Ok(f) => f,
Err(_) => fail!(fmt!("Font descriptor deserialization failed! desc=%?", self.font)) Err(_) => fail!(fmt!("Font descriptor deserialization failed! desc=%?", self.font))
@ -40,7 +40,7 @@ impl SendableTextRun {
} }
pub impl TextRun { pub impl TextRun {
static fn new(font: @Font, text: ~str) -> TextRun { static fn new(font: @mut Font, text: ~str) -> TextRun {
let mut glyph_store = GlyphStore::new(str::char_len(text)); let mut glyph_store = GlyphStore::new(str::char_len(text));
TextRun::compute_potential_breaks(text, &mut glyph_store); TextRun::compute_potential_breaks(text, &mut glyph_store);
font.shape_text(text, &mut glyph_store); font.shape_text(text, &mut glyph_store);
@ -103,7 +103,7 @@ pub impl TextRun {
} }
} }
pure fn char_len() -> uint { self.glyphs.entry_buffer.len() } pure fn char_len(&self) -> uint { self.glyphs.entry_buffer.len() }
pure fn glyphs(&self) -> &self/GlyphStore { &self.glyphs } pure fn glyphs(&self) -> &self/GlyphStore { &self.glyphs }
pure fn range_is_trimmable_whitespace(&self, range: &const Range) -> bool { pure fn range_is_trimmable_whitespace(&self, range: &const Range) -> bool {

View file

@ -2,33 +2,33 @@ use core::cmp::*;
pub trait Cache<K: Copy + Eq, V: Copy> { pub trait Cache<K: Copy + Eq, V: Copy> {
static fn new(size: uint) -> Self; static fn new(size: uint) -> Self;
fn insert(key: &K, value: V); fn insert(&mut self, key: &K, value: V);
fn find(key: &K) -> Option<V>; fn find(&self, key: &K) -> Option<V>;
fn find_or_create(key: &K, blk: pure fn&(&K) -> V) -> V; fn find_or_create(&mut self, key: &K, blk: &pure fn(&K) -> V) -> V;
fn evict_all(); fn evict_all(&mut self);
} }
pub struct MonoCache<K, V> { pub struct MonoCache<K, V> {
mut entry: Option<(K,V)>, entry: Option<(K,V)>,
} }
pub impl<K: Copy + Eq, V: Copy> Cache<K,V> for MonoCache<K,V> { impl<K: Copy + Eq, V: Copy> Cache<K,V> for MonoCache<K,V> {
static fn new(_size: uint) -> MonoCache<K,V> { static fn new(_size: uint) -> MonoCache<K,V> {
MonoCache { entry: None } MonoCache { entry: None }
} }
fn insert(key: &K, value: V) { fn insert(&mut self, key: &K, value: V) {
self.entry = Some((copy *key, value)); self.entry = Some((copy *key, value));
} }
fn find(key: &K) -> Option<V> { fn find(&self, key: &K) -> Option<V> {
match self.entry { match self.entry {
None => None, None => None,
Some((ref k,v)) => if *k == *key { Some(v) } else { None } Some((ref k,v)) => if *k == *key { Some(v) } else { None }
} }
} }
fn find_or_create(key: &K, blk: pure fn&(&K) -> V) -> V { fn find_or_create(&mut self, key: &K, blk: &pure fn(&K) -> V) -> V {
return match self.find(key) { return match self.find(key) {
None => { None => {
let value = blk(key); let value = blk(key);
@ -38,7 +38,7 @@ pub impl<K: Copy + Eq, V: Copy> Cache<K,V> for MonoCache<K,V> {
Some(v) => v Some(v) => v
}; };
} }
fn evict_all() { fn evict_all(&mut self) {
self.entry = None; self.entry = None;
} }
} }

View file

@ -27,7 +27,7 @@ pub impl Range {
pure fn begin(&const self) -> uint { self.off } pure fn begin(&const self) -> uint { self.off }
pure fn length(&const self) -> uint { self.len } pure fn length(&const self) -> uint { self.len }
pure fn end(&const self) -> uint { self.off + self.len } pure fn end(&const self) -> uint { self.off + self.len }
pure fn eachi(&const self, cb: fn&(uint) -> bool) { pure fn eachi(&const self, cb: &fn(uint) -> bool) {
do uint::range(self.off, self.off + self.len) |i| { cb(i) } do uint::range(self.off, self.off + self.len) |i| { cb(i) }
} }

View file

@ -28,7 +28,7 @@ pub fn make_url(str_url: ~str, current_url: Option<Url>) -> Url {
} else { } else {
let path = str::split_char(current_url.path, '/'); let path = str::split_char(current_url.path, '/');
let path = path.init(); let path = path.init();
let path = str::connect(path + ~[str_url], "/"); let path = str::connect(path.map(|x| copy *x) + ~[str_url], "/");
current_url.scheme + "://" + current_url.host + path current_url.scheme + "://" + current_url.host + path
} }

View file

@ -5,7 +5,7 @@ pub trait BinarySearchMethods<T: Ord + Eq> {
pure fn binary_search_index(&self, key: &T) -> Option<uint>; pure fn binary_search_index(&self, key: &T) -> Option<uint>;
} }
pub impl<T: Ord + Eq> BinarySearchMethods<T> for &[T] { impl<'self, T: Ord + Eq> BinarySearchMethods<T> for &'self [T] {
pure fn binary_search(&self, key: &T) -> Option<&self/T> { pure fn binary_search(&self, key: &T) -> Option<&self/T> {
match self.binary_search_index(key) { match self.binary_search_index(key) {
None => None, None => None,

View file

@ -13,6 +13,7 @@ use layout::layout_task::{AddStylesheet, BuildData, BuildMsg, Damage, LayoutTask
use layout::layout_task::{MatchSelectorsDamage, NoDamage, ReflowDamage}; use layout::layout_task::{MatchSelectorsDamage, NoDamage, ReflowDamage};
use util::task::spawn_listener; use util::task::spawn_listener;
use core::cell::Cell;
use core::comm::{Port, Chan, SharedChan}; use core::comm::{Port, Chan, SharedChan};
use core::pipes::select2i; use core::pipes::select2i;
use core::either; use core::either;
@ -33,7 +34,6 @@ use js::rust::{Compartment, Cx};
use jsrt = js::rust::rt; use jsrt = js::rust::rt;
use newcss::stylesheet::Stylesheet; use newcss::stylesheet::Stylesheet;
use std::arc::{ARC, clone}; use std::arc::{ARC, clone};
use std::cell::Cell;
use std::net::url::Url; use std::net::url::Url;
use url_to_str = std::net::url::to_str; use url_to_str = std::net::url::to_str;
use dom; use dom;
@ -82,7 +82,7 @@ pub fn ContentTask(layout_task: LayoutTask,
pub struct Content { pub struct Content {
layout_task: LayoutTask, layout_task: LayoutTask,
mut layout_join_port: Option<comm::Port<()>>, layout_join_port: Option<comm::Port<()>>,
image_cache_task: ImageCacheTask, image_cache_task: ImageCacheTask,
control_port: comm::Port<ControlMsg>, control_port: comm::Port<ControlMsg>,
@ -93,17 +93,17 @@ pub struct Content {
jsrt: jsrt, jsrt: jsrt,
cx: @Cx, cx: @Cx,
mut document: Option<@Document>, document: Option<@Document>,
mut window: Option<@Window>, window: Option<@Window>,
mut doc_url: Option<Url>, doc_url: Option<Url>,
mut window_size: Size2D<uint>, window_size: Size2D<uint>,
resource_task: ResourceTask, resource_task: ResourceTask,
compartment: Option<@mut Compartment>, compartment: Option<@mut Compartment>,
// What parts of layout are dirty. // What parts of layout are dirty.
mut damage: Damage, damage: Damage,
} }
pub fn Content(layout_task: LayoutTask, pub fn Content(layout_task: LayoutTask,
@ -113,7 +113,7 @@ pub fn Content(layout_task: LayoutTask,
img_cache_task: ImageCacheTask, img_cache_task: ImageCacheTask,
event_port: comm::Port<Event>, event_port: comm::Port<Event>,
event_chan: comm::SharedChan<Event>) event_chan: comm::SharedChan<Event>)
-> @Content { -> @mut Content {
let jsrt = jsrt(); let jsrt = jsrt();
let cx = jsrt.cx(); let cx = jsrt.cx();
@ -125,7 +125,7 @@ pub fn Content(layout_task: LayoutTask,
Err(()) => None Err(()) => None
}; };
let content = @Content { let content = @mut Content {
layout_task: layout_task, layout_task: layout_task,
layout_join_port: None, layout_join_port: None,
image_cache_task: img_cache_task, image_cache_task: img_cache_task,
@ -153,28 +153,34 @@ pub fn Content(layout_task: LayoutTask,
content content
} }
pub fn task_from_context(cx: *JSContext) -> *Content { pub fn task_from_context(cx: *JSContext) -> *mut Content {
unsafe { unsafe {
cast::reinterpret_cast(&JS_GetContextPrivate(cx)) cast::reinterpret_cast(&JS_GetContextPrivate(cx))
} }
} }
#[allow(non_implicitly_copyable_typarams)] #[allow(non_implicitly_copyable_typarams)]
impl Content { pub impl Content {
fn start() { fn start(&mut self) {
while self.handle_msg() { while self.handle_msg() {
// Go on ... // Go on ...
} }
} }
fn handle_msg() -> bool { fn handle_msg(&mut self) -> bool {
match select2i(&self.control_port, &self.event_port) { match select2i(&self.control_port, &self.event_port) {
either::Left(*) => self.handle_control_msg(self.control_port.recv()), either::Left(*) => {
either::Right(*) => self.handle_event(self.event_port.recv()) let msg = self.control_port.recv();
self.handle_control_msg(msg)
}
either::Right(*) => {
let ev = self.event_port.recv();
self.handle_event(ev)
}
} }
} }
fn handle_control_msg(control_msg: ControlMsg) -> bool { fn handle_control_msg(&mut self, control_msg: ControlMsg) -> bool {
match control_msg { match control_msg {
ParseMsg(url) => { ParseMsg(url) => {
debug!("content: Received url `%s` to parse", url_to_str(&url)); debug!("content: Received url `%s` to parse", url_to_str(&url));
@ -269,7 +275,7 @@ impl Content {
Sends a ping to layout and waits for the response (i.e., it has finished any Sends a ping to layout and waits for the response (i.e., it has finished any
pending layout request messages). pending layout request messages).
*/ */
fn join_layout(&self) { fn join_layout(&mut self) {
if self.layout_join_port.is_some() { if self.layout_join_port.is_some() {
let join_port = replace(&mut self.layout_join_port, None); let join_port = replace(&mut self.layout_join_port, None);
match join_port { match join_port {
@ -290,7 +296,7 @@ impl Content {
join the layout task, and then request a new layout run. It won't wait for the join the layout task, and then request a new layout run. It won't wait for the
new layout computation to finish. new layout computation to finish.
*/ */
fn relayout(document: &Document, doc_url: &Url) { fn relayout(&mut self, document: &Document, doc_url: &Url) {
debug!("content: performing relayout"); debug!("content: performing relayout");
// Now, join the layout so that they will see the latest // Now, join the layout so that they will see the latest
@ -317,7 +323,7 @@ impl Content {
debug!("content: layout forked"); debug!("content: layout forked");
} }
fn query_layout(query: layout_task::LayoutQuery) -> layout_task::LayoutQueryResponse { fn query_layout(&mut self, query: layout_task::LayoutQuery) -> layout_task::LayoutQueryResponse {
self.relayout(self.document.get(), &(copy self.doc_url).get()); self.relayout(self.document.get(), &(copy self.doc_url).get());
self.join_layout(); self.join_layout();
@ -330,7 +336,7 @@ impl Content {
This is the main entry point for receiving and dispatching DOM events. This is the main entry point for receiving and dispatching DOM events.
*/ */
// TODO: actually perform DOM event dispatch. // TODO: actually perform DOM event dispatch.
fn handle_event(event: Event) -> bool { fn handle_event(&mut self, event: Event) -> bool {
match event { match event {
ResizeEvent(new_width, new_height, response_chan) => { ResizeEvent(new_width, new_height, response_chan) => {
debug!("content got resize event: %u, %u", new_width, new_height); debug!("content got resize event: %u, %u", new_width, new_height);

View file

@ -8,7 +8,7 @@ pub trait NodeUtil {
fn set_css_select_results(self, decl: CompleteSelectResults); fn set_css_select_results(self, decl: CompleteSelectResults);
} }
impl NodeUtil for AbstractNode { impl<'self> NodeUtil<'self> for AbstractNode {
/** /**
* Provides the computed style for the given node. If CSS selector * Provides the computed style for the given node. If CSS selector
* Returns the style results for the given node. If CSS selector * Returns the style results for the given node. If CSS selector

View file

@ -1,6 +1,6 @@
use std::net::url::Url; use std::net::url::Url;
use url_from_str = std::net::url::from_str; use url_from_str = std::net::url::from_str;
use std::cell::Cell; use core::cell::Cell;
use newcss::stylesheet::Stylesheet; use newcss::stylesheet::Stylesheet;
use newcss::select::SelectCtx; use newcss::select::SelectCtx;
use newcss::types::OriginUA; use newcss::types::OriginUA;

View file

@ -21,11 +21,11 @@ fn with_node_name<R>(node: AbstractNode, f: &fn(&str) -> R) -> R {
} }
impl SelectHandler<AbstractNode> for NodeSelectHandler { impl SelectHandler<AbstractNode> for NodeSelectHandler {
fn with_node_name<R>(node: &AbstractNode, f: &fn(&str) -> R) -> R { fn with_node_name<R>(&self, node: &AbstractNode, f: &fn(&str) -> R) -> R {
with_node_name(*node, f) with_node_name(*node, f)
} }
fn named_parent_node(node: &AbstractNode, name: &str) -> Option<AbstractNode> { fn named_parent_node(&self, node: &AbstractNode, name: &str) -> Option<AbstractNode> {
match node.parent_node() { match node.parent_node() {
Some(parent) => { Some(parent) => {
do with_node_name(parent) |node_name| { do with_node_name(parent) |node_name| {
@ -40,12 +40,12 @@ impl SelectHandler<AbstractNode> for NodeSelectHandler {
} }
} }
fn parent_node(node: &AbstractNode) -> Option<AbstractNode> { fn parent_node(&self, node: &AbstractNode) -> Option<AbstractNode> {
node.parent_node() node.parent_node()
} }
// TODO: Use a Bloom filter. // TODO: Use a Bloom filter.
fn named_ancestor_node(node: &AbstractNode, name: &str) -> Option<AbstractNode> { fn named_ancestor_node(&self, node: &AbstractNode, name: &str) -> Option<AbstractNode> {
let mut node = *node; let mut node = *node;
loop { loop {
let parent = node.parent_node(); let parent = node.parent_node();
@ -67,11 +67,11 @@ impl SelectHandler<AbstractNode> for NodeSelectHandler {
} }
} }
fn node_is_root(node: &AbstractNode) -> bool { fn node_is_root(&self, node: &AbstractNode) -> bool {
self.parent_node(node).is_none() self.parent_node(node).is_none()
} }
fn with_node_id<R>(node: &AbstractNode, f: &fn(Option<&str>) -> R) -> R { fn with_node_id<R>(&self, node: &AbstractNode, f: &fn(Option<&str>) -> R) -> R {
if !node.is_element() { if !node.is_element() {
fail!(~"attempting to style non-element node"); fail!(~"attempting to style non-element node");
} }
@ -80,7 +80,7 @@ impl SelectHandler<AbstractNode> for NodeSelectHandler {
} }
} }
fn node_has_id(node: &AbstractNode, id: &str) -> bool { fn node_has_id(&self, node: &AbstractNode, id: &str) -> bool {
if !node.is_element() { if !node.is_element() {
fail!(~"attempting to style non-element node"); fail!(~"attempting to style non-element node");
} }

View file

@ -9,8 +9,8 @@ use js::jsapi::bindgen::{JS_ValueToString, JS_GetStringCharsZAndLength, JS_Repor
use js::glue::bindgen::*; use js::glue::bindgen::*;
use js::glue::{PROPERTY_STUB, STRICT_PROPERTY_STUB}; use js::glue::{PROPERTY_STUB, STRICT_PROPERTY_STUB};
use js::crust::{JS_PropertyStub, JS_StrictPropertyStub, JS_EnumerateStub, JS_ConvertStub, JS_ResolveStub}; use js::crust::{JS_PropertyStub, JS_StrictPropertyStub, JS_EnumerateStub, JS_ConvertStub, JS_ResolveStub};
use ptr::null; use core::ptr::null;
use libc::c_uint; use core::libc::c_uint;
use dom::bindings::utils::{DOMString, domstring_to_jsval, rust_box, squirrel_away, str}; use dom::bindings::utils::{DOMString, domstring_to_jsval, rust_box, squirrel_away, str};
use dom::bindings::node::create; use dom::bindings::node::create;

View file

@ -114,7 +114,7 @@ extern fn HTMLImageElement_setWidth(cx: *JSContext, _argc: c_uint, vp: *mut JSVa
ElementNodeTypeId(HTMLImageElementTypeId) => { ElementNodeTypeId(HTMLImageElementTypeId) => {
do node.as_mut_element |elem| { do node.as_mut_element |elem| {
let arg = ptr::offset(JS_ARGV(cx, cast::reinterpret_cast(&vp)), 0); let arg = ptr::offset(JS_ARGV(cx, cast::reinterpret_cast(&vp)), 0);
elem.set_attr(~"width", int::str(RUST_JSVAL_TO_INT(*arg) as int)) elem.set_attr(~"width", (RUST_JSVAL_TO_INT(*arg) as int).to_str())
} }
} }
ElementNodeTypeId(_) => fail!(~"why is this not an image element?"), ElementNodeTypeId(_) => fail!(~"why is this not an image element?"),

View file

@ -10,7 +10,8 @@ use js::jsapi::bindgen::{JS_ValueToString, JS_GetStringCharsZAndLength, JS_Repor
use js::glue::{PROPERTY_STUB, STRICT_PROPERTY_STUB, ENUMERATE_STUB, CONVERT_STUB, use js::glue::{PROPERTY_STUB, STRICT_PROPERTY_STUB, ENUMERATE_STUB, CONVERT_STUB,
RESOLVE_STUB}; RESOLVE_STUB};
use js::glue::bindgen::*; use js::glue::bindgen::*;
use ptr::null; use core::ptr::null;
use core::cast;
use content::content_task::{Content, task_from_context}; use content::content_task::{Content, task_from_context};
pub enum DOMString { pub enum DOMString {

View file

@ -9,6 +9,7 @@ use super::utils;
use core::dvec::DVec; use core::dvec::DVec;
use core::libc::c_uint; use core::libc::c_uint;
use core::ptr::null; use core::ptr::null;
use core::ptr;
use js::crust::{JS_PropertyStub, JS_StrictPropertyStub, JS_EnumerateStub, JS_ConvertStub}; use js::crust::{JS_PropertyStub, JS_StrictPropertyStub, JS_EnumerateStub, JS_ConvertStub};
use js::crust::{JS_ResolveStub}; use js::crust::{JS_ResolveStub};
use js::global::jsval_to_rust_str; use js::global::jsval_to_rust_str;

View file

@ -5,7 +5,7 @@
use dom::node::{ElementNodeTypeId, Node}; use dom::node::{ElementNodeTypeId, Node};
use core::str::eq_slice; use core::str::eq_slice;
use std::cell::Cell; use core::cell::Cell;
use std::net::url::Url; use std::net::url::Url;
pub struct Element { pub struct Element {
@ -107,7 +107,7 @@ pub struct HTMLImageElement {
// Element methods // Element methods
// //
impl Element { pub impl Element {
static pub fn new(type_id: ElementTypeId, tag_name: ~str) -> Element { static pub fn new(type_id: ElementTypeId, tag_name: ~str) -> Element {
Element { Element {
parent: Node::new(ElementNodeTypeId(type_id)), parent: Node::new(ElementNodeTypeId(type_id)),

View file

@ -62,7 +62,7 @@ pub enum NodeTypeId {
pub struct LayoutData { pub struct LayoutData {
style: Option<CompleteSelectResults>, style: Option<CompleteSelectResults>,
flow: Option<@FlowContext>, flow: Option<@mut FlowContext>,
} }
impl LayoutData { impl LayoutData {
@ -130,7 +130,7 @@ impl Text {
} }
} }
impl AbstractNode { pub impl AbstractNode {
// //
// Convenience accessors // Convenience accessors
// //

View file

@ -1,8 +1,9 @@
use core::comm::{Port, Chan};
use content::content_task::{ControlMsg, Timer, ExitMsg}; use content::content_task::{ControlMsg, Timer, ExitMsg};
use js::jsapi::JSVal; use js::jsapi::JSVal;
use dvec::DVec;
use util::task::spawn_listener; use util::task::spawn_listener;
use core::comm::{Port, Chan};
use core::dvec::DVec;
use std::timer; use std::timer;
use std::uv_global_loop; use std::uv_global_loop;
@ -47,7 +48,7 @@ pub fn TimerData(argc: libc::c_uint, argv: *JSVal) -> TimerData {
// FIXME: delayed_send shouldn't require Copy // FIXME: delayed_send shouldn't require Copy
#[allow(non_implicitly_copyable_typarams)] #[allow(non_implicitly_copyable_typarams)]
impl Window { pub impl Window {
fn alert(s: &str) { fn alert(s: &str) {
// Right now, just print to the console // Right now, just print to the console
io::println(fmt!("ALERT: %s", s)); io::println(fmt!("ALERT: %s", s));

View file

@ -8,12 +8,12 @@ use resource::resource_task::ResourceTask;
use resource::resource_task; use resource::resource_task;
use util::task::spawn_listener; use util::task::spawn_listener;
use core::cell::Cell;
use core::comm::{Port, Chan}; use core::comm::{Port, Chan};
use gfx::compositor::Compositor; use gfx::compositor::Compositor;
use gfx::opts::Opts; use gfx::opts::Opts;
use gfx::render_task::RenderTask; use gfx::render_task::RenderTask;
use gfx::render_task; use gfx::render_task;
use std::cell::Cell;
use std::net::url::Url; use std::net::url::Url;
pub type EngineTask = Chan<Msg>; pub type EngineTask = Chan<Msg>;

View file

@ -4,12 +4,12 @@ Some little helpers for hooking up the HTML parser with the CSS parser
use resource::resource_task::{ResourceTask, ProgressMsg, Load, Payload, Done}; use resource::resource_task::{ResourceTask, ProgressMsg, Load, Payload, Done};
use core::cell::Cell;
use core::comm::{Port, Chan}; use core::comm::{Port, Chan};
use core::pipes; use core::pipes;
use core::str; use core::str;
use newcss::stylesheet::Stylesheet; use newcss::stylesheet::Stylesheet;
use newcss::util::DataStream; use newcss::util::DataStream;
use std::cell::Cell;
use std::net::url::Url; use std::net::url::Url;
use std::net::url; use std::net::url;

View file

@ -9,12 +9,12 @@ use resource::image_cache_task;
use resource::resource_task::{Done, Load, Payload, ResourceTask}; use resource::resource_task::{Done, Load, Payload, ResourceTask};
use util::task::{spawn_listener, spawn_conversation}; use util::task::{spawn_listener, spawn_conversation};
use core::cell::Cell;
use core::comm::{Chan, Port, SharedChan}; use core::comm::{Chan, Port, SharedChan};
use core::str::eq_slice; use core::str::eq_slice;
use gfx::util::url::make_url; use gfx::util::url::make_url;
use hubbub::hubbub::Attribute; use hubbub::hubbub::Attribute;
use hubbub::hubbub; use hubbub::hubbub;
use std::cell::Cell;
use std::net::url::Url; use std::net::url::Url;
use std::net::url; use std::net::url;
@ -237,7 +237,7 @@ pub fn parse_html(url: Url,
let root = ~HTMLHtmlElement { parent: Element::new(HTMLHtmlElementTypeId, ~"html") }; let root = ~HTMLHtmlElement { parent: Element::new(HTMLHtmlElementTypeId, ~"html") };
let root = unsafe { Node::as_abstract_node(root) }; let root = unsafe { Node::as_abstract_node(root) };
debug!("created new node"); debug!("created new node");
let parser = hubbub::Parser("UTF-8", false); let mut parser = hubbub::Parser("UTF-8", false);
debug!("created parser"); debug!("created parser");
parser.set_document_node(root.to_hubbub_node()); parser.set_document_node(root.to_hubbub_node());
parser.enable_scripting(true); parser.enable_scripting(true);

View file

@ -17,7 +17,7 @@ use gfx::display_list::DisplayList;
use gfx::geometry::Au; use gfx::geometry::Au;
pub struct BlockFlowData { pub struct BlockFlowData {
mut box: Option<@RenderBox> box: Option<@mut RenderBox>
} }
pub fn BlockFlowData() -> BlockFlowData { pub fn BlockFlowData() -> BlockFlowData {
@ -28,12 +28,12 @@ pub fn BlockFlowData() -> BlockFlowData {
pub trait BlockLayout { pub trait BlockLayout {
pure fn starts_block_flow() -> bool; pure fn starts_block_flow() -> bool;
pure fn with_block_box(@self, fn(box: &@RenderBox) -> ()) -> (); pure fn with_block_box(@mut self, fn(box: &@mut RenderBox) -> ()) -> ();
fn bubble_widths_block(@self, ctx: &LayoutContext); fn bubble_widths_block(@mut self, ctx: &LayoutContext);
fn assign_widths_block(@self, ctx: &LayoutContext); fn assign_widths_block(@mut self, ctx: &LayoutContext);
fn assign_height_block(@self, ctx: &LayoutContext); fn assign_height_block(@mut self, ctx: &LayoutContext);
fn build_display_list_block(@self, fn build_display_list_block(@mut self,
a: &DisplayListBuilder, a: &DisplayListBuilder,
b: &Rect<Au>, b: &Rect<Au>,
c: &Point2D<Au>, c: &Point2D<Au>,
@ -50,15 +50,15 @@ impl BlockLayout for FlowContext {
/* Get the current flow's corresponding block box, if it exists, and do something with it. /* Get the current flow's corresponding block box, if it exists, and do something with it.
This works on both BlockFlow and RootFlow, since they are mostly the same. */ This works on both BlockFlow and RootFlow, since they are mostly the same. */
pure fn with_block_box(@self, cb: fn(box: &@RenderBox) -> ()) -> () { pure fn with_block_box(@mut self, cb: fn(box: &@mut RenderBox) -> ()) -> () {
match *self { match *self {
BlockFlow(*) => { BlockFlow(*) => {
let mut box = self.block().box; let box = self.block().box;
box.iter(cb); for box.each |b| { cb(b); }
}, },
RootFlow(*) => { RootFlow(*) => {
let mut box = self.root().box; let mut box = self.root().box;
box.iter(cb); for box.each |b| { cb(b); }
}, },
_ => fail!(fmt!("Tried to do something with_block_box(), but this is a %?", self)) _ => fail!(fmt!("Tried to do something with_block_box(), but this is a %?", self))
} }
@ -73,7 +73,7 @@ impl BlockLayout for FlowContext {
/* TODO: floats */ /* TODO: floats */
/* TODO: absolute contexts */ /* TODO: absolute contexts */
/* TODO: inline-blocks */ /* TODO: inline-blocks */
fn bubble_widths_block(@self, ctx: &LayoutContext) { fn bubble_widths_block(@mut self, ctx: &LayoutContext) {
assert self.starts_block_flow(); assert self.starts_block_flow();
let mut min_width = Au(0); let mut min_width = Au(0);
@ -105,7 +105,7 @@ impl BlockLayout for FlowContext {
Dual boxes consume some width first, and the remainder is assigned to Dual boxes consume some width first, and the remainder is assigned to
all child (block) contexts. */ all child (block) contexts. */
fn assign_widths_block(@self, _ctx: &LayoutContext) { fn assign_widths_block(@mut self, _ctx: &LayoutContext) {
assert self.starts_block_flow(); assert self.starts_block_flow();
let mut remaining_width = self.d().position.size.width; let mut remaining_width = self.d().position.size.width;
@ -127,7 +127,7 @@ impl BlockLayout for FlowContext {
} }
} }
fn assign_height_block(@self, _ctx: &LayoutContext) { fn assign_height_block(@mut self, _ctx: &LayoutContext) {
assert self.starts_block_flow(); assert self.starts_block_flow();
let mut cur_y = Au(0); let mut cur_y = Au(0);
@ -149,7 +149,7 @@ impl BlockLayout for FlowContext {
} }
} }
fn build_display_list_block(@self, builder: &DisplayListBuilder, dirty: &Rect<Au>, fn build_display_list_block(@mut self, builder: &DisplayListBuilder, dirty: &Rect<Au>,
offset: &Point2D<Au>, list: &Mut<DisplayList>) { offset: &Point2D<Au>, list: &Mut<DisplayList>) {
assert self.starts_block_flow(); assert self.starts_block_flow();

View file

@ -3,7 +3,7 @@
use css::node_style::StyledNode; use css::node_style::StyledNode;
use dom::node::AbstractNode; use dom::node::AbstractNode;
use layout::context::LayoutContext; use layout::context::LayoutContext;
use layout::debug::BoxedDebugMethods; use layout::debug::BoxedMutDebugMethods;
use layout::display_list_builder::DisplayListBuilder; use layout::display_list_builder::DisplayListBuilder;
use layout::flow::FlowContext; use layout::flow::FlowContext;
use layout::text::TextBoxData; use layout::text::TextBoxData;
@ -80,15 +80,15 @@ pub struct RenderBoxData {
node : AbstractNode, node : AbstractNode,
/* reference to containing flow context, which this box /* reference to containing flow context, which this box
participates in */ participates in */
ctx : @FlowContext, ctx : @mut FlowContext,
/* position of this box relative to owning flow */ /* position of this box relative to owning flow */
mut position : Rect<Au>, position : Rect<Au>,
font_size : Length, font_size : Length,
/* TODO (Issue #87): debug only */ /* TODO (Issue #87): debug only */
mut id: int id: int
} }
enum RenderBoxType { pub enum RenderBoxType {
RenderBox_Generic, RenderBox_Generic,
RenderBox_Image, RenderBox_Image,
RenderBox_Text, RenderBox_Text,
@ -102,31 +102,35 @@ pub enum RenderBox {
} }
pub enum SplitBoxResult { pub enum SplitBoxResult {
CannotSplit(@RenderBox), CannotSplit(@mut RenderBox),
// in general, when splitting the left or right side can // in general, when splitting the left or right side can
// be zero length, due to leading/trailing trimmable whitespace // be zero length, due to leading/trailing trimmable whitespace
SplitDidFit(Option<@RenderBox>, Option<@RenderBox>), SplitDidFit(Option<@mut RenderBox>, Option<@mut RenderBox>),
SplitDidNotFit(Option<@RenderBox>, Option<@RenderBox>) SplitDidNotFit(Option<@mut RenderBox>, Option<@mut RenderBox>)
} }
pub fn RenderBoxData(node: AbstractNode, ctx: @FlowContext, id: int) -> RenderBoxData { pub fn RenderBoxData(node: AbstractNode, ctx: @mut FlowContext, id: int) -> RenderBoxData {
RenderBoxData { RenderBoxData {
node : node, node : node,
mut ctx : ctx, ctx : ctx,
mut position : Au::zero_rect(), position : Au::zero_rect(),
font_size: Px(0.0), font_size: Px(0.0),
id : id id : id
} }
} }
impl RenderBox { impl RenderBox {
pure fn d(&self) -> &self/RenderBoxData { pure fn d(&mut self) -> &self/mut RenderBoxData {
match *self { unsafe {
GenericBox(ref d) => d, //Rust #5074 - we can't take mutable references to the
ImageBox(ref d, _) => d, // data that needs to be returned right now.
TextBox(ref d, _) => d, match self {
UnscannedTextBox(ref d, _) => d, &GenericBox(ref d) => cast::transmute(d),
&ImageBox(ref d, _) => cast::transmute(d),
&TextBox(ref d, _) => cast::transmute(d),
&UnscannedTextBox(ref d, _) => cast::transmute(d),
} }
}
} }
pure fn is_replaced() -> bool { pure fn is_replaced() -> bool {
@ -150,8 +154,8 @@ impl RenderBox {
} }
} }
fn can_merge_with_box(@self, other: @RenderBox) -> bool { fn can_merge_with_box(@mut self, other: @mut RenderBox) -> bool {
assert !managed::ptr_eq(self, other); assert !managed::mut_ptr_eq(self, other);
match (self, other) { match (self, other) {
(@UnscannedTextBox(*), @UnscannedTextBox(*)) => { (@UnscannedTextBox(*), @UnscannedTextBox(*)) => {
@ -162,7 +166,7 @@ impl RenderBox {
} }
} }
fn split_to_width(@self, _ctx: &LayoutContext, max_width: Au, starts_line: bool) -> SplitBoxResult { fn split_to_width(@mut self, _ctx: &LayoutContext, max_width: Au, starts_line: bool) -> SplitBoxResult {
match self { match self {
@GenericBox(*) => CannotSplit(self), @GenericBox(*) => CannotSplit(self),
@ImageBox(*) => CannotSplit(self), @ImageBox(*) => CannotSplit(self),
@ -238,31 +242,31 @@ impl RenderBox {
* may cause glyphs to be allocated. For now, it's impure because of * may cause glyphs to be allocated. For now, it's impure because of
* holder.get_image() * holder.get_image()
*/ */
fn get_min_width(_ctx: &LayoutContext) -> Au { fn get_min_width(&mut self, _ctx: &LayoutContext) -> Au {
match &self { match *self {
// TODO: this should account for min/pref widths of the // TODO: this should account for min/pref widths of the
// box element in isolation. That includes // box element in isolation. That includes
// border/margin/padding but not child widths. The block // border/margin/padding but not child widths. The block
// FlowContext will combine the width of this element and // FlowContext will combine the width of this element and
// that of its children to arrive at the context width. // that of its children to arrive at the context width.
&GenericBox(*) => Au(0), GenericBox(*) => Au(0),
// TODO: consult CSS 'width', margin, border. // TODO: consult CSS 'width', margin, border.
// TODO: If image isn't available, consult 'width'. // TODO: If image isn't available, consult 'width'.
&ImageBox(_, ref i) => Au::from_px(i.get_size().get_or_default(Size2D(0,0)).width), ImageBox(_, ref mut i) => Au::from_px(i.get_size().get_or_default(Size2D(0,0)).width),
&TextBox(_,d) => d.run.min_width_for_range(&const d.range), TextBox(_,d) => d.run.min_width_for_range(&const d.range),
&UnscannedTextBox(*) => fail!(~"Shouldn't see unscanned boxes here.") UnscannedTextBox(*) => fail!(~"Shouldn't see unscanned boxes here.")
} }
} }
fn get_pref_width(_ctx: &LayoutContext) -> Au { fn get_pref_width(&mut self, _ctx: &LayoutContext) -> Au {
match &self { match self {
// TODO: this should account for min/pref widths of the // TODO: this should account for min/pref widths of the
// box element in isolation. That includes // box element in isolation. That includes
// border/margin/padding but not child widths. The block // border/margin/padding but not child widths. The block
// FlowContext will combine the width of this element and // FlowContext will combine the width of this element and
// that of its children to arrive at the context width. // that of its children to arrive at the context width.
&GenericBox(*) => Au(0), &GenericBox(*) => Au(0),
&ImageBox(_, ref i) => Au::from_px(i.get_size().get_or_default(Size2D(0,0)).width), &ImageBox(_, ref mut i) => Au::from_px(i.get_size().get_or_default(Size2D(0,0)).width),
// a text box cannot span lines, so assume that this is an unsplit text box. // a text box cannot span lines, so assume that this is an unsplit text box.
@ -306,12 +310,13 @@ impl RenderBox {
/* The box formed by the content edge, as defined in CSS 2.1 Section 8.1. /* The box formed by the content edge, as defined in CSS 2.1 Section 8.1.
Coordinates are relative to the owning flow. */ Coordinates are relative to the owning flow. */
pure fn content_box() -> Rect<Au> { pure fn content_box(&mut self) -> Rect<Au> {
match &self { let origin = {copy self.d().position.origin};
&ImageBox(_, ref i) => { match self {
&ImageBox(_, ref mut i) => {
let size = i.size(); let size = i.size();
Rect { Rect {
origin: copy self.d().position.origin, origin: origin,
size: Size2D(Au::from_px(size.width), size: Size2D(Au::from_px(size.width),
Au::from_px(size.height)) Au::from_px(size.height))
} }
@ -340,24 +345,24 @@ impl RenderBox {
/* The box formed by the border edge, as defined in CSS 2.1 Section 8.1. /* The box formed by the border edge, as defined in CSS 2.1 Section 8.1.
Coordinates are relative to the owning flow. */ Coordinates are relative to the owning flow. */
pure fn border_box() -> Rect<Au> { pure fn border_box(&mut self) -> Rect<Au> {
// TODO: actually compute content_box + padding + border // TODO: actually compute content_box + padding + border
self.content_box() self.content_box()
} }
/* The box fromed by the margin edge, as defined in CSS 2.1 Section 8.1. /* The box fromed by the margin edge, as defined in CSS 2.1 Section 8.1.
Coordinates are relative to the owning flow. */ Coordinates are relative to the owning flow. */
pure fn margin_box() -> Rect<Au> { pure fn margin_box(&mut self) -> Rect<Au> {
// TODO: actually compute content_box + padding + border + margin // TODO: actually compute content_box + padding + border + margin
self.content_box() self.content_box()
} }
fn style(&self) -> CompleteStyle/&self { fn style(&mut self) -> CompleteStyle/&self {
let d: &self/RenderBoxData = self.d(); let d: &self/mut RenderBoxData = self.d();
d.node.style() d.node.style()
} }
fn with_style_of_nearest_element<R>(@self, f: &fn(CompleteStyle) -> R) -> R { fn with_style_of_nearest_element<R>(@mut self, f: &fn(CompleteStyle) -> R) -> R {
let mut node = self.d().node; let mut node = self.d().node;
while !node.is_element() { while !node.is_element() {
node = node.parent_node().get(); node = node.parent_node().get();
@ -383,7 +388,7 @@ impl RenderBox {
* `origin` - Total offset from display list root flow to this box's owning flow * `origin` - Total offset from display list root flow to this box's owning flow
* `list` - List to which items should be appended * `list` - List to which items should be appended
*/ */
fn build_display_list(@self, _builder: &DisplayListBuilder, dirty: &Rect<Au>, fn build_display_list(@mut self, _builder: &DisplayListBuilder, dirty: &Rect<Au>,
offset: &Point2D<Au>, list: &Mut<DisplayList>) { offset: &Point2D<Au>, list: &Mut<DisplayList>) {
let box_bounds = self.d().position; let box_bounds = self.d().position;
@ -401,9 +406,10 @@ impl RenderBox {
self.add_bgcolor_to_list(list, &abs_box_bounds); self.add_bgcolor_to_list(list, &abs_box_bounds);
match self { let m = &mut *self;
@UnscannedTextBox(*) => fail!(~"Shouldn't see unscanned boxes here."), match m {
@TextBox(_,data) => { &UnscannedTextBox(*) => fail!(~"Shouldn't see unscanned boxes here."),
&TextBox(_,data) => {
do list.borrow_mut |list| { do list.borrow_mut |list| {
let nearest_ancestor_element = self.nearest_ancestor_element(); let nearest_ancestor_element = self.nearest_ancestor_element();
let color = nearest_ancestor_element.style().color().to_gfx_color(); let color = nearest_ancestor_element.style().color().to_gfx_color();
@ -430,8 +436,9 @@ impl RenderBox {
} }
}, },
// TODO: items for background, border, outline // TODO: items for background, border, outline
@GenericBox(_) => {} &GenericBox(_) => {}
@ImageBox(_, ref i) => { &ImageBox(_, ref mut i) => {
//let i: &mut ImageHolder = unsafe { cast::transmute(i) }; // Rust #5074
match i.get_image() { match i.get_image() {
Some(image) => { Some(image) => {
do list.borrow_mut |list| { do list.borrow_mut |list| {
@ -451,7 +458,7 @@ impl RenderBox {
self.add_border_to_list(list, &abs_box_bounds); self.add_border_to_list(list, &abs_box_bounds);
} }
fn add_bgcolor_to_list(@self, list: &Mut<DisplayList>, abs_bounds: &Rect<Au>) { fn add_bgcolor_to_list(&mut self, list: &Mut<DisplayList>, abs_bounds: &Rect<Au>) {
use std::cmp::FuzzyEq; use std::cmp::FuzzyEq;
// FIXME: This causes a lot of background colors to be displayed when they are clearly not // FIXME: This causes a lot of background colors to be displayed when they are clearly not
@ -468,7 +475,7 @@ impl RenderBox {
} }
} }
fn add_border_to_list(list: &Mut<DisplayList>, abs_bounds: &Rect<Au>) { fn add_border_to_list(&mut self, list: &Mut<DisplayList>, abs_bounds: &Rect<Au>) {
if !self.d().node.is_element() { return } if !self.d().node.is_element() { return }
let top_width = self.style().border_top_width(); let top_width = self.style().border_top_width();
@ -523,7 +530,7 @@ impl RenderBox {
} }
// Converts this node's ComputedStyle to a font style used in the graphics code. // Converts this node's ComputedStyle to a font style used in the graphics code.
fn font_style(@self) -> FontStyle { fn font_style(@mut self) -> FontStyle {
do self.with_style_of_nearest_element |my_style| { do self.with_style_of_nearest_element |my_style| {
let font_families = do my_style.font_family().map |family| { let font_families = do my_style.font_family().map |family| {
match *family { match *family {
@ -564,20 +571,20 @@ impl RenderBox {
} }
// Converts this node's ComputedStyle to a text alignment used in the inline layout code. // Converts this node's ComputedStyle to a text alignment used in the inline layout code.
fn text_align(@self) -> CSSTextAlign { fn text_align(@mut self) -> CSSTextAlign {
do self.with_style_of_nearest_element |my_style| { do self.with_style_of_nearest_element |my_style| {
my_style.text_align() my_style.text_align()
} }
} }
} }
impl BoxedDebugMethods for RenderBox { impl BoxedMutDebugMethods for RenderBox {
pure fn dump(@self) { pure fn dump(@mut self) {
self.dump_indent(0u); self.dump_indent(0u);
} }
/* Dumps the node tree, for debugging, with indentation. */ /* Dumps the node tree, for debugging, with indentation. */
pure fn dump_indent(@self, indent: uint) { pure fn dump_indent(@mut self, indent: uint) {
let mut s = ~""; let mut s = ~"";
for uint::range(0u, indent) |_i| { for uint::range(0u, indent) |_i| {
s += ~" "; s += ~" ";
@ -587,7 +594,7 @@ impl BoxedDebugMethods for RenderBox {
debug!("%s", s); debug!("%s", s);
} }
pure fn debug_str(@self) -> ~str { pure fn debug_str(@mut self) -> ~str {
let repr = match self { let repr = match self {
@GenericBox(*) => ~"GenericBox", @GenericBox(*) => ~"GenericBox",
@ImageBox(*) => ~"ImageBox", @ImageBox(*) => ~"ImageBox",
@ -602,7 +609,7 @@ impl BoxedDebugMethods for RenderBox {
// Other methods // Other methods
impl RenderBox { impl RenderBox {
/// Returns the nearest ancestor-or-self element node. Infallible. /// Returns the nearest ancestor-or-self element node. Infallible.
fn nearest_ancestor_element(@self) -> AbstractNode { fn nearest_ancestor_element(&mut self) -> AbstractNode {
let mut node = self.d().node; let mut node = self.d().node;
while !node.is_element() { while !node.is_element() {
match node.parent_node() { match node.parent_node() {

View file

@ -7,9 +7,9 @@ use dom;
use layout::block::BlockFlowData; use layout::block::BlockFlowData;
use layout::box::*; use layout::box::*;
use layout::context::LayoutContext; use layout::context::LayoutContext;
use layout::debug::{BoxedDebugMethods, DebugMethods}; use layout::debug::{BoxedMutDebugMethods, DebugMethods};
use layout::flow::*; use layout::flow::*;
use layout::inline::InlineFlowData; use layout::inline::{InlineFlowData, InlineLayout};
use layout::root::RootFlowData; use layout::root::RootFlowData;
use util::tree; use util::tree;
@ -20,9 +20,9 @@ use newcss::values::{CSSDisplay, CSSDisplayBlock, CSSDisplayInline, CSSDisplayIn
use newcss::values::{CSSDisplayNone, Inherit, Specified}; use newcss::values::{CSSDisplayNone, Inherit, Specified};
pub struct LayoutTreeBuilder { pub struct LayoutTreeBuilder {
mut root_flow: Option<@FlowContext>, root_flow: Option<@mut FlowContext>,
mut next_bid: int, next_bid: int,
mut next_cid: int next_cid: int
} }
pub impl LayoutTreeBuilder { pub impl LayoutTreeBuilder {
@ -38,7 +38,7 @@ pub impl LayoutTreeBuilder {
// helper object for building the initial box list and making the // helper object for building the initial box list and making the
// mapping between DOM nodes and boxes. // mapping between DOM nodes and boxes.
struct BoxGenerator { struct BoxGenerator {
flow: @FlowContext, flow: @mut FlowContext,
range_stack: DVec<uint>, range_stack: DVec<uint>,
} }
@ -80,7 +80,7 @@ priv fn simulate_UA_display_rules(node: AbstractNode) -> CSSDisplay {
} }
impl BoxGenerator { impl BoxGenerator {
static pure fn new(flow: @FlowContext) -> BoxGenerator { static pure fn new(flow: @mut FlowContext) -> BoxGenerator {
unsafe { debug!("Creating box generator for flow: %s", flow.debug_str()); } unsafe { debug!("Creating box generator for flow: %s", flow.debug_str()); }
BoxGenerator { BoxGenerator {
flow: flow, flow: flow,
@ -97,11 +97,11 @@ impl BoxGenerator {
fn make_inline_spacer_for_node_side(_: &LayoutContext, fn make_inline_spacer_for_node_side(_: &LayoutContext,
_: AbstractNode, _: AbstractNode,
_: InlineSpacerSide) _: InlineSpacerSide)
-> Option<@RenderBox> { -> Option<@mut RenderBox> {
None None
} }
pub fn push_node(ctx: &LayoutContext, builder: &LayoutTreeBuilder, node: AbstractNode) { pub fn push_node(&mut self, ctx: &LayoutContext, builder: &mut LayoutTreeBuilder, node: AbstractNode) {
debug!("BoxGenerator[f%d]: pushing node: %s", self.flow.d().id, node.debug_str()); debug!("BoxGenerator[f%d]: pushing node: %s", self.flow.d().id, node.debug_str());
// first, determine the box type, based on node characteristics // first, determine the box type, based on node characteristics
@ -123,12 +123,14 @@ impl BoxGenerator {
// if a leaf, make a box. // if a leaf, make a box.
if node.is_leaf() { if node.is_leaf() {
let new_box = builder.make_box(ctx, box_type, node, self.flow); let new_box = builder.make_box(ctx, box_type, node, self.flow);
self.flow.inline().boxes.push(new_box); let boxes = &mut self.flow.inline().boxes;
boxes.push(new_box);
} else if self.inline_spacers_needed_for_node(node) { } else if self.inline_spacers_needed_for_node(node) {
// else, maybe make a spacer for "left" margin, border, padding // else, maybe make a spacer for "left" margin, border, padding
do self.make_inline_spacer_for_node_side(ctx, node, LogicalBefore).iter for self.make_inline_spacer_for_node_side(ctx, node, LogicalBefore).each
|spacer: &@RenderBox| { |spacer: &@mut RenderBox| {
self.flow.inline().boxes.push(*spacer); let boxes = &mut self.flow.inline().boxes;
boxes.push(*spacer);
} }
} }
// TODO: cases for inline-block, etc. // TODO: cases for inline-block, etc.
@ -156,7 +158,7 @@ impl BoxGenerator {
} }
} }
pub fn pop_node(ctx: &LayoutContext, _builder: &LayoutTreeBuilder, node: AbstractNode) { pub fn pop_node(&mut self, ctx: &LayoutContext, _builder: &LayoutTreeBuilder, node: AbstractNode) {
debug!("BoxGenerator[f%d]: popping node: %s", self.flow.d().id, node.debug_str()); debug!("BoxGenerator[f%d]: popping node: %s", self.flow.d().id, node.debug_str());
match self.flow { match self.flow {
@ -164,8 +166,9 @@ impl BoxGenerator {
if self.inline_spacers_needed_for_node(node) { if self.inline_spacers_needed_for_node(node) {
// if this non-leaf box generates extra horizontal // if this non-leaf box generates extra horizontal
// spacing, add a SpacerBox for it. // spacing, add a SpacerBox for it.
do self.make_inline_spacer_for_node_side(ctx, node, LogicalAfter).iter |spacer: &@RenderBox| { for self.make_inline_spacer_for_node_side(ctx, node, LogicalAfter).each |spacer: &@mut RenderBox| {
self.flow.inline().boxes.push(*spacer); let boxes = &mut self.flow.inline().boxes;
boxes.push(*spacer);
} }
} }
let mut node_range: Range = Range::new(self.range_stack.pop(), 0); let mut node_range: Range = Range::new(self.range_stack.pop(), 0);
@ -173,7 +176,8 @@ impl BoxGenerator {
assert node_range.length() > 0; assert node_range.length() > 0;
debug!("BoxGenerator: adding element range=%?", node_range); debug!("BoxGenerator: adding element range=%?", node_range);
self.flow.inline().elems.add_mapping(node, &const node_range); let elems = &mut self.flow.inline().elems;
elems.add_mapping(node, &const node_range);
}, },
@BlockFlow(*) | @RootFlow(*) => { @BlockFlow(*) | @RootFlow(*) => {
assert self.range_stack.len() == 0; assert self.range_stack.len() == 0;
@ -184,12 +188,12 @@ impl BoxGenerator {
} }
struct BuilderContext { struct BuilderContext {
default_collector: @BoxGenerator, default_collector: @mut BoxGenerator,
priv mut inline_collector: Option<@BoxGenerator> priv inline_collector: Option<@mut BoxGenerator>
} }
impl BuilderContext { impl BuilderContext {
static pure fn new(collector: @BoxGenerator) -> BuilderContext { static pure fn new(collector: @mut BoxGenerator) -> BuilderContext {
unsafe { debug!("Creating new BuilderContext for flow: %s", collector.flow.debug_str()); } unsafe { debug!("Creating new BuilderContext for flow: %s", collector.flow.debug_str()); }
BuilderContext { BuilderContext {
default_collector: collector, default_collector: collector,
@ -202,24 +206,24 @@ impl BuilderContext {
copy self copy self
} }
priv fn attach_child_flow(child: @FlowContext) { priv fn attach_child_flow(child: @mut FlowContext) {
debug!("BuilderContext: Adding child flow f%? of f%?", debug!("BuilderContext: Adding child flow f%? of f%?",
self.default_collector.flow.d().id, child.d().id); self.default_collector.flow.d().id, child.d().id);
tree::add_child(&FlowTree, self.default_collector.flow, child); tree::add_child(&FlowTree, self.default_collector.flow, child);
} }
priv fn create_child_flow_of_type(flow_type: FlowContextType, priv fn create_child_flow_of_type(flow_type: FlowContextType,
builder: &LayoutTreeBuilder) -> BuilderContext { builder: &mut LayoutTreeBuilder) -> BuilderContext {
let new_flow = builder.make_flow(flow_type); let new_flow = builder.make_flow(flow_type);
self.attach_child_flow(new_flow); self.attach_child_flow(new_flow);
BuilderContext::new(@BoxGenerator::new(new_flow)) BuilderContext::new(@mut BoxGenerator::new(new_flow))
} }
priv fn make_inline_collector(builder: &LayoutTreeBuilder) -> BuilderContext { priv fn make_inline_collector(&mut self, builder: &mut LayoutTreeBuilder) -> BuilderContext {
debug!("BuilderContext: making new inline collector flow"); debug!("BuilderContext: making new inline collector flow");
let new_flow = builder.make_flow(Flow_Inline); let new_flow = builder.make_flow(Flow_Inline);
let new_generator = @BoxGenerator::new(new_flow); let new_generator = @mut BoxGenerator::new(new_flow);
self.inline_collector = Some(new_generator); self.inline_collector = Some(new_generator);
self.attach_child_flow(new_flow); self.attach_child_flow(new_flow);
@ -227,22 +231,23 @@ impl BuilderContext {
BuilderContext::new(new_generator) BuilderContext::new(new_generator)
} }
priv fn get_inline_collector(builder: &LayoutTreeBuilder) -> BuilderContext { priv fn get_inline_collector(&mut self, builder: &mut LayoutTreeBuilder) -> BuilderContext {
match copy self.inline_collector { match copy self.inline_collector {
Some(collector) => BuilderContext::new(collector), Some(collector) => BuilderContext::new(collector),
None => self.make_inline_collector(builder) None => self.make_inline_collector(builder)
} }
} }
priv fn clear_inline_collector() { priv fn clear_inline_collector(&mut self) {
self.inline_collector = None; self.inline_collector = None;
} }
// returns a context for the current node, or None if the document subtree rooted // returns a context for the current node, or None if the document subtree rooted
// by the node should not generate a layout tree. For example, nodes with style 'display:none' // by the node should not generate a layout tree. For example, nodes with style 'display:none'
// should just not generate any flows or boxes. // should just not generate any flows or boxes.
fn containing_context_for_node(node: AbstractNode, fn containing_context_for_node(&mut self,
builder: &LayoutTreeBuilder) node: AbstractNode,
builder: &mut LayoutTreeBuilder)
-> Option<BuilderContext> { -> Option<BuilderContext> {
// TODO: remove this once UA styles work // TODO: remove this once UA styles work
// TODO: handle interactions with 'float', 'position' (CSS 2.1, Section 9.7) // TODO: handle interactions with 'float', 'position' (CSS 2.1, Section 9.7)
@ -275,20 +280,20 @@ impl BuilderContext {
} }
} }
impl LayoutTreeBuilder { pub impl LayoutTreeBuilder {
/* Debug-only ids */ /* Debug-only ids */
fn next_box_id(&self) -> int { self.next_bid += 1; self.next_bid } fn next_box_id(&mut self) -> int { self.next_bid += 1; self.next_bid }
fn next_flow_id(&self) -> int { self.next_cid += 1; self.next_cid } fn next_flow_id(&mut self) -> int { self.next_cid += 1; self.next_cid }
/// Creates necessary box(es) and flow context(s) for the current DOM node, /// Creates necessary box(es) and flow context(s) for the current DOM node,
/// and recurses on its children. /// and recurses on its children.
fn construct_recursively(&self, fn construct_recursively(&mut self,
layout_ctx: &LayoutContext, layout_ctx: &LayoutContext,
cur_node: AbstractNode, cur_node: AbstractNode,
parent_ctx: &BuilderContext) { parent_ctx: &mut BuilderContext) {
debug!("Considering node: %s", cur_node.debug_str()); debug!("Considering node: %s", cur_node.debug_str());
let this_ctx = match parent_ctx.containing_context_for_node(cur_node, self) { let mut this_ctx = match parent_ctx.containing_context_for_node(cur_node, self) {
Some(ctx) => ctx, Some(ctx) => ctx,
None => { return; } // no context because of display: none. Stop building subtree. None => { return; } // no context because of display: none. Stop building subtree.
}; };
@ -298,7 +303,7 @@ impl LayoutTreeBuilder {
// recurse on child nodes. // recurse on child nodes.
for cur_node.each_child |child_node| { for cur_node.each_child |child_node| {
self.construct_recursively(layout_ctx, child_node, &this_ctx); self.construct_recursively(layout_ctx, child_node, &mut this_ctx);
} }
this_ctx.default_collector.pop_node(layout_ctx, self, cur_node); this_ctx.default_collector.pop_node(layout_ctx, self, cur_node);
@ -308,8 +313,9 @@ impl LayoutTreeBuilder {
// boxes that correspond to child_flow.node. These boxes may // boxes that correspond to child_flow.node. These boxes may
// eventually be elided or split, but the mapping between // eventually be elided or split, but the mapping between
// nodes and FlowContexts should not change during layout. // nodes and FlowContexts should not change during layout.
for tree::each_child(&FlowTree, &this_ctx.default_collector.flow) |child_flow: &@FlowContext| { let flow = &mut this_ctx.default_collector.flow;
do (copy child_flow.d().node).iter |node| { for tree::each_child(&FlowTree, flow) |child_flow: &@mut FlowContext| {
for (copy child_flow.d().node).each |node| {
assert node.has_layout_data(); assert node.has_layout_data();
node.layout_data().flow = Some(*child_flow); node.layout_data().flow = Some(*child_flow);
} }
@ -331,7 +337,8 @@ impl LayoutTreeBuilder {
let mut found_child_inline = false; let mut found_child_inline = false;
let mut found_child_block = false; let mut found_child_block = false;
for tree::each_child(&FlowTree, &parent_ctx.default_collector.flow) |child_ctx: &@FlowContext| { let flow = &mut parent_ctx.default_collector.flow;
for tree::each_child(&FlowTree, flow) |child_ctx: &@mut FlowContext| {
match **child_ctx { match **child_ctx {
InlineFlow(*) | InlineBlockFlow(*) => found_child_inline = true, InlineFlow(*) | InlineBlockFlow(*) => found_child_inline = true,
BlockFlow(*) => found_child_block = true, BlockFlow(*) => found_child_block = true,
@ -348,9 +355,9 @@ impl LayoutTreeBuilder {
// of its RenderBox or FlowContext children, and possibly keep alive other junk // of its RenderBox or FlowContext children, and possibly keep alive other junk
let parent_flow = parent_ctx.default_collector.flow; let parent_flow = parent_ctx.default_collector.flow;
// check first/last child for whitespace-ness // check first/last child for whitespace-ness
do tree::first_child(&FlowTree, &parent_flow).iter |first_flow: &@FlowContext| { for tree::first_child(&FlowTree, &parent_flow).each |first_flow: &@mut FlowContext| {
if first_flow.starts_inline_flow() { if first_flow.starts_inline_flow() {
let boxes = &first_flow.inline().boxes; let boxes = &mut first_flow.inline().boxes;
if boxes.len() == 1 && boxes[0].is_whitespace_only() { if boxes.len() == 1 && boxes[0].is_whitespace_only() {
debug!("LayoutTreeBuilder: pruning whitespace-only first child flow f%d from parent f%d", debug!("LayoutTreeBuilder: pruning whitespace-only first child flow f%d from parent f%d",
first_flow.d().id, parent_flow.d().id); first_flow.d().id, parent_flow.d().id);
@ -358,9 +365,9 @@ impl LayoutTreeBuilder {
} }
} }
} }
do tree::last_child(&FlowTree, &parent_flow).iter |last_flow: &@FlowContext| { for tree::last_child(&FlowTree, &parent_flow).each |last_flow: &@mut FlowContext| {
if last_flow.starts_inline_flow() { if last_flow.starts_inline_flow() {
let boxes = &last_flow.inline().boxes; let boxes = &mut last_flow.inline().boxes;
if boxes.len() == 1 && boxes.last().is_whitespace_only() { if boxes.len() == 1 && boxes.last().is_whitespace_only() {
debug!("LayoutTreeBuilder: pruning whitespace-only last child flow f%d from parent f%d", debug!("LayoutTreeBuilder: pruning whitespace-only last child flow f%d from parent f%d",
last_flow.d().id, parent_flow.d().id); last_flow.d().id, parent_flow.d().id);
@ -373,34 +380,34 @@ impl LayoutTreeBuilder {
} }
} }
fn fixup_split_inline(&self, _: @FlowContext) { fn fixup_split_inline(&self, _: @mut FlowContext) {
// TODO: finish me. // TODO: finish me.
fail!(~"TODO: handle case where an inline is split by a block") fail!(~"TODO: handle case where an inline is split by a block")
} }
/** entry point for box creation. Should only be /** entry point for box creation. Should only be
called on root DOM element. */ called on root DOM element. */
fn construct_trees(&self, layout_ctx: &LayoutContext, root: AbstractNode) fn construct_trees(&mut self, layout_ctx: &LayoutContext, root: AbstractNode)
-> Result<@FlowContext, ()> { -> Result<@mut FlowContext, ()> {
let new_flow = self.make_flow(Flow_Root); let new_flow = self.make_flow(Flow_Root);
let new_generator = @BoxGenerator::new(new_flow); let new_generator = @mut BoxGenerator::new(new_flow);
let root_ctx = BuilderContext::new(new_generator); let mut root_ctx = BuilderContext::new(new_generator);
self.root_flow = Some(new_flow); self.root_flow = Some(new_flow);
self.construct_recursively(layout_ctx, root, &root_ctx); self.construct_recursively(layout_ctx, root, &mut root_ctx);
return Ok(new_flow) return Ok(new_flow)
} }
fn make_flow(&self, ty: FlowContextType) -> @FlowContext { fn make_flow(&mut self, ty: FlowContextType) -> @mut FlowContext {
let data = FlowData(self.next_flow_id()); let data = FlowData(self.next_flow_id());
let ret = match ty { let ret = match ty {
Flow_Absolute => @AbsoluteFlow(data), Flow_Absolute => @mut AbsoluteFlow(data),
Flow_Block => @BlockFlow(data, BlockFlowData()), Flow_Block => @mut BlockFlow(data, BlockFlowData()),
Flow_Float => @FloatFlow(data), Flow_Float => @mut FloatFlow(data),
Flow_InlineBlock => @InlineBlockFlow(data), Flow_InlineBlock => @mut InlineBlockFlow(data),
Flow_Inline => @InlineFlow(data, InlineFlowData()), Flow_Inline => @mut InlineFlow(data, InlineFlowData()),
Flow_Root => @RootFlow(data, RootFlowData()), Flow_Root => @mut RootFlow(data, RootFlowData()),
Flow_Table => @TableFlow(data) Flow_Table => @mut TableFlow(data)
}; };
debug!("LayoutTreeBuilder: created flow: %s", ret.debug_str()); debug!("LayoutTreeBuilder: created flow: %s", ret.debug_str());
ret ret
@ -410,12 +417,12 @@ impl LayoutTreeBuilder {
disambiguate between different methods here instead of inlining, since each disambiguate between different methods here instead of inlining, since each
case has very different complexity case has very different complexity
*/ */
fn make_box(&self, fn make_box(&mut self,
layout_ctx: &LayoutContext, layout_ctx: &LayoutContext,
ty: RenderBoxType, ty: RenderBoxType,
node: AbstractNode, node: AbstractNode,
ctx: @FlowContext) ctx: @mut FlowContext)
-> @RenderBox { -> @mut RenderBox {
let ret = match ty { let ret = match ty {
RenderBox_Generic => self.make_generic_box(layout_ctx, node, ctx), RenderBox_Generic => self.make_generic_box(layout_ctx, node, ctx),
RenderBox_Text => self.make_text_box(layout_ctx, node, ctx), RenderBox_Text => self.make_text_box(layout_ctx, node, ctx),
@ -425,19 +432,19 @@ impl LayoutTreeBuilder {
ret ret
} }
fn make_generic_box(&self, fn make_generic_box(&mut self,
_: &LayoutContext, _: &LayoutContext,
node: AbstractNode, node: AbstractNode,
ctx: @FlowContext) ctx: @mut FlowContext)
-> @RenderBox { -> @mut RenderBox {
@GenericBox(RenderBoxData(copy node, ctx, self.next_box_id())) @mut GenericBox(RenderBoxData(copy node, ctx, self.next_box_id()))
} }
fn make_image_box(&self, fn make_image_box(&mut self,
layout_ctx: &LayoutContext, layout_ctx: &LayoutContext,
node: AbstractNode, node: AbstractNode,
ctx: @FlowContext) ctx: @mut FlowContext)
-> @RenderBox { -> @mut RenderBox {
if !node.is_image_element() { if !node.is_image_element() {
fail!(~"WAT error: why couldn't we make an image box?"); fail!(~"WAT error: why couldn't we make an image box?");
} }
@ -446,7 +453,7 @@ impl LayoutTreeBuilder {
if image_element.image.is_some() { if image_element.image.is_some() {
let holder = ImageHolder::new(copy *image_element.image.get_ref(), let holder = ImageHolder::new(copy *image_element.image.get_ref(),
layout_ctx.image_cache); layout_ctx.image_cache);
@ImageBox(RenderBoxData(node, ctx, self.next_box_id()), holder) @mut ImageBox(RenderBoxData(node, ctx, self.next_box_id()), holder)
} else { } else {
info!("Tried to make image box, but couldn't find image. Made generic box instead."); info!("Tried to make image box, but couldn't find image. Made generic box instead.");
self.make_generic_box(layout_ctx, node, ctx) self.make_generic_box(layout_ctx, node, ctx)
@ -454,11 +461,11 @@ impl LayoutTreeBuilder {
} }
} }
fn make_text_box(&self, fn make_text_box(&mut self,
_: &LayoutContext, _: &LayoutContext,
node: AbstractNode, node: AbstractNode,
ctx: @FlowContext) ctx: @mut FlowContext)
-> @RenderBox { -> @mut RenderBox {
if !node.is_text() { if !node.is_text() {
fail!(~"WAT error: why couldn't we make a text box?"); fail!(~"WAT error: why couldn't we make a text box?");
} }
@ -466,7 +473,7 @@ impl LayoutTreeBuilder {
// FIXME: Don't copy text. I guess it should be atomically reference counted? // FIXME: Don't copy text. I guess it should be atomically reference counted?
do node.with_imm_text |text_node| { do node.with_imm_text |text_node| {
let string = text_node.text.to_str(); let string = text_node.text.to_str();
@UnscannedTextBox(RenderBoxData(node, ctx, self.next_box_id()), string) @mut UnscannedTextBox(RenderBoxData(node, ctx, self.next_box_id()), string)
} }
} }

View file

@ -7,8 +7,8 @@ use std::net::url::Url;
/* Represents layout task context. */ /* Represents layout task context. */
pub struct LayoutContext { pub struct LayoutContext {
font_ctx: @FontContext, font_ctx: @mut FontContext,
image_cache: @LocalImageCache, image_cache: @mut LocalImageCache,
doc_url: Url, doc_url: Url,
screen_size: Rect<Au> screen_size: Rect<Au>
} }

View file

@ -1,3 +1,9 @@
pub trait BoxedMutDebugMethods {
pure fn dump(@mut self);
pure fn dump_indent(@mut self, ident: uint);
pure fn debug_str(@mut self) -> ~str;
}
pub trait BoxedDebugMethods { pub trait BoxedDebugMethods {
pure fn dump(@self); pure fn dump(@self);
pure fn dump_indent(@self, ident: uint); pure fn dump_indent(@self, ident: uint);

View file

@ -29,21 +29,21 @@ use gfx;
Right now, the builder isn't used for much, but it establishes the Right now, the builder isn't used for much, but it establishes the
pattern we'll need once we support DL-based hit testing &c. */ pattern we'll need once we support DL-based hit testing &c. */
pub struct DisplayListBuilder { pub struct DisplayListBuilder {
ctx: &LayoutContext, ctx: &'self LayoutContext,
} }
pub trait FlowDisplayListBuilderMethods { pub trait FlowDisplayListBuilderMethods {
fn build_display_list(@self, a: &DisplayListBuilder, b: &Rect<Au>, c: &Mut<DisplayList>); fn build_display_list(@mut self, a: &DisplayListBuilder, b: &Rect<Au>, c: &Mut<DisplayList>);
fn build_display_list_for_child(@self, fn build_display_list_for_child(@mut self,
a: &DisplayListBuilder, a: &DisplayListBuilder,
b: @FlowContext, b: @mut FlowContext,
c: &Rect<Au>, c: &Rect<Au>,
d: &Point2D<Au>, d: &Point2D<Au>,
e: &Mut<DisplayList>); e: &Mut<DisplayList>);
} }
impl FlowDisplayListBuilderMethods for FlowContext { impl FlowDisplayListBuilderMethods for FlowContext {
fn build_display_list(@self, fn build_display_list(@mut self,
builder: &DisplayListBuilder, builder: &DisplayListBuilder,
dirty: &Rect<Au>, dirty: &Rect<Au>,
list: &Mut<DisplayList>) { list: &Mut<DisplayList>) {
@ -51,9 +51,9 @@ impl FlowDisplayListBuilderMethods for FlowContext {
self.build_display_list_recurse(builder, dirty, &zero, list); self.build_display_list_recurse(builder, dirty, &zero, list);
} }
fn build_display_list_for_child(@self, fn build_display_list_for_child(@mut self,
builder: &DisplayListBuilder, builder: &DisplayListBuilder,
child_flow: @FlowContext, child_flow: @mut FlowContext,
dirty: &Rect<Au>, offset: &Point2D<Au>, dirty: &Rect<Au>, offset: &Point2D<Au>,
list: &Mut<DisplayList>) { list: &Mut<DisplayList>) {

View file

@ -3,7 +3,7 @@ use dom::node::AbstractNode;
use layout::block::{BlockFlowData, BlockLayout}; use layout::block::{BlockFlowData, BlockLayout};
use layout::box::RenderBox; use layout::box::RenderBox;
use layout::context::LayoutContext; use layout::context::LayoutContext;
use layout::debug::BoxedDebugMethods; use layout::debug::BoxedMutDebugMethods;
use layout::display_list_builder::DisplayListBuilder; use layout::display_list_builder::DisplayListBuilder;
use layout::inline::{InlineFlowData, InlineLayout, NodeRange}; use layout::inline::{InlineFlowData, InlineLayout, NodeRange};
use layout::root::{RootFlowData, RootLayout}; use layout::root::{RootFlowData, RootLayout};
@ -54,7 +54,7 @@ pub enum FlowContext {
TableFlow(FlowData) TableFlow(FlowData)
} }
enum FlowContextType { pub enum FlowContextType {
Flow_Absolute, Flow_Absolute,
Flow_Block, Flow_Block,
Flow_Float, Flow_Float,
@ -66,22 +66,22 @@ enum FlowContextType {
/* A particular kind of layout context. It manages the positioning of /* A particular kind of layout context. It manages the positioning of
render boxes within the context. */ render boxes within the context. */
struct FlowData { pub struct FlowData {
mut node: Option<AbstractNode>, node: Option<AbstractNode>,
/* reference to parent, children flow contexts */ /* reference to parent, children flow contexts */
tree: tree::Tree<@FlowContext>, tree: tree::Tree<@mut FlowContext>,
/* TODO (Issue #87): debug only */ /* TODO (Issue #87): debug only */
mut id: int, id: int,
/* layout computations */ /* layout computations */
// TODO: min/pref and position are used during disjoint phases of // TODO: min/pref and position are used during disjoint phases of
// layout; maybe combine into a single enum to save space. // layout; maybe combine into a single enum to save space.
mut min_width: Au, min_width: Au,
mut pref_width: Au, pref_width: Au,
mut position: Rect<Au>, position: Rect<Au>,
} }
fn FlowData(id: int) -> FlowData { pub fn FlowData(id: int) -> FlowData {
FlowData { FlowData {
node: None, node: None,
tree: tree::empty(), tree: tree::empty(),
@ -93,41 +93,43 @@ fn FlowData(id: int) -> FlowData {
} }
} }
impl FlowContext { pub impl FlowContext {
pure fn d(&self) -> &self/FlowData { pure fn d(&mut self) -> &self/mut FlowData {
unsafe {
match *self { match *self {
AbsoluteFlow(ref d) => d, AbsoluteFlow(ref d) => cast::transmute(d),
BlockFlow(ref d, _) => d, BlockFlow(ref d, _) => cast::transmute(d),
FloatFlow(ref d) => d, FloatFlow(ref d) => cast::transmute(d),
InlineBlockFlow(ref d) => d, InlineBlockFlow(ref d) => cast::transmute(d),
InlineFlow(ref d, _) => d, InlineFlow(ref d, _) => cast::transmute(d),
RootFlow(ref d, _) => d, RootFlow(ref d, _) => cast::transmute(d),
TableFlow(ref d) => d TableFlow(ref d) => cast::transmute(d)
} }
}
} }
pure fn inline(&self) -> &self/InlineFlowData { pure fn inline(&mut self) -> &self/mut InlineFlowData {
match *self { match self {
InlineFlow(_, ref i) => i, &InlineFlow(_, ref i) => unsafe { cast::transmute(i) },
_ => fail!(fmt!("Tried to access inline data of non-inline: f%d", self.d().id)) _ => fail!(fmt!("Tried to access inline data of non-inline: f%d", self.d().id))
} }
} }
pure fn block(&self) -> &self/BlockFlowData { pure fn block(&mut self) -> &self/mut BlockFlowData {
match *self { match self {
BlockFlow(_, ref b) => b, &BlockFlow(_, ref mut b) => unsafe { cast::transmute(b) },
_ => fail!(fmt!("Tried to access block data of non-block: f%d", self.d().id)) _ => fail!(fmt!("Tried to access block data of non-block: f%d", self.d().id))
} }
} }
pure fn root(&self) -> &self/RootFlowData { pure fn root(&mut self) -> &self/mut RootFlowData {
match *self { match self {
RootFlow(_, ref r) => r, &RootFlow(_, ref r) => unsafe { cast::transmute(r) },
_ => fail!(fmt!("Tried to access root data of non-root: f%d", self.d().id)) _ => fail!(fmt!("Tried to access root data of non-root: f%d", self.d().id))
} }
} }
fn bubble_widths(@self, ctx: &LayoutContext) { fn bubble_widths(@mut self, ctx: &mut LayoutContext) {
match self { match self {
@BlockFlow(*) => self.bubble_widths_block(ctx), @BlockFlow(*) => self.bubble_widths_block(ctx),
@InlineFlow(*) => self.bubble_widths_inline(ctx), @InlineFlow(*) => self.bubble_widths_inline(ctx),
@ -136,7 +138,7 @@ impl FlowContext {
} }
} }
fn assign_widths(@self, ctx: &LayoutContext) { fn assign_widths(@mut self, ctx: &mut LayoutContext) {
match self { match self {
@BlockFlow(*) => self.assign_widths_block(ctx), @BlockFlow(*) => self.assign_widths_block(ctx),
@InlineFlow(*) => self.assign_widths_inline(ctx), @InlineFlow(*) => self.assign_widths_inline(ctx),
@ -145,7 +147,7 @@ impl FlowContext {
} }
} }
fn assign_height(@self, ctx: &LayoutContext) { fn assign_height(@mut self, ctx: &mut LayoutContext) {
match self { match self {
@BlockFlow(*) => self.assign_height_block(ctx), @BlockFlow(*) => self.assign_height_block(ctx),
@InlineFlow(*) => self.assign_height_inline(ctx), @InlineFlow(*) => self.assign_height_inline(ctx),
@ -154,7 +156,7 @@ impl FlowContext {
} }
} }
fn build_display_list_recurse(@self, builder: &DisplayListBuilder, dirty: &Rect<Au>, fn build_display_list_recurse(@mut self, builder: &DisplayListBuilder, dirty: &Rect<Au>,
offset: &Point2D<Au>, list: &Mut<DisplayList>) { offset: &Point2D<Au>, list: &Mut<DisplayList>) {
debug!("FlowContext::build_display_list at %?: %s", self.d().position, self.debug_str()); debug!("FlowContext::build_display_list at %?: %s", self.d().position, self.debug_str());
@ -167,19 +169,21 @@ impl FlowContext {
} }
// Actual methods that do not require much flow-specific logic // Actual methods that do not require much flow-specific logic
pure fn foldl_all_boxes<B: Copy>(seed: B, pure fn foldl_all_boxes<B: Copy>(&mut self,
cb: pure fn&(a: B,@RenderBox) -> B) -> B { seed: B,
cb: &pure fn(a: B,@mut RenderBox) -> B) -> B {
match self { match self {
RootFlow(*) => option::map_default(&self.root().box, seed, |box| { cb(seed, *box) }), &RootFlow(*) => option::map_default(&self.root().box, seed, |box| { cb(seed, *box) }),
BlockFlow(*) => option::map_default(&self.block().box, seed, |box| { cb(seed, *box) }), &BlockFlow(*) => option::map_default(&self.block().box, seed, |box| { cb(seed, *box) }),
InlineFlow(*) => do self.inline().boxes.foldl(seed) |acc, box| { cb(*acc, *box) }, &InlineFlow(*) => do self.inline().boxes.foldl(seed) |acc, box| { cb(*acc, *box) },
_ => fail!(fmt!("Don't know how to iterate node's RenderBoxes for %?", self)) _ => fail!(fmt!("Don't know how to iterate node's RenderBoxes for %?", self))
} }
} }
pure fn foldl_boxes_for_node<B: Copy>(node: AbstractNode, pure fn foldl_boxes_for_node<B: Copy>(&mut self,
node: AbstractNode,
seed: B, seed: B,
cb: pure fn&(a: B,@RenderBox) -> B) cb: &pure fn(a: B,@mut RenderBox) -> B)
-> B { -> B {
do self.foldl_all_boxes(seed) |acc, box| { do self.foldl_all_boxes(seed) |acc, box| {
if box.d().node == node { cb(acc, box) } if box.d().node == node { cb(acc, box) }
@ -187,17 +191,18 @@ impl FlowContext {
} }
} }
pure fn iter_all_boxes<T>(cb: pure fn&(@RenderBox) -> T) { pure fn iter_all_boxes<T>(&mut self, cb: &pure fn(@mut RenderBox) -> T) {
match self { match self {
RootFlow(*) => do self.root().box.iter |box| { cb(*box); }, &RootFlow(*) => for self.root().box.each |box| { cb(*box); },
BlockFlow(*) => do self.block().box.iter |box| { cb(*box); }, &BlockFlow(*) => for self.block().box.each |box| { cb(*box); },
InlineFlow(*) => for self.inline().boxes.each |box| { cb(*box); }, &InlineFlow(*) => for self.inline().boxes.each |box| { cb(*box); },
_ => fail!(fmt!("Don't know how to iterate node's RenderBoxes for %?", self)) _ => fail!(fmt!("Don't know how to iterate node's RenderBoxes for %?", self))
} }
} }
pure fn iter_boxes_for_node<T>(node: AbstractNode, pure fn iter_boxes_for_node<T>(&mut self,
cb: pure fn&(@RenderBox) -> T) { node: AbstractNode,
cb: &pure fn(@mut RenderBox) -> T) {
do self.iter_all_boxes |box| { do self.iter_all_boxes |box| {
if box.d().node == node { cb(box); } if box.d().node == node { cb(box); }
} }
@ -208,39 +213,41 @@ impl FlowContext {
pub enum FlowTree { FlowTree } pub enum FlowTree { FlowTree }
impl FlowTree { impl FlowTree {
fn each_child(ctx: @FlowContext, f: fn(box: @FlowContext) -> bool) { fn each_child(ctx: @mut FlowContext, f: fn(box: @mut FlowContext) -> bool) {
tree::each_child(&self, &ctx, |box| f(*box) ) tree::each_child(&self, &ctx, |box| f(*box) )
} }
} }
impl tree::ReadMethods<@FlowContext> for FlowTree { impl tree::ReadMethods<@mut FlowContext> for FlowTree {
fn with_tree_fields<R>(box: &@FlowContext, f: fn(&tree::Tree<@FlowContext>) -> R) -> R { fn with_tree_fields<R>(box: &@mut FlowContext, f: fn(&mut tree::Tree<@mut FlowContext>) -> R) -> R {
f(&box.d().tree) let tree = &mut box.d().tree;
f(tree)
} }
} }
impl FlowTree { impl FlowTree {
fn add_child(parent: @FlowContext, child: @FlowContext) { fn add_child(parent: @mut FlowContext, child: @mut FlowContext) {
tree::add_child(&self, parent, child) tree::add_child(&self, parent, child)
} }
} }
impl tree::WriteMethods<@FlowContext> for FlowTree { impl tree::WriteMethods<@mut FlowContext> for FlowTree {
pure fn tree_eq(a: &@FlowContext, b: &@FlowContext) -> bool { core::managed::ptr_eq(*a, *b) } pure fn tree_eq(a: &@mut FlowContext, b: &@mut FlowContext) -> bool { core::managed::mut_ptr_eq(*a, *b) }
fn with_tree_fields<R>(box: &@FlowContext, f: fn(&tree::Tree<@FlowContext>) -> R) -> R { fn with_tree_fields<R>(box: &@mut FlowContext, f: fn(&mut tree::Tree<@mut FlowContext>) -> R) -> R {
f(&box.d().tree) let tree = &mut box.d().tree;
f(tree)
} }
} }
impl BoxedDebugMethods for FlowContext { impl BoxedMutDebugMethods for FlowContext {
pure fn dump(@self) { pure fn dump(@mut self) {
self.dump_indent(0u); self.dump_indent(0u);
} }
/** Dumps the flow tree, for debugging, with indentation. */ /** Dumps the flow tree, for debugging, with indentation. */
pure fn dump_indent(@self, indent: uint) { pure fn dump_indent(@mut self, indent: uint) {
let mut s = ~"|"; let mut s = ~"|";
for uint::range(0u, indent) |_i| { for uint::range(0u, indent) |_i| {
s += ~"---- "; s += ~"---- ";
@ -257,7 +264,7 @@ impl BoxedDebugMethods for FlowContext {
} }
} }
pure fn debug_str(@self) -> ~str { pure fn debug_str(@mut self) -> ~str {
let repr = match *self { let repr = match *self {
InlineFlow(*) => { InlineFlow(*) => {
let mut s = self.inline().boxes.foldl(~"InlineFlow(children=", |s, box| { let mut s = self.inline().boxes.foldl(~"InlineFlow(children=", |s, box| {

View file

@ -2,21 +2,26 @@ use core;
use dom::node::AbstractNode; use dom::node::AbstractNode;
use layout::box::*; use layout::box::*;
use layout::context::LayoutContext; use layout::context::LayoutContext;
use layout::debug::{BoxedDebugMethods, DebugMethods}; use layout::debug::{BoxedDebugMethods, BoxedMutDebugMethods, DebugMethods};
use layout::display_list_builder::DisplayListBuilder;
use layout::flow::{FlowContext, InlineFlow}; use layout::flow::{FlowContext, InlineFlow};
use layout::text::{TextBoxData, UnscannedMethods}; use layout::text::{TextBoxData, UnscannedMethods, adapt_textbox_with_range};
use util::tree; use util::tree;
use core::dlist::DList; use core::dlist::DList;
use core::dvec::DVec; use core::dvec::DVec;
use geom::{Point2D, Rect, Size2D}; use geom::{Point2D, Rect, Size2D};
use gfx::display_list::DisplayList;
use gfx::font::FontStyle; use gfx::font::FontStyle;
use gfx::geometry::Au; use gfx::geometry::Au;
use gfx::image::holder;
use gfx::text::text_run::TextRun;
use gfx::text::util::*; use gfx::text::util::*;
use gfx::util::range::Range; use gfx::util::range::Range;
use newcss::values::{CSSTextAlignCenter, CSSTextAlignJustify, CSSTextAlignLeft, CSSTextAlignRight}; use newcss::values::{CSSTextAlignCenter, CSSTextAlignJustify, CSSTextAlignLeft, CSSTextAlignRight};
use newcss::units::{BoxAuto, BoxLength, Px}; use newcss::units::{BoxAuto, BoxLength, Px};
use std::arc; use std::arc;
use core::mutable::Mut;
/* /*
Lineboxes are represented as offsets into the child list, rather than Lineboxes are represented as offsets into the child list, rather than
@ -55,7 +60,7 @@ struct ElementMapping {
priv entries: DVec<NodeRange>, priv entries: DVec<NodeRange>,
} }
impl ElementMapping { pub impl ElementMapping {
static pure fn new() -> ElementMapping { static pure fn new() -> ElementMapping {
ElementMapping { entries: DVec() } ElementMapping { entries: DVec() }
} }
@ -64,19 +69,19 @@ impl ElementMapping {
self.entries.push(NodeRange::new(node, range)) self.entries.push(NodeRange::new(node, range))
} }
fn each(cb: pure fn&(nr: &NodeRange) -> bool) { fn each(cb: &pure fn(nr: &NodeRange) -> bool) {
do self.entries.each |nr| { cb(nr) } do self.entries.each |nr| { cb(nr) }
} }
fn eachi(cb: pure fn&(i: uint, nr: &NodeRange) -> bool) { fn eachi(cb: &pure fn(i: uint, nr: &NodeRange) -> bool) {
do self.entries.eachi |i, nr| { cb(i, nr) } do self.entries.eachi |i, nr| { cb(i, nr) }
} }
fn eachi_mut(cb: fn&(i: uint, nr: &NodeRange) -> bool) { fn eachi_mut(cb: &fn(i: uint, nr: &NodeRange) -> bool) {
do self.entries.eachi |i, nr| { cb(i, nr) } do self.entries.eachi |i, nr| { cb(i, nr) }
} }
fn repair_for_box_changes(old_boxes: &DVec<@RenderBox>, new_boxes: &DVec<@RenderBox>) { fn repair_for_box_changes(old_boxes: &DVec<@mut RenderBox>, new_boxes: &DVec<@mut RenderBox>) {
debug!("--- Old boxes: ---"); debug!("--- Old boxes: ---");
for old_boxes.eachi |i, box| { for old_boxes.eachi |i, box| {
debug!("%u --> %s", i, box.debug_str()); debug!("%u --> %s", i, box.debug_str());
@ -104,7 +109,7 @@ impl ElementMapping {
}; };
let repair_stack : DVec<WorkItem> = DVec(); let repair_stack : DVec<WorkItem> = DVec();
do self.entries.borrow_mut |entries: &[mut NodeRange]| { do self.entries.borrow_mut |entries: &mut [NodeRange]| {
// index into entries // index into entries
let mut entries_k = 0; let mut entries_k = 0;
@ -161,10 +166,11 @@ priv impl TextRunScanner {
} }
priv impl TextRunScanner { priv impl TextRunScanner {
fn scan_for_runs(&mut self, ctx: &LayoutContext, flow: @FlowContext) { fn scan_for_runs(&mut self, ctx: &mut LayoutContext, flow: @mut FlowContext) {
assert flow.inline().boxes.len() > 0; assert flow.inline().boxes.len() > 0;
do flow.inline().boxes.swap |in_boxes| { let boxes = &mut flow.inline().boxes;
do boxes.swap |in_boxes| {
debug!("TextRunScanner: scanning %u boxes for text runs...", in_boxes.len()); debug!("TextRunScanner: scanning %u boxes for text runs...", in_boxes.len());
let out_boxes = DVec(); let out_boxes = DVec();
@ -187,7 +193,7 @@ priv impl TextRunScanner {
} }
// helper functions // helper functions
fn can_coalesce_text_nodes(boxes: &[@RenderBox], left_i: uint, right_i: uint) -> bool { fn can_coalesce_text_nodes(boxes: &[@mut RenderBox], left_i: uint, right_i: uint) -> bool {
assert left_i < boxes.len(); assert left_i < boxes.len();
assert right_i > 0 && right_i < boxes.len(); assert right_i > 0 && right_i < boxes.len();
assert left_i != right_i; assert left_i != right_i;
@ -213,10 +219,10 @@ priv impl TextRunScanner {
// recursively borrow or swap the flow's dvec of boxes. When all // recursively borrow or swap the flow's dvec of boxes. When all
// boxes are appended, the caller swaps the flow's box list. // boxes are appended, the caller swaps the flow's box list.
fn flush_clump_to_list(&mut self, fn flush_clump_to_list(&mut self,
ctx: &LayoutContext, ctx: &mut LayoutContext,
flow: @FlowContext, flow: @mut FlowContext,
in_boxes: &[@RenderBox], in_boxes: &[@mut RenderBox],
out_boxes: &DVec<@RenderBox>) { out_boxes: &DVec<@mut RenderBox>) {
assert self.clump.length() > 0; assert self.clump.length() > 0;
debug!("TextRunScanner: flushing boxes in range=%?", self.clump); debug!("TextRunScanner: flushing boxes in range=%?", self.clump);
@ -247,9 +253,9 @@ priv impl TextRunScanner {
let fontgroup = ctx.font_ctx.get_resolved_font_for_style(&font_style); let fontgroup = ctx.font_ctx.get_resolved_font_for_style(&font_style);
let run = @fontgroup.create_textrun(transformed_text); let run = @fontgroup.create_textrun(transformed_text);
debug!("TextRunScanner: pushing single text box in range: %?", self.clump); debug!("TextRunScanner: pushing single text box in range: %?", self.clump);
let new_box = layout::text::adapt_textbox_with_range(old_box.d(), let new_box = adapt_textbox_with_range(old_box.d(),
run, run,
&const Range::new(0, run.char_len())); &const Range::new(0, run.char_len()));
out_boxes.push(new_box); out_boxes.push(new_box);
}, },
(false, true) => { (false, true) => {
@ -294,7 +300,7 @@ priv impl TextRunScanner {
in_boxes[i].debug_str()); in_boxes[i].debug_str());
loop loop
} }
let new_box = layout::text::adapt_textbox_with_range(in_boxes[i].d(), run, range); let new_box = adapt_textbox_with_range(in_boxes[i].d(), run, range);
out_boxes.push(new_box); out_boxes.push(new_box);
} }
} }
@ -313,7 +319,8 @@ priv impl TextRunScanner {
debug!("------------------"); debug!("------------------");
debug!("--- Elem ranges: ---"); debug!("--- Elem ranges: ---");
for flow.inline().elems.eachi_mut |i: uint, nr: &NodeRange| { let elems: &mut ElementMapping = &mut flow.inline().elems;
for elems.eachi_mut |i: uint, nr: &NodeRange| {
debug!("%u: %? --> %s", i, nr.range, nr.node.debug_str()); () debug!("%u: %? --> %s", i, nr.range, nr.node.debug_str()); ()
} }
debug!("--------------------"); debug!("--------------------");
@ -323,19 +330,19 @@ priv impl TextRunScanner {
} }
struct PendingLine { struct PendingLine {
mut range: Range, range: Range,
mut width: Au width: Au
} }
struct LineboxScanner { struct LineboxScanner {
flow: @FlowContext, flow: @mut FlowContext,
new_boxes: DVec<@RenderBox>, new_boxes: DVec<@mut RenderBox>,
work_list: @mut DList<@RenderBox>, work_list: @mut DList<@mut RenderBox>,
pending_line: PendingLine, pending_line: PendingLine,
line_spans: DVec<Range>, line_spans: DVec<Range>,
} }
fn LineboxScanner(inline: @FlowContext) -> LineboxScanner { fn LineboxScanner(inline: @mut FlowContext) -> LineboxScanner {
assert inline.starts_inline_flow(); assert inline.starts_inline_flow();
LineboxScanner { LineboxScanner {
@ -363,7 +370,7 @@ impl LineboxScanner {
pub fn scan_for_lines(&mut self, ctx: &LayoutContext) { pub fn scan_for_lines(&mut self, ctx: &LayoutContext) {
self.reset_scanner(); self.reset_scanner();
let boxes = &self.flow.inline().boxes; let boxes = &mut self.flow.inline().boxes;
let mut i = 0u; let mut i = 0u;
loop { loop {
@ -397,7 +404,9 @@ impl LineboxScanner {
self.flush_current_line(); self.flush_current_line();
} }
self.flow.inline().elems.repair_for_box_changes(&self.flow.inline().boxes, &self.new_boxes); let boxes = &mut self.flow.inline().boxes;
let elems = &mut self.flow.inline().elems;
elems.repair_for_box_changes(boxes, &self.new_boxes);
self.swap_out_results(); self.swap_out_results();
} }
@ -406,11 +415,13 @@ impl LineboxScanner {
self.line_spans.len(), self.flow.d().id); self.line_spans.len(), self.flow.d().id);
do self.new_boxes.swap |boxes| { do self.new_boxes.swap |boxes| {
self.flow.inline().boxes.set(boxes); let inline_boxes = &mut self.flow.inline().boxes;
inline_boxes.set(boxes);
~[] ~[]
}; };
do self.line_spans.swap |boxes| { do self.line_spans.swap |boxes| {
self.flow.inline().lines.set(boxes); let lines = &mut self.flow.inline().lines;
lines.set(boxes);
~[] ~[]
}; };
} }
@ -472,7 +483,7 @@ impl LineboxScanner {
} }
// return value: whether any box was appended. // return value: whether any box was appended.
priv fn try_append_to_line(&mut self, ctx: &LayoutContext, in_box: @RenderBox) -> bool { priv fn try_append_to_line(&mut self, ctx: &LayoutContext, in_box: @mut RenderBox) -> bool {
let remaining_width = self.flow.d().position.size.width - self.pending_line.width; let remaining_width = self.flow.d().position.size.width - self.pending_line.width;
let in_box_width = in_box.d().position.size.width; let in_box_width = in_box.d().position.size.width;
let line_is_empty: bool = self.pending_line.range.length() == 0; let line_is_empty: bool = self.pending_line.range.length() == 0;
@ -552,7 +563,7 @@ impl LineboxScanner {
} }
// unconditional push // unconditional push
priv fn push_box_to_line(&mut self, box: @RenderBox) { priv fn push_box_to_line(&mut self, box: @mut RenderBox) {
debug!("LineboxScanner: Pushing box b%d to line %u", box.d().id, self.line_spans.len()); debug!("LineboxScanner: Pushing box b%d to line %u", box.d().id, self.line_spans.len());
if self.pending_line.range.length() == 0 { if self.pending_line.range.length() == 0 {
@ -568,7 +579,7 @@ impl LineboxScanner {
pub struct InlineFlowData { pub struct InlineFlowData {
// A vec of all inline render boxes. Several boxes may // A vec of all inline render boxes. Several boxes may
// correspond to one Node/Element. // correspond to one Node/Element.
boxes: DVec<@RenderBox>, boxes: DVec<@mut RenderBox>,
// vec of ranges into boxes that represents line positions. // vec of ranges into boxes that represents line positions.
// these ranges are disjoint, and are the result of inline layout. // these ranges are disjoint, and are the result of inline layout.
lines: DVec<Range>, lines: DVec<Range>,
@ -589,17 +600,17 @@ pub fn InlineFlowData() -> InlineFlowData {
pub trait InlineLayout { pub trait InlineLayout {
pure fn starts_inline_flow() -> bool; pure fn starts_inline_flow() -> bool;
fn bubble_widths_inline(@self, ctx: &LayoutContext); fn bubble_widths_inline(@mut self, ctx: &mut LayoutContext);
fn assign_widths_inline(@self, ctx: &LayoutContext); fn assign_widths_inline(@mut self, ctx: &mut LayoutContext);
fn assign_height_inline(@self, ctx: &LayoutContext); fn assign_height_inline(@mut self, ctx: &mut LayoutContext);
fn build_display_list_inline(@self, a: &DisplayListBuilder, b: &Rect<Au>, c: &Point2D<Au>, fn build_display_list_inline(@mut self, a: &DisplayListBuilder, b: &Rect<Au>, c: &Point2D<Au>,
d: &Mut<DisplayList>); d: &Mut<DisplayList>);
} }
impl InlineLayout for FlowContext { impl InlineLayout for FlowContext {
pure fn starts_inline_flow() -> bool { match self { InlineFlow(*) => true, _ => false } } pure fn starts_inline_flow() -> bool { match self { InlineFlow(*) => true, _ => false } }
fn bubble_widths_inline(@self, ctx: &LayoutContext) { fn bubble_widths_inline(@mut self, ctx: &mut LayoutContext) {
assert self.starts_inline_flow(); assert self.starts_inline_flow();
let mut scanner = TextRunScanner::new(); let mut scanner = TextRunScanner::new();
@ -608,7 +619,8 @@ impl InlineLayout for FlowContext {
let mut min_width = Au(0); let mut min_width = Au(0);
let mut pref_width = Au(0); let mut pref_width = Au(0);
for self.inline().boxes.each |box| { let boxes = &mut self.inline().boxes;
for boxes.each |box| {
debug!("FlowContext[%d]: measuring %s", self.d().id, box.debug_str()); debug!("FlowContext[%d]: measuring %s", self.d().id, box.debug_str());
min_width = Au::max(min_width, box.get_min_width(ctx)); min_width = Au::max(min_width, box.get_min_width(ctx));
pref_width = Au::max(pref_width, box.get_pref_width(ctx)); pref_width = Au::max(pref_width, box.get_pref_width(ctx));
@ -621,22 +633,25 @@ impl InlineLayout for FlowContext {
/* Recursively (top-down) determines the actual width of child /* Recursively (top-down) determines the actual width of child
contexts and boxes. When called on this context, the context has contexts and boxes. When called on this context, the context has
had its width set by the parent context. */ had its width set by the parent context. */
fn assign_widths_inline(@self, ctx: &LayoutContext) { fn assign_widths_inline(@mut self, ctx: &mut LayoutContext) {
assert self.starts_inline_flow(); assert self.starts_inline_flow();
// initialize (content) box widths, if they haven't been // initialize (content) box widths, if they haven't been
// already. This could be combined with LineboxScanner's walk // already. This could be combined with LineboxScanner's walk
// over the box list, and/or put into RenderBox. // over the box list, and/or put into RenderBox.
for self.inline().boxes.each |box| { let boxes = &mut self.inline().boxes;
box.d().position.size.width = match *box { for boxes.each |&box| {
@ImageBox(_, ref img) => { let box2 = &mut *box;
Au::from_px(img.get_size().get_or_default(Size2D(0,0)).width) box.d().position.size.width = match *box2 {
ImageBox(_, ref img) => {
let img2: &mut holder::ImageHolder = unsafe { cast::transmute(img) };
Au::from_px(img2.get_size().get_or_default(Size2D(0,0)).width)
} }
@TextBox(*) => { /* text boxes are initialized with dimensions */ TextBox(*) => { /* text boxes are initialized with dimensions */
box.d().position.size.width box.d().position.size.width
}, },
// TODO(Issue #225): different cases for 'inline-block', other replaced content // TODO(Issue #225): different cases for 'inline-block', other replaced content
@GenericBox(*) => Au::from_px(45), GenericBox(*) => Au::from_px(45),
_ => fail!(fmt!("Tried to assign width to unknown Box variant: %?", box)) _ => fail!(fmt!("Tried to assign width to unknown Box variant: %?", box))
}; };
} // for boxes.each |box| } // for boxes.each |box|
@ -653,7 +668,7 @@ impl InlineLayout for FlowContext {
// 'inline-block' box that created this flow before recursing. // 'inline-block' box that created this flow before recursing.
} }
fn assign_height_inline(@self, _ctx: &LayoutContext) { fn assign_height_inline(@mut self, _ctx: &mut LayoutContext) {
// TODO(Issue #226): get CSS 'line-height' property from // TODO(Issue #226): get CSS 'line-height' property from
// containing block's style to determine minimum linebox height. // containing block's style to determine minimum linebox height.
// TODO(Issue #226): get CSS 'line-height' property from each non-replaced // TODO(Issue #226): get CSS 'line-height' property from each non-replaced
@ -661,13 +676,14 @@ impl InlineLayout for FlowContext {
let line_height = Au::from_px(20); let line_height = Au::from_px(20);
let mut cur_y = Au(0); let mut cur_y = Au(0);
for self.inline().lines.eachi |i, line_span| { let lines = &mut self.inline().lines;
for lines.eachi |i, line_span| {
debug!("assign_height_inline: processing line %u with box span: %?", i, line_span); debug!("assign_height_inline: processing line %u with box span: %?", i, line_span);
// coords relative to left baseline // coords relative to left baseline
let mut linebox_bounding_box = Au::zero_rect(); let mut linebox_bounding_box = Au::zero_rect();
let boxes = &self.inline().boxes; let boxes = &mut self.inline().boxes;
for line_span.eachi |box_i| { for line_span.eachi |box_i| {
let cur_box = boxes[box_i]; let mut cur_box = boxes[box_i];
// compute box height. // compute box height.
cur_box.d().position.size.height = match cur_box { cur_box.d().position.size.height = match cur_box {
@ -731,7 +747,7 @@ impl InlineLayout for FlowContext {
self.d().position.size.height = cur_y; self.d().position.size.height = cur_y;
} }
fn build_display_list_inline(@self, builder: &DisplayListBuilder, dirty: &Rect<Au>, fn build_display_list_inline(@mut self, builder: &DisplayListBuilder, dirty: &Rect<Au>,
offset: &Point2D<Au>, list: &Mut<DisplayList>) { offset: &Point2D<Au>, list: &Mut<DisplayList>) {
assert self.starts_inline_flow(); assert self.starts_inline_flow();
@ -740,7 +756,8 @@ impl InlineLayout for FlowContext {
// smarter and not recurse on a line if nothing in it can intersect dirty // smarter and not recurse on a line if nothing in it can intersect dirty
debug!("FlowContext[%d]: building display list for %u inline boxes", debug!("FlowContext[%d]: building display list for %u inline boxes",
self.d().id, self.inline().boxes.len()); self.d().id, self.inline().boxes.len());
for self.inline().boxes.each |box| { let boxes = &mut self.inline().boxes;
for boxes.each |box| {
box.build_display_list(builder, dirty, offset, list) box.build_display_list(builder, dirty, offset, list)
} }

View file

@ -10,14 +10,16 @@ use layout::aux::LayoutAuxMethods;
use layout::box::RenderBox; use layout::box::RenderBox;
use layout::box_builder::LayoutTreeBuilder; use layout::box_builder::LayoutTreeBuilder;
use layout::context::LayoutContext; use layout::context::LayoutContext;
use layout::debug::{BoxedDebugMethods, DebugMethods}; use layout::debug::{BoxedMutDebugMethods, DebugMethods};
use layout::display_list_builder::{DisplayListBuilder, FlowDisplayListBuilderMethods}; use layout::display_list_builder::{DisplayListBuilder, FlowDisplayListBuilderMethods};
use layout::flow::FlowContext;
use layout::traverse::*; use layout::traverse::*;
use resource::image_cache_task::{ImageCacheTask, ImageResponseMsg}; use resource::image_cache_task::{ImageCacheTask, ImageResponseMsg};
use resource::local_image_cache::LocalImageCache; use resource::local_image_cache::LocalImageCache;
use util::task::spawn_listener; use util::task::spawn_listener;
use util::time::time; use util::time::time;
use core::cell::Cell;
use core::comm::{Chan, Port, SharedChan}; use core::comm::{Chan, Port, SharedChan};
use core::dvec::DVec; use core::dvec::DVec;
use core::mutable::Mut; use core::mutable::Mut;
@ -36,7 +38,6 @@ use newcss::select::SelectCtx;
use newcss::stylesheet::Stylesheet; use newcss::stylesheet::Stylesheet;
use newcss::types::OriginAuthor; use newcss::types::OriginAuthor;
use std::arc::ARC; use std::arc::ARC;
use std::cell::Cell;
use std::net::url::Url; use std::net::url::Url;
pub type LayoutTask = SharedChan<Msg>; pub type LayoutTask = SharedChan<Msg>;
@ -89,17 +90,18 @@ pub fn LayoutTask(render_task: RenderTask,
img_cache_task: ImageCacheTask, img_cache_task: ImageCacheTask,
opts: Opts) -> LayoutTask { opts: Opts) -> LayoutTask {
SharedChan(spawn_listener::<Msg>(|from_content| { SharedChan(spawn_listener::<Msg>(|from_content| {
Layout(render_task.clone(), img_cache_task.clone(), from_content, &opts).start(); let mut layout = Layout(render_task.clone(), img_cache_task.clone(), from_content, &opts);
layout.start();
})) }))
} }
struct Layout { struct Layout {
render_task: RenderTask, render_task: RenderTask,
image_cache_task: ImageCacheTask, image_cache_task: ImageCacheTask,
local_image_cache: @LocalImageCache, local_image_cache: @mut LocalImageCache,
from_content: Port<Msg>, from_content: Port<Msg>,
font_ctx: @FontContext, font_ctx: @mut FontContext,
// This is used to root reader data // This is used to root reader data
layout_refs: DVec<@mut LayoutData>, layout_refs: DVec<@mut LayoutData>,
css_select_ctx: Mut<SelectCtx>, css_select_ctx: Mut<SelectCtx>,
@ -110,12 +112,12 @@ fn Layout(render_task: RenderTask,
from_content: Port<Msg>, from_content: Port<Msg>,
opts: &Opts) opts: &Opts)
-> Layout { -> Layout {
let fctx = @FontContext::new(opts.render_backend, true); let fctx = @mut FontContext::new(opts.render_backend, true);
Layout { Layout {
render_task: render_task, render_task: render_task,
image_cache_task: image_cache_task.clone(), image_cache_task: image_cache_task.clone(),
local_image_cache: @LocalImageCache(image_cache_task), local_image_cache: @mut LocalImageCache(image_cache_task),
from_content: from_content, from_content: from_content,
font_ctx: fctx, font_ctx: fctx,
layout_refs: DVec(), layout_refs: DVec(),
@ -125,13 +127,13 @@ fn Layout(render_task: RenderTask,
impl Layout { impl Layout {
fn start() { fn start(&mut self) {
while self.handle_request() { while self.handle_request() {
// loop indefinitely // loop indefinitely
} }
} }
fn handle_request() -> bool { fn handle_request(&mut self) -> bool {
match self.from_content.recv() { match self.from_content.recv() {
AddStylesheet(sheet) => { AddStylesheet(sheet) => {
@ -167,7 +169,7 @@ impl Layout {
} }
} }
fn handle_build(data: &BuildData) { fn handle_build(&mut self, data: &BuildData) {
let node = &data.node; let node = &data.node;
// FIXME: Bad copy // FIXME: Bad copy
let doc_url = copy data.url; let doc_url = copy data.url;
@ -185,7 +187,7 @@ impl Layout {
let screen_size = Size2D(Au::from_px(data.window_size.width as int), let screen_size = Size2D(Au::from_px(data.window_size.width as int),
Au::from_px(data.window_size.height as int)); Au::from_px(data.window_size.height as int));
let layout_ctx = LayoutContext { let mut layout_ctx = LayoutContext {
image_cache: self.local_image_cache, image_cache: self.local_image_cache,
font_ctx: self.font_ctx, font_ctx: self.font_ctx,
doc_url: doc_url, doc_url: doc_url,
@ -209,10 +211,10 @@ impl Layout {
} }
} }
let layout_root: @FlowContext = do time("layout: tree construction") { let layout_root: @mut FlowContext = do time("layout: tree construction") {
let builder = LayoutTreeBuilder::new(); let mut builder = LayoutTreeBuilder::new();
let layout_root: @FlowContext = match builder.construct_trees(&layout_ctx, let layout_root: @mut FlowContext = match builder.construct_trees(&layout_ctx,
*node) { *node) {
Ok(root) => root, Ok(root) => root,
Err(*) => fail!(~"Root flow should always exist") Err(*) => fail!(~"Root flow should always exist")
}; };
@ -225,9 +227,9 @@ impl Layout {
do time("layout: main layout") { do time("layout: main layout") {
/* perform layout passes over the flow tree */ /* perform layout passes over the flow tree */
do layout_root.traverse_postorder |f| { f.bubble_widths(&layout_ctx) } do layout_root.traverse_postorder |f| { f.bubble_widths(&mut layout_ctx) }
do layout_root.traverse_preorder |f| { f.assign_widths(&layout_ctx) } do layout_root.traverse_preorder |f| { f.assign_widths(&mut layout_ctx) }
do layout_root.traverse_postorder |f| { f.assign_height(&layout_ctx) } do layout_root.traverse_postorder |f| { f.assign_height(&mut layout_ctx) }
} }
do time("layout: display list building") { do time("layout: display list building") {

View file

@ -13,7 +13,7 @@ use util::tree;
use core::mutable::Mut; use core::mutable::Mut;
pub struct RootFlowData { pub struct RootFlowData {
mut box: Option<@RenderBox> box: Option<@mut RenderBox>
} }
pub fn RootFlowData() -> RootFlowData { pub fn RootFlowData() -> RootFlowData {
@ -25,10 +25,10 @@ pub fn RootFlowData() -> RootFlowData {
pub trait RootLayout { pub trait RootLayout {
pure fn starts_root_flow() -> bool; pure fn starts_root_flow() -> bool;
fn bubble_widths_root(@self, ctx: &LayoutContext); fn bubble_widths_root(@mut self, ctx: &LayoutContext);
fn assign_widths_root(@self, ctx: &LayoutContext); fn assign_widths_root(@mut self, ctx: &LayoutContext);
fn assign_height_root(@self, ctx: &LayoutContext); fn assign_height_root(@mut self, ctx: &LayoutContext);
fn build_display_list_root(@self, a: &DisplayListBuilder, b: &Rect<Au>, fn build_display_list_root(@mut self, a: &DisplayListBuilder, b: &Rect<Au>,
c: &Point2D<Au>, d: &Mut<DisplayList>); c: &Point2D<Au>, d: &Mut<DisplayList>);
} }
@ -41,12 +41,12 @@ impl RootLayout for FlowContext {
} }
/* defer to the block algorithm */ /* defer to the block algorithm */
fn bubble_widths_root(@self, ctx: &LayoutContext) { fn bubble_widths_root(@mut self, ctx: &LayoutContext) {
assert self.starts_root_flow(); assert self.starts_root_flow();
self.bubble_widths_block(ctx) self.bubble_widths_block(ctx)
} }
fn assign_widths_root(@self, ctx: &LayoutContext) { fn assign_widths_root(@mut self, ctx: &LayoutContext) {
assert self.starts_root_flow(); assert self.starts_root_flow();
self.d().position.origin = Au::zero_point(); self.d().position.origin = Au::zero_point();
@ -55,7 +55,7 @@ impl RootLayout for FlowContext {
self.assign_widths_block(ctx) self.assign_widths_block(ctx)
} }
fn assign_height_root(@self, ctx: &LayoutContext) { fn assign_height_root(@mut self, ctx: &LayoutContext) {
assert self.starts_root_flow(); assert self.starts_root_flow();
// this is essentially the same as assign_height_block(), except // this is essentially the same as assign_height_block(), except
@ -76,7 +76,7 @@ impl RootLayout for FlowContext {
} }
} }
fn build_display_list_root(@self, builder: &DisplayListBuilder, dirty: &Rect<Au>, fn build_display_list_root(@mut self, builder: &DisplayListBuilder, dirty: &Rect<Au>,
offset: &Point2D<Au>, list: &Mut<DisplayList>) { offset: &Point2D<Au>, list: &Mut<DisplayList>) {
assert self.starts_root_flow(); assert self.starts_root_flow();

View file

@ -17,27 +17,27 @@ pub fn TextBoxData(run: @TextRun, range: &const Range) -> TextBoxData {
} }
} }
pub fn adapt_textbox_with_range(box_data: &RenderBoxData, run: @TextRun, pub fn adapt_textbox_with_range(box_data: &mut RenderBoxData, run: @TextRun,
range: &const Range) -> @RenderBox { range: &const Range) -> @mut RenderBox {
assert range.begin() < run.char_len(); assert range.begin() < run.char_len();
assert range.end() <= run.char_len(); assert range.end() <= run.char_len();
assert range.length() > 0; assert range.length() > 0;
debug!("Creating textbox with span: (strlen=%u, off=%u, len=%u) of textrun: %s", debug!("Creating textbox with span: (strlen=%u, off=%u, len=%u) of textrun: %s",
run.char_len(), range.begin(), range.length(), run.text); run.char_len(), range.begin(), range.length(), run.text);
let new_box_data = copy *box_data; let mut new_box_data = copy *box_data;
let new_text_data = TextBoxData(run, range); let new_text_data = TextBoxData(run, range);
let metrics = run.metrics_for_range(range); let metrics = run.metrics_for_range(range);
new_box_data.position.size = metrics.bounding_box.size; new_box_data.position.size = metrics.bounding_box.size;
@TextBox(new_box_data, new_text_data) @mut TextBox(new_box_data, new_text_data)
} }
pub trait UnscannedMethods { pub trait UnscannedMethods {
pure fn raw_text(&self) -> ~str; pure fn raw_text(&mut self) -> ~str;
} }
impl UnscannedMethods for RenderBox { impl UnscannedMethods for RenderBox {
pure fn raw_text(&self) -> ~str { pure fn raw_text(&mut self) -> ~str {
match self { match self {
&UnscannedTextBox(_, ref s) => copy *s, &UnscannedTextBox(_, ref s) => copy *s,
_ => fail!(~"unsupported operation: box.raw_text() on non-unscanned text box.") _ => fail!(~"unsupported operation: box.raw_text() on non-unscanned text box.")

View file

@ -1,18 +1,18 @@
use layout::flow::{FlowContext, FlowTree}; use layout::flow::{FlowContext, FlowTree};
/** Trait for running tree-based traversals over layout contexts */ /** Trait for running tree-based traversals over layout contexts */
trait FlowContextTraversals { pub trait FlowContextTraversals {
fn traverse_preorder(preorder_cb: &fn(@FlowContext)); fn traverse_preorder(preorder_cb: &fn(@mut FlowContext));
fn traverse_postorder(postorder_cb: &fn(@FlowContext)); fn traverse_postorder(postorder_cb: &fn(@mut FlowContext));
} }
impl FlowContextTraversals for @FlowContext { impl FlowContextTraversals for @mut FlowContext {
fn traverse_preorder(preorder_cb: &fn(@FlowContext)) { fn traverse_preorder(preorder_cb: &fn(@mut FlowContext)) {
preorder_cb(self); preorder_cb(self);
do FlowTree.each_child(self) |child| { child.traverse_preorder(preorder_cb); true } do FlowTree.each_child(self) |child| { child.traverse_preorder(preorder_cb); true }
} }
fn traverse_postorder(postorder_cb: &fn(@FlowContext)) { fn traverse_postorder(postorder_cb: &fn(@mut FlowContext)) {
do FlowTree.each_child(self) |child| { child.traverse_postorder(postorder_cb); true } do FlowTree.each_child(self) |child| { child.traverse_postorder(postorder_cb); true }
postorder_cb(self); postorder_cb(self);
} }

View file

@ -15,12 +15,13 @@ use gfx::compositor::{Compositor, LayerBuffer, LayerBufferSet};
use gfx::opts::Opts; use gfx::opts::Opts;
use gfx::util::time; use gfx::util::time;
use layers::layers::ImageLayer; use layers::layers::ImageLayer;
use std::cell::Cell; use core::cell::Cell;
use std::cmp::FuzzyEq; use std::cmp::FuzzyEq;
use glut::glut; use glut::glut;
use layers; use layers;
use sharegl; use sharegl;
use sharegl::ShareGlContext; use sharegl::ShareGlContext;
use sharegl::base::ShareContext;
pub struct OSMain { pub struct OSMain {
chan: SharedChan<Msg> chan: SharedChan<Msg>
@ -81,13 +82,13 @@ struct AzureDrawTargetImageData {
} }
impl layers::layers::ImageData for AzureDrawTargetImageData { impl layers::layers::ImageData for AzureDrawTargetImageData {
fn size() -> Size2D<uint> { self.size } fn size(&self) -> Size2D<uint> { self.size }
fn stride() -> uint { self.data_source_surface.get_size().width as uint } fn stride(&self) -> uint { self.data_source_surface.get_size().width as uint }
fn format() -> layers::layers::Format { fn format(&self) -> layers::layers::Format {
// FIXME: This is not always correct. We should query the Azure draw target for the format. // FIXME: This is not always correct. We should query the Azure draw target for the format.
layers::layers::ARGB32Format layers::layers::ARGB32Format
} }
fn with_data(f: layers::layers::WithDataFn) { fn with_data(&self, f: layers::layers::WithDataFn) {
do self.data_source_surface.with_data |data| { do self.data_source_surface.with_data |data| {
f(data); f(data);
} }
@ -117,19 +118,21 @@ fn mainloop(mode: Mode,
} }
} }
let surfaces = @SurfaceSet(opts.render_backend); let surfaces = @mut SurfaceSet(opts.render_backend);
let context = layers::rendergl::init_render_context(); let context = layers::rendergl::init_render_context();
let root_layer = @layers::layers::ContainerLayer(); let root_layer = @mut layers::layers::ContainerLayer();
let original_layer_transform; let original_layer_transform;
{ {
let image_data = @layers::layers::BasicImageData::new(Size2D(0u, 0u), let mut image_data = @mut layers::layers::BasicImageData::new(Size2D(0u, 0u),
0, 0,
layers::layers::RGB24Format, layers::layers::RGB24Format,
~[]); ~[]);
let image = @layers::layers::Image::new(image_data as @layers::layers::ImageData); //XXXjdm How can we obtain a @mut @ImageData without transmute?
let image_layer = @layers::layers::ImageLayer(image); let image_data: @mut @layers::layers::ImageData = unsafe { cast::transmute(image_data) };
let image = @mut layers::layers::Image::new(image_data);
let image_layer = @mut layers::layers::ImageLayer(image);
original_layer_transform = image_layer.common.transform; original_layer_transform = image_layer.common.transform;
image_layer.common.set_transform(original_layer_transform.scale(800.0, 600.0, 1.0)); image_layer.common.set_transform(original_layer_transform.scale(800.0, 600.0, 1.0));
root_layer.add_child(layers::layers::ImageLayerKind(image_layer)); root_layer.add_child(layers::layers::ImageLayerKind(image_layer));
@ -141,8 +144,8 @@ fn mainloop(mode: Mode,
identity()); identity());
let done = @mut false; let done = @mut false;
let resize_rate_limiter = @ResizeRateLimiter(dom_event_chan); let resize_rate_limiter = @mut ResizeRateLimiter(dom_event_chan);
let check_for_messages = fn@() { let check_for_messages: @fn() = || {
// Periodically check if content responded to our last resize event // Periodically check if content responded to our last resize event
resize_rate_limiter.check_resize_response(); resize_rate_limiter.check_resize_response();
@ -169,20 +172,21 @@ fn mainloop(mode: Mode,
debug!("osmain: compositing buffer rect %?", &buffer.rect); debug!("osmain: compositing buffer rect %?", &buffer.rect);
let image_data = @AzureDrawTargetImageData { let image_data = @mut AzureDrawTargetImageData {
draw_target: buffer.draw_target.clone(), draw_target: buffer.draw_target.clone(),
data_source_surface: buffer.draw_target.snapshot().get_data_surface(), data_source_surface: buffer.draw_target.snapshot().get_data_surface(),
size: Size2D(width, height) size: Size2D(width, height)
}; };
let image = @layers::layers::Image::new( //XXXjdm How can we extract a @mut @ImageData without transmute?
image_data as @layers::layers::ImageData); let image_data: @mut @layers::layers::ImageData = unsafe { cast::transmute(image_data) };
let image = @mut layers::layers::Image::new(image_data);
// Find or create an image layer. // Find or create an image layer.
let image_layer; let image_layer;
current_layer_child = match current_layer_child { current_layer_child = match current_layer_child {
None => { None => {
debug!("osmain: adding new image layer"); debug!("osmain: adding new image layer");
image_layer = @layers::layers::ImageLayer(image); image_layer = @mut layers::layers::ImageLayer(image);
root_layer.add_child(layers::layers::ImageLayerKind(image_layer)); root_layer.add_child(layers::layers::ImageLayerKind(image_layer));
None None
} }
@ -216,7 +220,7 @@ fn mainloop(mode: Mode,
} }
}; };
let adjust_for_window_resizing: fn@() = || { let adjust_for_window_resizing: @fn() = || {
let window_width = glut::get(glut::WindowWidth) as uint; let window_width = glut::get(glut::WindowWidth) as uint;
let window_height = glut::get(glut::WindowHeight) as uint; let window_height = glut::get(glut::WindowHeight) as uint;
@ -226,7 +230,7 @@ fn mainloop(mode: Mode,
*size = Size2D(window_width as f32, window_height as f32); *size = Size2D(window_width as f32, window_height as f32);
}; };
let composite: fn@() = || { let composite: @fn() = || {
//#debug("osmain: drawing to screen"); //#debug("osmain: drawing to screen");
do time::time(~"compositing") { do time::time(~"compositing") {
@ -276,20 +280,20 @@ Implementation to allow the osmain channel to be used as a graphics
compositor for the renderer compositor for the renderer
*/ */
impl Compositor for OSMain { impl Compositor for OSMain {
fn begin_drawing(next_dt: comm::Chan<LayerBufferSet>) { fn begin_drawing(&self, next_dt: comm::Chan<LayerBufferSet>) {
self.chan.send(BeginDrawing(next_dt)) self.chan.send(BeginDrawing(next_dt))
} }
fn draw(next_dt: comm::Chan<LayerBufferSet>, draw_me: LayerBufferSet) { fn draw(&self, next_dt: comm::Chan<LayerBufferSet>, draw_me: LayerBufferSet) {
self.chan.send(Draw(next_dt, draw_me)) self.chan.send(Draw(next_dt, draw_me))
} }
} }
struct SurfaceSet { struct SurfaceSet {
mut front: Surface, front: Surface,
mut back: Surface, back: Surface,
} }
fn lend_surface(surfaces: &SurfaceSet, receiver: comm::Chan<LayerBufferSet>) { fn lend_surface(surfaces: &mut SurfaceSet, receiver: comm::Chan<LayerBufferSet>) {
// We are in a position to lend out the surface? // We are in a position to lend out the surface?
assert surfaces.front.have; assert surfaces.front.have;
// Ok then take it // Ok then take it
@ -316,7 +320,7 @@ fn lend_surface(surfaces: &SurfaceSet, receiver: comm::Chan<LayerBufferSet>) {
assert surfaces.front.have; assert surfaces.front.have;
} }
fn return_surface(surfaces: &SurfaceSet, layer_buffer_set: LayerBufferSet) { fn return_surface(surfaces: &mut SurfaceSet, layer_buffer_set: LayerBufferSet) {
//#debug("osmain: returning surface %?", layer_buffer_set); //#debug("osmain: returning surface %?", layer_buffer_set);
// We have room for a return // We have room for a return
assert surfaces.front.have; assert surfaces.front.have;
@ -334,7 +338,7 @@ fn SurfaceSet(backend: BackendType) -> SurfaceSet {
struct Surface { struct Surface {
layer_buffer_set: LayerBufferSet, layer_buffer_set: LayerBufferSet,
mut have: bool, have: bool,
} }
fn Surface(backend: BackendType) -> Surface { fn Surface(backend: BackendType) -> Surface {
@ -348,7 +352,7 @@ fn Surface(backend: BackendType) -> Surface {
} }
/// A function for spawning into the platform's main thread /// A function for spawning into the platform's main thread
fn on_osmain<T: Owned>(f: fn~(po: Port<T>)) -> Chan<T> { fn on_osmain<T: Owned>(f: ~fn(po: Port<T>)) -> Chan<T> {
let (setup_po, setup_ch) = comm::stream(); let (setup_po, setup_ch) = comm::stream();
do task::task().sched_mode(task::PlatformThread).spawn { do task::task().sched_mode(task::PlatformThread).spawn {
let (po, ch) = comm::stream(); let (po, ch) = comm::stream();

View file

@ -11,9 +11,9 @@ pub struct ResizeRateLimiter {
/// The channel we send resize events on /// The channel we send resize events on
/* priv */ dom_event_chan: comm::SharedChan<Event>, /* priv */ dom_event_chan: comm::SharedChan<Event>,
/// The port we are waiting on for a response to the last resize event /// The port we are waiting on for a response to the last resize event
/* priv */ mut last_response_port: Option<comm::Port<()>>, /* priv */ last_response_port: Option<comm::Port<()>>,
/// The next window resize event we should fire /// The next window resize event we should fire
/* priv */ mut next_resize_event: Option<(uint, uint)> /* priv */ next_resize_event: Option<(uint, uint)>
} }
pub fn ResizeRateLimiter(dom_event_chan: comm::SharedChan<Event>) -> ResizeRateLimiter { pub fn ResizeRateLimiter(dom_event_chan: comm::SharedChan<Event>) -> ResizeRateLimiter {
@ -24,8 +24,8 @@ pub fn ResizeRateLimiter(dom_event_chan: comm::SharedChan<Event>) -> ResizeRateL
} }
} }
impl ResizeRateLimiter { pub impl ResizeRateLimiter {
fn window_resized(width: uint, height: uint) { fn window_resized(&mut self, width: uint, height: uint) {
match self.last_response_port { match self.last_response_port {
None => { None => {
assert self.next_resize_event.is_none(); assert self.next_resize_event.is_none();
@ -45,7 +45,7 @@ impl ResizeRateLimiter {
} }
} }
fn check_resize_response() { fn check_resize_response(&mut self) {
match self.next_resize_event { match self.next_resize_event {
Some((copy width, copy height)) => { Some((copy width, copy height)) => {
assert self.last_response_port.is_some(); assert self.last_response_port.is_some();
@ -58,7 +58,7 @@ impl ResizeRateLimiter {
} }
} }
priv fn send_event(width: uint, height: uint) { priv fn send_event(&mut self, width: uint, height: uint) {
let (port, chan) = comm::stream(); let (port, chan) = comm::stream();
self.dom_event_chan.send(ResizeEvent(width, height, chan)); self.dom_event_chan.send(ResizeEvent(width, height, chan));
self.last_response_port = Some(port); self.last_response_port = Some(port);

View file

@ -1,8 +1,8 @@
use core::cell::Cell;
use core::comm::{Chan, Port}; use core::comm::{Chan, Port};
use core::task; use core::task;
use std::cell::Cell;
pub fn spawn_listener<A: Owned>(f: fn~(Port<A>)) -> Chan<A> { pub fn spawn_listener<A: Owned>(f: ~fn(Port<A>)) -> Chan<A> {
let (setup_po, setup_ch) = comm::stream(); let (setup_po, setup_ch) = comm::stream();
do task::spawn { do task::spawn {
let (po, ch) = comm::stream(); let (po, ch) = comm::stream();
@ -12,7 +12,7 @@ pub fn spawn_listener<A: Owned>(f: fn~(Port<A>)) -> Chan<A> {
setup_po.recv() setup_po.recv()
} }
pub fn spawn_conversation<A: Owned, B: Owned>(f: fn~(Port<A>, Chan<B>)) -> (Port<B>, Chan<A>) { pub fn spawn_conversation<A: Owned, B: Owned>(f: ~fn(Port<A>, Chan<B>)) -> (Port<B>, Chan<A>) {
let (from_child, to_parent) = comm::stream(); let (from_child, to_parent) = comm::stream();
let to_parent = Cell(to_parent); let to_parent = Cell(to_parent);
let to_child = do spawn_listener |from_parent| { let to_child = do spawn_listener |from_parent| {

View file

@ -5,19 +5,19 @@ use core::vec;
// TODO: Use traits. // TODO: Use traits.
pub struct Tree<T> { pub struct Tree<T> {
mut parent: Option<T>, parent: Option<T>,
mut first_child: Option<T>, first_child: Option<T>,
mut last_child: Option<T>, last_child: Option<T>,
mut prev_sibling: Option<T>, prev_sibling: Option<T>,
mut next_sibling: Option<T> next_sibling: Option<T>
} }
pub trait ReadMethods<T> { pub trait ReadMethods<T> {
fn with_tree_fields<R>(&T, f: fn(&Tree<T>) -> R) -> R; fn with_tree_fields<R>(&T, f: fn(&mut Tree<T>) -> R) -> R;
} }
pub trait WriteMethods<T> { pub trait WriteMethods<T> {
fn with_tree_fields<R>(&T, f: fn(&Tree<T>) -> R) -> R; fn with_tree_fields<R>(&T, f: fn(&mut Tree<T>) -> R) -> R;
pure fn tree_eq(&T, &T) -> bool; pure fn tree_eq(&T, &T) -> bool;
} }
@ -161,10 +161,10 @@ mod test {
use super::*; use super::*;
use core::managed::ptr_eq; use core::managed::ptr_eq;
enum dummy = { struct dummy {
fields: Tree<@dummy>, fields: Tree<@dummy>,
value: uint value: uint
}; }
enum dtree { dtree } enum dtree { dtree }
@ -182,10 +182,10 @@ mod test {
} }
fn new_dummy(v: uint) -> @dummy { fn new_dummy(v: uint) -> @dummy {
@dummy({fields: empty(), value: v}) @dummy {fields: empty(), value: v}
} }
fn parent_with_3_children() -> {p: @dummy, children: ~[@dummy]} { fn parent_with_3_children() -> (@dummy, ~[@dummy]) {
let children = ~[new_dummy(0u), let children = ~[new_dummy(0u),
new_dummy(1u), new_dummy(1u),
new_dummy(2u)]; new_dummy(2u)];
@ -195,12 +195,12 @@ mod test {
add_child(&dtree, p, *c); add_child(&dtree, p, *c);
} }
return {p: p, children: children}; return (p, children);
} }
#[test] #[test]
fn add_child_0() { fn add_child_0() {
let {p, children} = parent_with_3_children(); let (p, children) = parent_with_3_children();
let mut i = 0u; let mut i = 0u;
for each_child(&dtree, &p) |c| { for each_child(&dtree, &p) |c| {
assert c.value == i; assert c.value == i;
@ -211,7 +211,7 @@ mod test {
#[test] #[test]
fn add_child_break() { fn add_child_break() {
let {p, _} = parent_with_3_children(); let (p, _) = parent_with_3_children();
let mut i = 0u; let mut i = 0u;
for each_child(&dtree, &p) |_c| { for each_child(&dtree, &p) |_c| {
i += 1u; i += 1u;
@ -222,7 +222,7 @@ mod test {
#[test] #[test]
fn remove_first_child() { fn remove_first_child() {
let {p, children} = parent_with_3_children(); let (p, children) = parent_with_3_children();
remove_child(&dtree, p, children[0]); remove_child(&dtree, p, children[0]);
let mut i = 0; let mut i = 0;
@ -234,7 +234,7 @@ mod test {
#[test] #[test]
fn remove_last_child() { fn remove_last_child() {
let {p, children} = parent_with_3_children(); let (p, children) = parent_with_3_children();
remove_child(&dtree, p, children[2]); remove_child(&dtree, p, children[2]);
let mut i = 0; let mut i = 0;
@ -246,7 +246,7 @@ mod test {
#[test] #[test]
fn remove_middle_child() { fn remove_middle_child() {
let {p, children} = parent_with_3_children(); let (p, children) = parent_with_3_children();
remove_child(&dtree, p, children[1]); remove_child(&dtree, p, children[1]);
let mut i = 0; let mut i = 0;
@ -258,7 +258,7 @@ mod test {
#[test] #[test]
fn remove_all_child() { fn remove_all_child() {
let {p, children} = parent_with_3_children(); let (p, children) = parent_with_3_children();
remove_child(&dtree, p, children[0]); remove_child(&dtree, p, children[0]);
remove_child(&dtree, p, children[1]); remove_child(&dtree, p, children[1]);
remove_child(&dtree, p, children[2]); remove_child(&dtree, p, children[2]);

@ -1 +1 @@
Subproject commit 0c2a999c2fc4b04a5580670343344e9fced91228 Subproject commit c14a4786b98dbb135cd0479d749be1bef0b57376