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
*/
pub trait Compositor {
fn begin_drawing(next_dt: comm::Chan<LayerBufferSet>);
fn draw(next_dt: comm::Chan<LayerBufferSet>, +draw_me: LayerBufferSet);
fn begin_drawing(&self, next_dt: comm::Chan<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);
}
fn draw_into_context(ctx: &RenderContext) {
fn draw_into_context(&self, ctx: &RenderContext) {
debug!("beginning display list");
for self.list.each |item| {
// FIXME(Issue #150): crashes

View file

@ -33,17 +33,17 @@ pub type FontHandle/& = freetype_impl::font::FreeTypeFontHandle;
pub trait FontHandleMethods {
// an identifier usable by FontContextHandle to recreate this FontHandle.
pure fn face_identifier() -> ~str;
pure fn family_name() -> ~str;
pure fn face_name() -> ~str;
pure fn is_italic() -> bool;
pure fn boldness() -> CSSFontWeight;
pure fn face_identifier(&self) -> ~str;
pure fn family_name(&self) -> ~str;
pure fn face_name(&self) -> ~str;
pure fn is_italic(&self) -> bool;
pure fn boldness(&self) -> CSSFontWeight;
fn clone_with_style(fctx: &native::FontContextHandle, style: &UsedFontStyle) -> Result<FontHandle, ()>;
fn glyph_index(codepoint: char) -> Option<GlyphIndex>;
fn glyph_h_advance(GlyphIndex) -> Option<FractionalPixel>;
fn get_metrics() -> FontMetrics;
fn get_table_for_tag(FontTableTag) -> Option<FontTable>;
fn clone_with_style(&self, fctx: &native::FontContextHandle, style: &UsedFontStyle) -> Result<FontHandle, ()>;
fn glyph_index(&self, codepoint: char) -> Option<GlyphIndex>;
fn glyph_h_advance(&self, GlyphIndex) -> Option<FractionalPixel>;
fn get_metrics(&self) -> FontMetrics;
fn get_table_for_tag(&self, FontTableTag) -> Option<FontTable>;
}
// TODO(Issue #163): this is a workaround for static methods and
@ -75,13 +75,13 @@ pub type FractionalPixel = float;
pub type FontTableTag = u32;
trait FontTableTagConversions {
pub pure fn tag_to_str() -> ~str;
pub pure fn tag_to_str(&self) -> ~str;
}
impl FontTableTagConversions for FontTableTag {
pub pure fn tag_to_str() -> ~str {
pub pure fn tag_to_str(&self) -> ~str {
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),
reversed.char_at(2),
reversed.char_at(1),
@ -97,7 +97,7 @@ pub type FontTable/& = quartz::font::QuartzFontTable;
pub type FontTable/& = freetype_impl::font::FreeTypeFontTable;
pub trait FontTableMethods {
fn with_buffer(fn&(*u8, uint));
fn with_buffer(&self, &fn(*u8, uint));
}
pub struct FontMetrics {
@ -126,7 +126,7 @@ pub enum CSSFontWeight {
}
pub impl CSSFontWeight {
pub pure fn is_bold() -> bool {
pub pure fn is_bold(self) -> bool {
match self {
FontWeight900 | FontWeight800 | FontWeight700 | FontWeight600 => true,
_ => false
@ -199,11 +199,11 @@ pub struct FontGroup {
// style of the first western font in group, which is
// used for purposes of calculating text run metrics.
style: UsedFontStyle,
fonts: ~[@Font],
fonts: ~[@mut Font],
}
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 {
families: families,
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;
// 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 {
priv handle: FontHandle,
priv mut azure_font: Option<ScaledFont>,
priv mut shaper: Option<@Shaper>,
priv azure_font: Option<ScaledFont>,
priv shaper: Option<@Shaper>,
style: UsedFontStyle,
metrics: FontMetrics,
backend: BackendType,
@ -247,7 +247,7 @@ pub impl Font {
buffer: ~[u8],
style: &SpecifiedFontStyle,
backend: BackendType)
-> Result<@Font, ()> {
-> Result<@mut Font, ()> {
let handle = FontHandle::new_from_buffer(&ctx.handle, buffer, style);
let handle = if handle.is_ok() {
result::unwrap(handle)
@ -258,7 +258,7 @@ pub impl Font {
let metrics = handle.get_metrics();
// TODO(Issue #179): convert between specified and used font style here?
return Ok(@Font {
return Ok(@mut Font {
handle: handle,
azure_font: None,
shaper: None,
@ -269,10 +269,10 @@ pub impl Font {
}
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();
@Font {
@mut Font {
handle: handle,
azure_font: None,
shaper: None,
@ -283,7 +283,7 @@ pub impl Font {
}
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?
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));
}
priv fn get_shaper(@self) -> @Shaper {
priv fn get_shaper(@mut self) -> @Shaper {
// fast path: already created a shaper
match self.shaper {
Some(shaper) => { return shaper; },
@ -306,7 +306,7 @@ pub impl Font {
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 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
// 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
match self.azure_font {
Some(ref azfont) => return azfont.get_ref(),
@ -341,7 +341,7 @@ pub impl Font {
}
#[cfg(target_os="linux")]
priv fn create_azure_font() -> ScaledFont {
priv fn create_azure_font(&self) -> ScaledFont {
let cairo_font = self.handle.face;
let size = self.style.pt_size as AzFloat;
ScaledFont::new(self.backend, cairo_font, size)
@ -350,7 +350,8 @@ pub impl Font {
pub impl Font {
fn draw_text_into_context(rctx: &RenderContext,
fn draw_text_into_context(&mut self,
rctx: &RenderContext,
run: &TextRun,
range: &const Range,
baseline_origin: Point2D<Au>,
@ -411,7 +412,7 @@ pub impl Font {
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 #98): using inter-char and inter-word spacing settings when measuring text
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.
// For example, Gecko uses a per-"word" hashtable of shaper results.
let shaper = self.get_shaper();
shaper.shape_text(text, store);
}
fn get_descriptor() -> FontDescriptor {
fn get_descriptor(&self) -> FontDescriptor {
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)
}
fn glyph_h_advance(glyph: GlyphIndex) -> FractionalPixel {
fn glyph_h_advance(&self, glyph: GlyphIndex) -> FractionalPixel {
match self.handle.glyph_h_advance(glyph) {
Some(adv) => adv,
None => /* FIXME: Need fallback strategy */ 10f as FractionalPixel

View file

@ -44,7 +44,7 @@ type FontContextHandle/& = freetype_impl::font_context::FreeTypeFontContextHandl
pub trait FontContextHandleMethods {
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,
@ -63,7 +63,7 @@ pub impl FontContextHandle {
#[allow(non_implicitly_copyable_typarams)]
pub struct FontContext {
instance_cache: MonoCache<FontDescriptor, @Font>,
instance_cache: MonoCache<FontDescriptor, @mut Font>,
font_list: Option<FontList>, // only needed by layout
handle: FontContextHandle,
backend: BackendType,
@ -87,7 +87,7 @@ pub impl FontContext {
FontContext {
// TODO(Rust #3902): remove extraneous type parameters once they are inferred correctly.
instance_cache:
Cache::new::<FontDescriptor,@Font,MonoCache<FontDescriptor,@Font>>(10),
Cache::new::<FontDescriptor,@mut Font,MonoCache<FontDescriptor,@mut Font>>(10),
font_list: font_list,
handle: handle,
backend: backend,
@ -99,12 +99,12 @@ pub impl FontContext {
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.
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) {
Some(f) => Ok(f),
None => {
@ -130,7 +130,7 @@ pub impl FontContext {
}
// 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();
debug!("(create font group) --- starting ---");
@ -145,11 +145,11 @@ pub impl FontContext {
let result = list.find_font_in_family(transformed_family_name, style);
let mut found = false;
do result.iter |font_entry| {
for result.each |font_entry| {
found = true;
// 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);
do result::iter(&instance) |font: &@Font| { fonts.push(*font); }
let instance = Font::new_from_existing_handle(self, &font_entry.handle, style, self.backend);
do result::iter(&instance) |font: &@mut Font| { fonts.push(*font); }
};
if !found {
@ -178,17 +178,17 @@ pub impl FontContext {
@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 {
&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.
&SelectorPlatformIdentifier(ref identifier) => {
let result_handle = self.handle.create_font_from_identifier(copy *identifier,
copy desc.style);
result::chain(result_handle, |handle| {
Ok(Font::new_from_adopted_handle(&self,
Ok(Font::new_from_adopted_handle(self,
handle,
&desc.style,
self.backend))

View file

@ -2,7 +2,6 @@ use font::{CSSFontWeight, SpecifiedFontStyle, UsedFontStyle};
use gfx_font::FontHandleMethods;
use native::FontHandle;
use dvec::DVec;
use core::hashmap::linear;
#[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 {
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 {
mut family_map: FontFamilyMap,
family_map: FontFamilyMap,
handle: FontListHandle,
}
pub impl FontList {
static fn new(fctx: &native::FontContextHandle) -> FontList {
let handle = result::unwrap(FontListHandle::new(fctx));
let list = FontList {
let mut list = FontList {
handle: handle,
family_map: linear::LinearMap::new(),
};
@ -53,7 +52,7 @@ pub impl FontList {
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
// 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> {
let family = self.find_family(family_name);
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'.
// 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);
}
@ -81,7 +81,7 @@ pub impl FontList {
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
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
pub struct FontFamily {
family_name: ~str,
entries: DVec<@FontEntry>,
entries: ~[@FontEntry],
}
pub impl FontFamily {
static fn new(family_name: &str) -> FontFamily {
FontFamily {
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; }
list.load_variations_for_family(self);
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);
@ -141,7 +141,7 @@ pub impl FontFamily {
// In the common case, each FontFamily will have a singleton FontEntry, or
// it will have the standard four faces: Normal, Bold, Italic, BoldItalic.
pub struct FontEntry {
family: @FontFamily,
family: @mut FontFamily,
face_name: ~str,
priv weight: CSSFontWeight,
priv italic: bool,
@ -150,7 +150,7 @@ pub struct FontEntry {
}
pub impl FontEntry {
static fn new(family: @FontFamily, handle: FontHandle) -> FontEntry {
static fn new(family: @mut FontFamily, handle: FontHandle) -> FontEntry {
FontEntry {
family: family,
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()
}
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 fontconfig;
use fc = fontconfig;
use ft = freetype;
use gfx_font::{FontHandle, FontHandleMethods};
use gfx_font_list::{FontEntry, FontFamily, FontFamilyMap};
use gfx_font_context::FontContextHandleMethods;
@ -24,8 +21,8 @@ use self::fontconfig::fontconfig::bindgen::{
use core::dvec::DVec;
use core::hashmap::linear;
use libc::c_int;
use ptr::Ptr;
use core::libc::c_int;
use core::ptr::Ptr;
use native;
pub struct FontconfigFontListHandle {
@ -37,7 +34,7 @@ pub impl FontconfigFontListHandle {
FontconfigFontListHandle { fctx: fctx.clone() }
}
fn get_available_families() -> FontFamilyMap {
fn get_available_families(&self) -> FontFamilyMap {
let mut family_map : FontFamilyMap = linear::LinearMap::new();
unsafe {
let config = FcConfigGetCurrent();
@ -50,7 +47,7 @@ pub impl FontconfigFontListHandle {
while FcPatternGetString(*font, FC_FAMILY, v, &family) == FcResultMatch {
let family_name = str::raw::from_buf(family as *u8);
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);
v += 1;
}
@ -60,7 +57,7 @@ pub impl FontconfigFontListHandle {
return family_map;
}
fn load_variations_for_family(family: @FontFamily) {
fn load_variations_for_family(&self, family: @mut FontFamily) {
debug!("getting variations for %?", family);
let config = FcConfigGetCurrent();
let font_set = FcConfigGetFonts(config, FcSetSystem);

View file

@ -72,8 +72,8 @@ pub struct FreeTypeFontTable {
bogus: ()
}
pub impl FontTableMethods for FreeTypeFontTable {
fn with_buffer(_blk: fn&(*u8, uint)) {
impl FontTableMethods for FreeTypeFontTable {
fn with_buffer(&self, _blk: &fn(*u8, uint)) {
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.
pure fn face_identifier() -> ~str {
pure fn face_identifier(&self) -> ~str {
/* FT_Get_Postscript_Name seems like a better choice here, but it
doesn't give usable results for fontconfig when deserializing. */
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) }
}
pure fn face_name() -> ~str {
pure fn face_name(&self) -> ~str {
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 }
}
pure fn boldness() -> CSSFontWeight {
pure fn boldness(&self) -> CSSFontWeight {
let default_weight = FontWeight400;
if unsafe { (*self.face).style_flags & FT_STYLE_FLAG_BOLD == 0 } {
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, ()> {
match self.source {
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();
let idx = FT_Get_Char_Index(self.face, codepoint as FT_ULong);
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();
let res = FT_Load_Glyph(self.face, glyph as FT_UInt, 0);
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 */
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
}
}
pub impl FreeTypeFontHandle {
priv fn get_face_rec() -> &self/FT_FaceRec {
priv fn get_face_rec(&self) -> &self/FT_FaceRec {
unsafe {
&(*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();

View file

@ -44,16 +44,16 @@ pub impl FreeTypeFontContextHandle {
}
}
pub impl FontContextHandleMethods for FreeTypeFontContextHandle {
impl FontContextHandleMethods for FreeTypeFontContextHandle {
pure fn clone(&const self) -> FreeTypeFontContextHandle {
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);
do path_from_identifier(name).chain |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 impl Add<Au,Au> for Au {
impl Add<Au,Au> for Au {
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) }
}
pub impl Mul<Au,Au> for Au {
impl Mul<Au,Au> for Au {
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) }
}
pub impl Modulo<Au,Au> for Au {
impl Modulo<Au,Au> for Au {
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) }
}
pub impl cmp::Ord for Au {
impl cmp::Ord for Au {
pure fn lt(&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 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 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 pure fn scale_by(factor: float) -> Au {
pub pure fn scale_by(self, factor: float) -> Au {
Au(((*self as float) * factor) as i32)
}

View file

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

View file

@ -17,13 +17,13 @@ use std::arc::{ARC, clone, get};
*/
pub struct ImageHolder {
url: Url,
mut image: Option<ARC<~Image>>,
mut cached_size: Size2D<int>,
local_image_cache: @LocalImageCache,
image: Option<ARC<~Image>>,
cached_size: Size2D<int>,
local_image_cache: @mut LocalImageCache,
}
impl ImageHolder {
static pub fn new(url: Url, local_image_cache: @LocalImageCache) -> ImageHolder {
pub impl ImageHolder {
static pub fn new(url: Url, local_image_cache: @mut LocalImageCache) -> ImageHolder {
debug!("ImageHolder::new() %?", url.to_str());
let holder = ImageHolder {
url: url,
@ -50,12 +50,12 @@ impl ImageHolder {
The intent is that the impure version is used during layout when
dimensions are used for computing layout.
*/
pure fn size() -> Size2D<int> {
pure fn size(&self) -> Size2D<int> {
self.cached_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);
match self.get_image() {
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);
// 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 {
fn with_buffer(blk: fn&(*u8, uint)) {
impl FontTableMethods for QuartzFontTable {
fn with_buffer(blk: &fn(*u8, uint)) {
blk(self.data.bytes(), self.data.len());
}
}
@ -129,7 +129,7 @@ impl FontHandleMethods for QuartzFontHandle {
fn glyph_index(codepoint: char) -> Option<GlyphIndex> {
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 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 {
QuartzFontContextHandle { ctx: self.ctx }
}

View file

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

View file

@ -19,9 +19,9 @@ pub struct RenderLayer {
size: Size2D<uint>
}
type RenderFn = &fn(layer: *RenderLayer,
buffer: LayerBuffer,
return_buffer: Chan<LayerBuffer>);
type RenderFn = &'self fn(layer: *RenderLayer,
buffer: LayerBuffer,
return_buffer: Chan<LayerBuffer>);
/// 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

View file

@ -12,11 +12,11 @@ use util::time::time;
use core::libc::size_t;
use core::libc::types::common::c99::uint16_t;
use core::cell::Cell;
use core::comm::{Chan, Port, SharedChan};
use core::task::SingleThreaded;
use std::arc::ARC;
use std::arc;
use std::cell::Cell;
use std::task_pool::TaskPool;
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| {
ThreadRenderContext {
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),
}
};
@ -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.
priv struct ThreadRenderContext {
thread_index: uint,
font_ctx: @FontContext,
font_ctx: @mut FontContext,
opts: Opts,
}
@ -79,7 +79,7 @@ priv struct Renderer<C> {
}
impl<C: Compositor + Owned> Renderer<C> {
fn start() {
fn start(&self) {
debug!("renderer: beginning rendering 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");
let layer_buffer_set_port = self.layer_buffer_set_port.take();

View file

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

View file

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

View file

@ -11,7 +11,7 @@ use core::to_str::ToStr;
use core::util::replace;
use std::arc::ARC;
use std::net::url::Url;
use std::cell::Cell;
use core::cell::Cell;
pub enum Msg {
/// 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>),
/// For testing
priv OnMsg(fn~(msg: &Msg)),
priv OnMsg(~fn(msg: &Msg)),
/// Clients must wait for a response before shutting down the ResourceTask
pub Exit(Chan<()>)
@ -49,11 +49,11 @@ pub enum ImageResponseMsg {
}
impl ImageResponseMsg {
pure fn clone() -> ImageResponseMsg {
match &self {
&ImageReady(ref img) => ImageReady(unsafe { clone_arc(img) }),
&ImageNotReady => ImageNotReady,
&ImageFailed => ImageFailed
pure fn clone(&self) -> ImageResponseMsg {
match *self {
ImageReady(ref img) => ImageReady(unsafe { clone_arc(img) }),
ImageNotReady => ImageNotReady,
ImageFailed => ImageFailed
}
}
}
@ -98,7 +98,7 @@ pub fn ImageCacheTask_(resource_task: ResourceTask,
let chan_cell = Cell(chan.clone());
do spawn {
ImageCache {
let mut cache = ImageCache {
resource_task: resource_task.clone(),
decoder_factory: decoder_factory_cell.take(),
port: port_cell.take(),
@ -106,7 +106,8 @@ pub fn ImageCacheTask_(resource_task: ResourceTask,
state_map: url_map(),
wait_map: url_map(),
need_exit: None
}.run();
};
cache.run();
}
chan
@ -152,7 +153,7 @@ struct ImageCache {
state_map: UrlMap<ImageState>,
/// List of clients waiting on a WaitForImage response
wait_map: UrlMap<@mut ~[Chan<ImageResponseMsg>]>,
mut need_exit: Option<Chan<()>>,
need_exit: Option<Chan<()>>,
}
enum ImageState {
@ -172,9 +173,9 @@ enum AfterPrefetch {
#[allow(non_implicitly_copyable_typarams)]
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 {
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) {
Some(state) => state,
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);
}
priv fn prefetch(url: Url) {
priv fn prefetch(&self, url: Url) {
match self.get_state(copy url) {
Init => {
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) {
Prefetching(next_step) => {
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) {
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) {
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) {
Some(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) {
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) {
Init => fail!(~"request for image before prefetch"),
@ -448,11 +449,11 @@ impl ImageCache {
trait ImageCacheTaskClient {
fn exit();
fn exit(&self);
}
impl ImageCacheTaskClient for ImageCacheTask {
fn exit() {
fn exit(&self) {
let (response_port, response_chan) = stream();
self.send(Exit(response_chan));
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~(data: &[u8]) -> Option<Image> { load_from_memory(data) }
let foo: ~fn(&[u8]) -> Option<Image> = |data: &[u8]| { load_from_memory(data) };
foo
}
#[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 decoder_factory = fn~() -> ~fn(&[u8]) -> Option<Image> {
let decoder_factory = || {
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
wait_to_decode_port.recv();
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 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::{ WaitForImage, ImageReady, ImageNotReady, ImageFailed};
use util::url::{UrlMap, url_map};
@ -22,16 +22,16 @@ pub fn LocalImageCache(image_cache_task: ImageCacheTask) -> LocalImageCache {
pub struct LocalImageCache {
priv image_cache_task: ImageCacheTask,
priv mut round_number: uint,
priv mut on_image_available: Option<@fn() -> ~fn(ImageResponseMsg)>,
priv state_map: UrlMap<@ImageState>
priv round_number: uint,
priv on_image_available: Option<@fn() -> ~fn(ImageResponseMsg)>,
priv state_map: UrlMap<@mut ImageState>
}
priv struct ImageState {
mut prefetched: bool,
mut decoded: bool,
mut last_request_round: uint,
mut last_response: ImageResponseMsg
prefetched: bool,
decoded: bool,
last_request_round: uint,
last_response: ImageResponseMsg
}
#[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
/// URL in each 'round'. Layout should call this each time it begins
// 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.on_image_available = Some(on_image_available);
}
pub fn prefetch(url: &Url) {
pub fn prefetch(&self, url: &Url) {
let state = self.get_state(url);
if !state.prefetched {
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);
if !state.decoded {
self.image_cache_task.send(Decode(copy *url));
@ -61,7 +61,7 @@ pub impl LocalImageCache {
}
// 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);
// Save the previous round number for comparison
@ -132,11 +132,11 @@ pub impl LocalImageCache {
return port;
}
priv fn get_state(url: &Url) -> @ImageState {
priv fn get_state(&self, url: &Url) -> @mut ImageState {
match self.state_map.find(url) {
Some(state) => state,
None => {
let new_state = @ImageState {
let new_state = @mut ImageState {
prefetched: false,
decoded: false,
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 std::cell::Cell;
use std::net::url;
use std::net::url::{Url, to_str};
use super::{file_loader, http_loader};
@ -76,7 +76,7 @@ pub fn ResourceManager(from_client: Port<ControlMsg>,
impl ResourceManager {
fn start() {
fn start(&self) {
loop {
match self.from_client.recv() {
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) {
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| {
match *scheme_loader {
(ref scheme, ref loader_factory) => {
@ -140,7 +140,7 @@ fn test_bad_scheme() {
#[allow(non_implicitly_copyable_typarams)]
fn should_delegate_to_scheme_loader() {
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(Done(Ok(())));
};

View file

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

View file

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

View file

@ -159,91 +159,91 @@ pure fn MissingGlyphsEntry(glyphCount: uint) -> GlyphEntry {
impl GlyphEntry {
// getter methods
#[inline(always)]
pure fn advance() -> Au {
pure fn advance(&self) -> Au {
//assert self.is_simple();
NumCast::from((self.value & GLYPH_ADVANCE_MASK) >> GLYPH_ADVANCE_SHIFT)
}
pure fn index() -> GlyphIndex {
pure fn index(&self) -> GlyphIndex {
//assert self.is_simple();
self.value & GLYPH_ID_MASK
}
pure fn offset() -> Point2D<Au> {
pure fn offset(&self) -> Point2D<Au> {
//assert self.is_simple();
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)
}
pure fn is_cluster_start() -> bool {
pure fn is_cluster_start(&self) -> bool {
self.has_flag(!FLAG_NOT_CLUSTER_START)
}
// True if original char was normal (U+0020) space. Other chars may
// 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)
}
pure fn char_is_tab() -> bool {
pure fn char_is_tab(&self) -> bool {
!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)
}
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;
break_flag_to_enum(flag)
}
// setter methods
#[inline(always)]
pure fn set_char_is_space() -> GlyphEntry {
pure fn set_char_is_space(&self) -> GlyphEntry {
GlyphEntry(self.value | FLAG_CHAR_IS_SPACE)
}
#[inline(always)]
pure fn set_char_is_tab() -> GlyphEntry {
pure fn set_char_is_tab(&self) -> GlyphEntry {
assert !self.is_simple();
GlyphEntry(self.value | FLAG_CHAR_IS_TAB)
}
#[inline(always)]
pure fn set_char_is_newline() -> GlyphEntry {
pure fn set_char_is_newline(&self) -> GlyphEntry {
assert !self.is_simple();
GlyphEntry(self.value | FLAG_CHAR_IS_NEWLINE)
}
#[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;
GlyphEntry(self.value | flag)
}
// helper methods
/*priv*/ pure fn glyph_count() -> u16 {
/*priv*/ pure fn glyph_count(&self) -> u16 {
assert !self.is_simple();
((self.value & GLYPH_COUNT_MASK) >> GLYPH_COUNT_SHIFT) as u16
}
#[inline(always)]
pure fn is_simple() -> bool {
pure fn is_simple(&self) -> bool {
self.has_flag(FLAG_IS_SIMPLE_GLYPH)
}
#[inline(always)]
/*priv*/ pure fn has_flag(flag: u32) -> bool {
/*priv*/ pure fn has_flag(&self, flag: u32) -> bool {
(self.value & flag) != 0
}
#[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 }
}
}
@ -398,9 +398,9 @@ impl DetailedGlyphStore {
// Thar be dragons here. You have been warned. (Tips accepted.)
let mut unsorted_records : ~[DetailedGlyphRecord] = ~[];
core::util::swap(&mut self.detail_lookup, &mut unsorted_records);
let mut_records : ~[mut DetailedGlyphRecord] = vec::cast_to_mut(unsorted_records);
let mut mut_records : ~[DetailedGlyphRecord] = unsorted_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);
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
// values as they are needed from the GlyphStore, using provided offsets.
enum GlyphInfo {
SimpleGlyphInfo(&GlyphStore, uint),
DetailGlyphInfo(&GlyphStore, uint, u16)
SimpleGlyphInfo(&'self GlyphStore, uint),
DetailGlyphInfo(&'self GlyphStore, uint, u16)
}
impl GlyphInfo {
fn index() -> GlyphIndex {
impl<'self> GlyphInfo<'self> {
fn index(self) -> GlyphIndex {
match self {
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
@ -458,28 +458,28 @@ impl GlyphInfo {
}
#[inline(always)]
fn advance() -> Au {
fn advance(self) -> Au {
match self {
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
}
}
fn offset() -> Option<Point2D<Au>> {
fn offset(self) -> Option<Point2D<Au>> {
match self {
SimpleGlyphInfo(_, _) => None,
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 {
SimpleGlyphInfo(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 {
SimpleGlyphInfo(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;
}
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();
let entry = &self.entry_buffer[i];
match entry.is_simple() {
true => {
let proxy = SimpleGlyphInfo(&self, i);
let proxy = SimpleGlyphInfo(self, i);
cb(i, proxy);
},
false => {
let glyphs = self.detail_store.get_detailed_glyphs_for_entry(i,
entry.glyph_count());
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);
}
}
@ -594,7 +594,7 @@ pub impl GlyphStore {
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() {
error!("iter_glyphs_for_range: range.begin beyond length!");
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| {
if !self.iter_glyphs_for_char_index(i, cb) { break; }
}
}
// 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();
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();
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();
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();
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();
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();
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::{c_uint, c_int, c_void, c_char};
use core::util::ignore;
use dvec::DVec;
//use dvec::DVec;
use std::arc;
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.
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;
let glyph_info_i = ptr::offset(self.glyph_infos, i);
@ -142,7 +142,7 @@ pub impl ShapedGlyphData {
}
pub struct HarfbuzzShaper {
font: @Font,
font: @mut Font,
priv hb_face: *hb_face_t,
priv hb_font: *hb_font_t,
priv hb_funcs: *hb_font_funcs_t,
@ -160,7 +160,7 @@ pub struct 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_font: *hb_font_t = hb_font_create(hb_face);
// 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
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();
hb_buffer_set_direction(hb_buffer, HB_DIRECTION_LTR);
@ -228,7 +228,7 @@ impl ShaperMethods for 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_count = glyph_data.len();
let byte_max = text.len();
@ -403,7 +403,7 @@ pub impl HarfbuzzShaper {
glyphs.add_glyph_for_char_index(char_idx, &data);
} else {
// collect all glyphs to be assigned to the first character.
let datas = DVec();
let mut datas = ~[];
for glyph_span.eachi |glyph_i| {
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.
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
let mut i = covered_byte_span.begin();

View file

@ -6,18 +6,18 @@ Currently, only harfbuzz bindings are implemented.
*/
use gfx_font::Font;
use text::glyph::GlyphStore;
use harfbuzz;
use text::harfbuzz;
pub type Shaper/& = harfbuzz::shaper::HarfbuzzShaper;
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
// typedefs not working well together. It should be removed.
pub impl Shaper {
static pub fn new(font: @Font) -> Shaper {
static pub fn new(font: @mut Font) -> Shaper {
harfbuzz::shaper::HarfbuzzShaper::new(font)
}
}

View file

@ -12,7 +12,7 @@ use std::arc::ARC;
pub struct TextRun {
text: ~str,
font: @Font,
font: @mut Font,
glyphs: GlyphStore,
}
@ -25,7 +25,7 @@ pub struct 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) {
Ok(f) => f,
Err(_) => fail!(fmt!("Font descriptor deserialization failed! desc=%?", self.font))
@ -40,7 +40,7 @@ impl SendableTextRun {
}
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));
TextRun::compute_potential_breaks(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 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> {
static fn new(size: uint) -> Self;
fn insert(key: &K, value: V);
fn find(key: &K) -> Option<V>;
fn find_or_create(key: &K, blk: pure fn&(&K) -> V) -> V;
fn evict_all();
fn insert(&mut self, key: &K, value: V);
fn find(&self, key: &K) -> Option<V>;
fn find_or_create(&mut self, key: &K, blk: &pure fn(&K) -> V) -> V;
fn evict_all(&mut self);
}
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> {
MonoCache { entry: None }
}
fn insert(key: &K, value: V) {
fn insert(&mut self, key: &K, value: V) {
self.entry = Some((copy *key, value));
}
fn find(key: &K) -> Option<V> {
fn find(&self, key: &K) -> Option<V> {
match self.entry {
None => 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) {
None => {
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
};
}
fn evict_all() {
fn evict_all(&mut self) {
self.entry = None;
}
}

View file

@ -27,7 +27,7 @@ pub impl Range {
pure fn begin(&const self) -> uint { self.off }
pure fn length(&const self) -> uint { 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) }
}

View file

@ -28,7 +28,7 @@ pub fn make_url(str_url: ~str, current_url: Option<Url>) -> Url {
} else {
let path = str::split_char(current_url.path, '/');
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
}

View file

@ -5,7 +5,7 @@ pub trait BinarySearchMethods<T: Ord + Eq> {
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> {
match self.binary_search_index(key) {
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 util::task::spawn_listener;
use core::cell::Cell;
use core::comm::{Port, Chan, SharedChan};
use core::pipes::select2i;
use core::either;
@ -33,7 +34,6 @@ use js::rust::{Compartment, Cx};
use jsrt = js::rust::rt;
use newcss::stylesheet::Stylesheet;
use std::arc::{ARC, clone};
use std::cell::Cell;
use std::net::url::Url;
use url_to_str = std::net::url::to_str;
use dom;
@ -82,7 +82,7 @@ pub fn ContentTask(layout_task: LayoutTask,
pub struct Content {
layout_task: LayoutTask,
mut layout_join_port: Option<comm::Port<()>>,
layout_join_port: Option<comm::Port<()>>,
image_cache_task: ImageCacheTask,
control_port: comm::Port<ControlMsg>,
@ -93,17 +93,17 @@ pub struct Content {
jsrt: jsrt,
cx: @Cx,
mut document: Option<@Document>,
mut window: Option<@Window>,
mut doc_url: Option<Url>,
mut window_size: Size2D<uint>,
document: Option<@Document>,
window: Option<@Window>,
doc_url: Option<Url>,
window_size: Size2D<uint>,
resource_task: ResourceTask,
compartment: Option<@mut Compartment>,
// What parts of layout are dirty.
mut damage: Damage,
damage: Damage,
}
pub fn Content(layout_task: LayoutTask,
@ -113,7 +113,7 @@ pub fn Content(layout_task: LayoutTask,
img_cache_task: ImageCacheTask,
event_port: comm::Port<Event>,
event_chan: comm::SharedChan<Event>)
-> @Content {
-> @mut Content {
let jsrt = jsrt();
let cx = jsrt.cx();
@ -125,7 +125,7 @@ pub fn Content(layout_task: LayoutTask,
Err(()) => None
};
let content = @Content {
let content = @mut Content {
layout_task: layout_task,
layout_join_port: None,
image_cache_task: img_cache_task,
@ -153,28 +153,34 @@ pub fn Content(layout_task: LayoutTask,
content
}
pub fn task_from_context(cx: *JSContext) -> *Content {
pub fn task_from_context(cx: *JSContext) -> *mut Content {
unsafe {
cast::reinterpret_cast(&JS_GetContextPrivate(cx))
}
}
#[allow(non_implicitly_copyable_typarams)]
impl Content {
fn start() {
pub impl Content {
fn start(&mut self) {
while self.handle_msg() {
// Go on ...
}
}
fn handle_msg() -> bool {
fn handle_msg(&mut self) -> bool {
match select2i(&self.control_port, &self.event_port) {
either::Left(*) => self.handle_control_msg(self.control_port.recv()),
either::Right(*) => self.handle_event(self.event_port.recv())
either::Left(*) => {
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 {
ParseMsg(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
pending layout request messages).
*/
fn join_layout(&self) {
fn join_layout(&mut self) {
if self.layout_join_port.is_some() {
let join_port = replace(&mut self.layout_join_port, None);
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
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");
// Now, join the layout so that they will see the latest
@ -317,7 +323,7 @@ impl Content {
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.join_layout();
@ -330,7 +336,7 @@ impl Content {
This is the main entry point for receiving and dispatching DOM events.
*/
// TODO: actually perform DOM event dispatch.
fn handle_event(event: Event) -> bool {
fn handle_event(&mut self, event: Event) -> bool {
match event {
ResizeEvent(new_width, new_height, response_chan) => {
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);
}
impl NodeUtil for AbstractNode {
impl<'self> NodeUtil<'self> for AbstractNode {
/**
* Provides the computed style 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 url_from_str = std::net::url::from_str;
use std::cell::Cell;
use core::cell::Cell;
use newcss::stylesheet::Stylesheet;
use newcss::select::SelectCtx;
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 {
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)
}
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() {
Some(parent) => {
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()
}
// 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;
loop {
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()
}
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() {
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() {
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::{PROPERTY_STUB, STRICT_PROPERTY_STUB};
use js::crust::{JS_PropertyStub, JS_StrictPropertyStub, JS_EnumerateStub, JS_ConvertStub, JS_ResolveStub};
use ptr::null;
use libc::c_uint;
use core::ptr::null;
use core::libc::c_uint;
use dom::bindings::utils::{DOMString, domstring_to_jsval, rust_box, squirrel_away, str};
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) => {
do node.as_mut_element |elem| {
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?"),

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,
RESOLVE_STUB};
use js::glue::bindgen::*;
use ptr::null;
use core::ptr::null;
use core::cast;
use content::content_task::{Content, task_from_context};
pub enum DOMString {

View file

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

View file

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

View file

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

View file

@ -1,8 +1,9 @@
use core::comm::{Port, Chan};
use content::content_task::{ControlMsg, Timer, ExitMsg};
use js::jsapi::JSVal;
use dvec::DVec;
use util::task::spawn_listener;
use core::comm::{Port, Chan};
use core::dvec::DVec;
use std::timer;
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
#[allow(non_implicitly_copyable_typarams)]
impl Window {
pub impl Window {
fn alert(s: &str) {
// Right now, just print to the console
io::println(fmt!("ALERT: %s", s));

View file

@ -8,12 +8,12 @@ use resource::resource_task::ResourceTask;
use resource::resource_task;
use util::task::spawn_listener;
use core::cell::Cell;
use core::comm::{Port, Chan};
use gfx::compositor::Compositor;
use gfx::opts::Opts;
use gfx::render_task::RenderTask;
use gfx::render_task;
use std::cell::Cell;
use std::net::url::Url;
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 core::cell::Cell;
use core::comm::{Port, Chan};
use core::pipes;
use core::str;
use newcss::stylesheet::Stylesheet;
use newcss::util::DataStream;
use std::cell::Cell;
use std::net::url::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 util::task::{spawn_listener, spawn_conversation};
use core::cell::Cell;
use core::comm::{Chan, Port, SharedChan};
use core::str::eq_slice;
use gfx::util::url::make_url;
use hubbub::hubbub::Attribute;
use hubbub::hubbub;
use std::cell::Cell;
use std::net::url::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 = unsafe { Node::as_abstract_node(root) };
debug!("created new node");
let parser = hubbub::Parser("UTF-8", false);
let mut parser = hubbub::Parser("UTF-8", false);
debug!("created parser");
parser.set_document_node(root.to_hubbub_node());
parser.enable_scripting(true);

View file

@ -17,7 +17,7 @@ use gfx::display_list::DisplayList;
use gfx::geometry::Au;
pub struct BlockFlowData {
mut box: Option<@RenderBox>
box: Option<@mut RenderBox>
}
pub fn BlockFlowData() -> BlockFlowData {
@ -28,12 +28,12 @@ pub fn BlockFlowData() -> BlockFlowData {
pub trait BlockLayout {
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 assign_widths_block(@self, ctx: &LayoutContext);
fn assign_height_block(@self, ctx: &LayoutContext);
fn build_display_list_block(@self,
fn bubble_widths_block(@mut self, ctx: &LayoutContext);
fn assign_widths_block(@mut self, ctx: &LayoutContext);
fn assign_height_block(@mut self, ctx: &LayoutContext);
fn build_display_list_block(@mut self,
a: &DisplayListBuilder,
b: &Rect<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.
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 {
BlockFlow(*) => {
let mut box = self.block().box;
box.iter(cb);
let box = self.block().box;
for box.each |b| { cb(b); }
},
RootFlow(*) => {
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))
}
@ -73,7 +73,7 @@ impl BlockLayout for FlowContext {
/* TODO: floats */
/* TODO: absolute contexts */
/* TODO: inline-blocks */
fn bubble_widths_block(@self, ctx: &LayoutContext) {
fn bubble_widths_block(@mut self, ctx: &LayoutContext) {
assert self.starts_block_flow();
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
all child (block) contexts. */
fn assign_widths_block(@self, _ctx: &LayoutContext) {
fn assign_widths_block(@mut self, _ctx: &LayoutContext) {
assert self.starts_block_flow();
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();
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>) {
assert self.starts_block_flow();

View file

@ -3,7 +3,7 @@
use css::node_style::StyledNode;
use dom::node::AbstractNode;
use layout::context::LayoutContext;
use layout::debug::BoxedDebugMethods;
use layout::debug::BoxedMutDebugMethods;
use layout::display_list_builder::DisplayListBuilder;
use layout::flow::FlowContext;
use layout::text::TextBoxData;
@ -80,15 +80,15 @@ pub struct RenderBoxData {
node : AbstractNode,
/* reference to containing flow context, which this box
participates in */
ctx : @FlowContext,
ctx : @mut FlowContext,
/* position of this box relative to owning flow */
mut position : Rect<Au>,
position : Rect<Au>,
font_size : Length,
/* TODO (Issue #87): debug only */
mut id: int
id: int
}
enum RenderBoxType {
pub enum RenderBoxType {
RenderBox_Generic,
RenderBox_Image,
RenderBox_Text,
@ -102,31 +102,35 @@ pub enum RenderBox {
}
pub enum SplitBoxResult {
CannotSplit(@RenderBox),
CannotSplit(@mut RenderBox),
// in general, when splitting the left or right side can
// be zero length, due to leading/trailing trimmable whitespace
SplitDidFit(Option<@RenderBox>, Option<@RenderBox>),
SplitDidNotFit(Option<@RenderBox>, Option<@RenderBox>)
SplitDidFit(Option<@mut RenderBox>, Option<@mut 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 {
node : node,
mut ctx : ctx,
mut position : Au::zero_rect(),
ctx : ctx,
position : Au::zero_rect(),
font_size: Px(0.0),
id : id
}
}
impl RenderBox {
pure fn d(&self) -> &self/RenderBoxData {
match *self {
GenericBox(ref d) => d,
ImageBox(ref d, _) => d,
TextBox(ref d, _) => d,
UnscannedTextBox(ref d, _) => d,
pure fn d(&mut self) -> &self/mut RenderBoxData {
unsafe {
//Rust #5074 - we can't take mutable references to the
// data that needs to be returned right now.
match self {
&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 {
@ -150,8 +154,8 @@ impl RenderBox {
}
}
fn can_merge_with_box(@self, other: @RenderBox) -> bool {
assert !managed::ptr_eq(self, other);
fn can_merge_with_box(@mut self, other: @mut RenderBox) -> bool {
assert !managed::mut_ptr_eq(self, other);
match (self, other) {
(@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 {
@GenericBox(*) => CannotSplit(self),
@ImageBox(*) => CannotSplit(self),
@ -238,31 +242,31 @@ impl RenderBox {
* may cause glyphs to be allocated. For now, it's impure because of
* holder.get_image()
*/
fn get_min_width(_ctx: &LayoutContext) -> Au {
match &self {
fn get_min_width(&mut self, _ctx: &LayoutContext) -> Au {
match *self {
// TODO: this should account for min/pref widths of the
// box element in isolation. That includes
// border/margin/padding but not child widths. The block
// FlowContext will combine the width of this element and
// that of its children to arrive at the context width.
&GenericBox(*) => Au(0),
GenericBox(*) => Au(0),
// TODO: consult CSS 'width', margin, border.
// TODO: If image isn't available, consult 'width'.
&ImageBox(_, ref 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),
&UnscannedTextBox(*) => fail!(~"Shouldn't see unscanned boxes here.")
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),
UnscannedTextBox(*) => fail!(~"Shouldn't see unscanned boxes here.")
}
}
fn get_pref_width(_ctx: &LayoutContext) -> Au {
match &self {
fn get_pref_width(&mut self, _ctx: &LayoutContext) -> Au {
match self {
// TODO: this should account for min/pref widths of the
// box element in isolation. That includes
// border/margin/padding but not child widths. The block
// FlowContext will combine the width of this element and
// that of its children to arrive at the context width.
&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.
@ -306,12 +310,13 @@ impl RenderBox {
/* The box formed by the content edge, as defined in CSS 2.1 Section 8.1.
Coordinates are relative to the owning flow. */
pure fn content_box() -> Rect<Au> {
match &self {
&ImageBox(_, ref i) => {
pure fn content_box(&mut self) -> Rect<Au> {
let origin = {copy self.d().position.origin};
match self {
&ImageBox(_, ref mut i) => {
let size = i.size();
Rect {
origin: copy self.d().position.origin,
origin: origin,
size: Size2D(Au::from_px(size.width),
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.
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
self.content_box()
}
/* The box fromed by the margin edge, as defined in CSS 2.1 Section 8.1.
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
self.content_box()
}
fn style(&self) -> CompleteStyle/&self {
let d: &self/RenderBoxData = self.d();
fn style(&mut self) -> CompleteStyle/&self {
let d: &self/mut RenderBoxData = self.d();
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;
while !node.is_element() {
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
* `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>) {
let box_bounds = self.d().position;
@ -401,9 +406,10 @@ impl RenderBox {
self.add_bgcolor_to_list(list, &abs_box_bounds);
match self {
@UnscannedTextBox(*) => fail!(~"Shouldn't see unscanned boxes here."),
@TextBox(_,data) => {
let m = &mut *self;
match m {
&UnscannedTextBox(*) => fail!(~"Shouldn't see unscanned boxes here."),
&TextBox(_,data) => {
do list.borrow_mut |list| {
let nearest_ancestor_element = self.nearest_ancestor_element();
let color = nearest_ancestor_element.style().color().to_gfx_color();
@ -430,8 +436,9 @@ impl RenderBox {
}
},
// TODO: items for background, border, outline
@GenericBox(_) => {}
@ImageBox(_, ref i) => {
&GenericBox(_) => {}
&ImageBox(_, ref mut i) => {
//let i: &mut ImageHolder = unsafe { cast::transmute(i) }; // Rust #5074
match i.get_image() {
Some(image) => {
do list.borrow_mut |list| {
@ -451,7 +458,7 @@ impl RenderBox {
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;
// 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 }
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.
fn font_style(@self) -> FontStyle {
fn font_style(@mut self) -> FontStyle {
do self.with_style_of_nearest_element |my_style| {
let font_families = do my_style.font_family().map |family| {
match *family {
@ -564,20 +571,20 @@ impl RenderBox {
}
// 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| {
my_style.text_align()
}
}
}
impl BoxedDebugMethods for RenderBox {
pure fn dump(@self) {
impl BoxedMutDebugMethods for RenderBox {
pure fn dump(@mut self) {
self.dump_indent(0u);
}
/* 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 = ~"";
for uint::range(0u, indent) |_i| {
s += ~" ";
@ -587,7 +594,7 @@ impl BoxedDebugMethods for RenderBox {
debug!("%s", s);
}
pure fn debug_str(@self) -> ~str {
pure fn debug_str(@mut self) -> ~str {
let repr = match self {
@GenericBox(*) => ~"GenericBox",
@ImageBox(*) => ~"ImageBox",
@ -602,7 +609,7 @@ impl BoxedDebugMethods for RenderBox {
// Other methods
impl RenderBox {
/// 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;
while !node.is_element() {
match node.parent_node() {

View file

@ -7,9 +7,9 @@ use dom;
use layout::block::BlockFlowData;
use layout::box::*;
use layout::context::LayoutContext;
use layout::debug::{BoxedDebugMethods, DebugMethods};
use layout::debug::{BoxedMutDebugMethods, DebugMethods};
use layout::flow::*;
use layout::inline::InlineFlowData;
use layout::inline::{InlineFlowData, InlineLayout};
use layout::root::RootFlowData;
use util::tree;
@ -20,9 +20,9 @@ use newcss::values::{CSSDisplay, CSSDisplayBlock, CSSDisplayInline, CSSDisplayIn
use newcss::values::{CSSDisplayNone, Inherit, Specified};
pub struct LayoutTreeBuilder {
mut root_flow: Option<@FlowContext>,
mut next_bid: int,
mut next_cid: int
root_flow: Option<@mut FlowContext>,
next_bid: int,
next_cid: int
}
pub impl LayoutTreeBuilder {
@ -38,7 +38,7 @@ pub impl LayoutTreeBuilder {
// helper object for building the initial box list and making the
// mapping between DOM nodes and boxes.
struct BoxGenerator {
flow: @FlowContext,
flow: @mut FlowContext,
range_stack: DVec<uint>,
}
@ -80,7 +80,7 @@ priv fn simulate_UA_display_rules(node: AbstractNode) -> CSSDisplay {
}
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()); }
BoxGenerator {
flow: flow,
@ -97,11 +97,11 @@ impl BoxGenerator {
fn make_inline_spacer_for_node_side(_: &LayoutContext,
_: AbstractNode,
_: InlineSpacerSide)
-> Option<@RenderBox> {
-> Option<@mut RenderBox> {
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());
// first, determine the box type, based on node characteristics
@ -123,12 +123,14 @@ impl BoxGenerator {
// if a leaf, make a box.
if node.is_leaf() {
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, maybe make a spacer for "left" margin, border, padding
do self.make_inline_spacer_for_node_side(ctx, node, LogicalBefore).iter
|spacer: &@RenderBox| {
self.flow.inline().boxes.push(*spacer);
for self.make_inline_spacer_for_node_side(ctx, node, LogicalBefore).each
|spacer: &@mut RenderBox| {
let boxes = &mut self.flow.inline().boxes;
boxes.push(*spacer);
}
}
// 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());
match self.flow {
@ -164,8 +166,9 @@ impl BoxGenerator {
if self.inline_spacers_needed_for_node(node) {
// if this non-leaf box generates extra horizontal
// spacing, add a SpacerBox for it.
do self.make_inline_spacer_for_node_side(ctx, node, LogicalAfter).iter |spacer: &@RenderBox| {
self.flow.inline().boxes.push(*spacer);
for self.make_inline_spacer_for_node_side(ctx, node, LogicalAfter).each |spacer: &@mut RenderBox| {
let boxes = &mut self.flow.inline().boxes;
boxes.push(*spacer);
}
}
let mut node_range: Range = Range::new(self.range_stack.pop(), 0);
@ -173,7 +176,8 @@ impl BoxGenerator {
assert node_range.length() > 0;
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(*) => {
assert self.range_stack.len() == 0;
@ -184,12 +188,12 @@ impl BoxGenerator {
}
struct BuilderContext {
default_collector: @BoxGenerator,
priv mut inline_collector: Option<@BoxGenerator>
default_collector: @mut BoxGenerator,
priv inline_collector: Option<@mut BoxGenerator>
}
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()); }
BuilderContext {
default_collector: collector,
@ -202,24 +206,24 @@ impl BuilderContext {
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%?",
self.default_collector.flow.d().id, child.d().id);
tree::add_child(&FlowTree, self.default_collector.flow, child);
}
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);
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");
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.attach_child_flow(new_flow);
@ -227,22 +231,23 @@ impl BuilderContext {
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 {
Some(collector) => BuilderContext::new(collector),
None => self.make_inline_collector(builder)
}
}
priv fn clear_inline_collector() {
priv fn clear_inline_collector(&mut self) {
self.inline_collector = None;
}
// 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'
// should just not generate any flows or boxes.
fn containing_context_for_node(node: AbstractNode,
builder: &LayoutTreeBuilder)
fn containing_context_for_node(&mut self,
node: AbstractNode,
builder: &mut LayoutTreeBuilder)
-> Option<BuilderContext> {
// TODO: remove this once UA styles work
// 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 */
fn next_box_id(&self) -> int { self.next_bid += 1; self.next_bid }
fn next_flow_id(&self) -> int { self.next_cid += 1; self.next_cid }
fn next_box_id(&mut self) -> int { self.next_bid += 1; self.next_bid }
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,
/// and recurses on its children.
fn construct_recursively(&self,
fn construct_recursively(&mut self,
layout_ctx: &LayoutContext,
cur_node: AbstractNode,
parent_ctx: &BuilderContext) {
parent_ctx: &mut BuilderContext) {
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,
None => { return; } // no context because of display: none. Stop building subtree.
};
@ -298,7 +303,7 @@ impl LayoutTreeBuilder {
// recurse on child nodes.
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);
@ -308,8 +313,9 @@ impl LayoutTreeBuilder {
// boxes that correspond to child_flow.node. These boxes may
// eventually be elided or split, but the mapping between
// nodes and FlowContexts should not change during layout.
for tree::each_child(&FlowTree, &this_ctx.default_collector.flow) |child_flow: &@FlowContext| {
do (copy child_flow.d().node).iter |node| {
let flow = &mut this_ctx.default_collector.flow;
for tree::each_child(&FlowTree, flow) |child_flow: &@mut FlowContext| {
for (copy child_flow.d().node).each |node| {
assert node.has_layout_data();
node.layout_data().flow = Some(*child_flow);
}
@ -331,7 +337,8 @@ impl LayoutTreeBuilder {
let mut found_child_inline = 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 {
InlineFlow(*) | InlineBlockFlow(*) => found_child_inline = true,
BlockFlow(*) => found_child_block = true,
@ -348,9 +355,9 @@ impl LayoutTreeBuilder {
// of its RenderBox or FlowContext children, and possibly keep alive other junk
let parent_flow = parent_ctx.default_collector.flow;
// 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() {
let boxes = &first_flow.inline().boxes;
let boxes = &mut first_flow.inline().boxes;
if boxes.len() == 1 && boxes[0].is_whitespace_only() {
debug!("LayoutTreeBuilder: pruning whitespace-only first child flow f%d from parent f%d",
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() {
let boxes = &last_flow.inline().boxes;
let boxes = &mut last_flow.inline().boxes;
if boxes.len() == 1 && boxes.last().is_whitespace_only() {
debug!("LayoutTreeBuilder: pruning whitespace-only last child flow f%d from parent f%d",
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.
fail!(~"TODO: handle case where an inline is split by a block")
}
/** entry point for box creation. Should only be
called on root DOM element. */
fn construct_trees(&self, layout_ctx: &LayoutContext, root: AbstractNode)
-> Result<@FlowContext, ()> {
fn construct_trees(&mut self, layout_ctx: &LayoutContext, root: AbstractNode)
-> Result<@mut FlowContext, ()> {
let new_flow = self.make_flow(Flow_Root);
let new_generator = @BoxGenerator::new(new_flow);
let root_ctx = BuilderContext::new(new_generator);
let new_generator = @mut BoxGenerator::new(new_flow);
let mut root_ctx = BuilderContext::new(new_generator);
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)
}
fn make_flow(&self, ty: FlowContextType) -> @FlowContext {
fn make_flow(&mut self, ty: FlowContextType) -> @mut FlowContext {
let data = FlowData(self.next_flow_id());
let ret = match ty {
Flow_Absolute => @AbsoluteFlow(data),
Flow_Block => @BlockFlow(data, BlockFlowData()),
Flow_Float => @FloatFlow(data),
Flow_InlineBlock => @InlineBlockFlow(data),
Flow_Inline => @InlineFlow(data, InlineFlowData()),
Flow_Root => @RootFlow(data, RootFlowData()),
Flow_Table => @TableFlow(data)
Flow_Absolute => @mut AbsoluteFlow(data),
Flow_Block => @mut BlockFlow(data, BlockFlowData()),
Flow_Float => @mut FloatFlow(data),
Flow_InlineBlock => @mut InlineBlockFlow(data),
Flow_Inline => @mut InlineFlow(data, InlineFlowData()),
Flow_Root => @mut RootFlow(data, RootFlowData()),
Flow_Table => @mut TableFlow(data)
};
debug!("LayoutTreeBuilder: created flow: %s", ret.debug_str());
ret
@ -410,12 +417,12 @@ impl LayoutTreeBuilder {
disambiguate between different methods here instead of inlining, since each
case has very different complexity
*/
fn make_box(&self,
fn make_box(&mut self,
layout_ctx: &LayoutContext,
ty: RenderBoxType,
node: AbstractNode,
ctx: @FlowContext)
-> @RenderBox {
ctx: @mut FlowContext)
-> @mut RenderBox {
let ret = match ty {
RenderBox_Generic => self.make_generic_box(layout_ctx, node, ctx),
RenderBox_Text => self.make_text_box(layout_ctx, node, ctx),
@ -425,19 +432,19 @@ impl LayoutTreeBuilder {
ret
}
fn make_generic_box(&self,
fn make_generic_box(&mut self,
_: &LayoutContext,
node: AbstractNode,
ctx: @FlowContext)
-> @RenderBox {
@GenericBox(RenderBoxData(copy node, ctx, self.next_box_id()))
ctx: @mut FlowContext)
-> @mut RenderBox {
@mut GenericBox(RenderBoxData(copy node, ctx, self.next_box_id()))
}
fn make_image_box(&self,
fn make_image_box(&mut self,
layout_ctx: &LayoutContext,
node: AbstractNode,
ctx: @FlowContext)
-> @RenderBox {
ctx: @mut FlowContext)
-> @mut RenderBox {
if !node.is_image_element() {
fail!(~"WAT error: why couldn't we make an image box?");
}
@ -446,7 +453,7 @@ impl LayoutTreeBuilder {
if image_element.image.is_some() {
let holder = ImageHolder::new(copy *image_element.image.get_ref(),
layout_ctx.image_cache);
@ImageBox(RenderBoxData(node, ctx, self.next_box_id()), holder)
@mut ImageBox(RenderBoxData(node, ctx, self.next_box_id()), holder)
} else {
info!("Tried to make image box, but couldn't find image. Made generic box instead.");
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,
node: AbstractNode,
ctx: @FlowContext)
-> @RenderBox {
ctx: @mut FlowContext)
-> @mut RenderBox {
if !node.is_text() {
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?
do node.with_imm_text |text_node| {
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. */
pub struct LayoutContext {
font_ctx: @FontContext,
image_cache: @LocalImageCache,
font_ctx: @mut FontContext,
image_cache: @mut LocalImageCache,
doc_url: Url,
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 {
pure fn dump(@self);
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
pattern we'll need once we support DL-based hit testing &c. */
pub struct DisplayListBuilder {
ctx: &LayoutContext,
ctx: &'self LayoutContext,
}
pub trait FlowDisplayListBuilderMethods {
fn build_display_list(@self, a: &DisplayListBuilder, b: &Rect<Au>, c: &Mut<DisplayList>);
fn build_display_list_for_child(@self,
fn build_display_list(@mut self, a: &DisplayListBuilder, b: &Rect<Au>, c: &Mut<DisplayList>);
fn build_display_list_for_child(@mut self,
a: &DisplayListBuilder,
b: @FlowContext,
b: @mut FlowContext,
c: &Rect<Au>,
d: &Point2D<Au>,
e: &Mut<DisplayList>);
}
impl FlowDisplayListBuilderMethods for FlowContext {
fn build_display_list(@self,
fn build_display_list(@mut self,
builder: &DisplayListBuilder,
dirty: &Rect<Au>,
list: &Mut<DisplayList>) {
@ -51,9 +51,9 @@ impl FlowDisplayListBuilderMethods for FlowContext {
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,
child_flow: @FlowContext,
child_flow: @mut FlowContext,
dirty: &Rect<Au>, offset: &Point2D<Au>,
list: &Mut<DisplayList>) {

View file

@ -3,7 +3,7 @@ use dom::node::AbstractNode;
use layout::block::{BlockFlowData, BlockLayout};
use layout::box::RenderBox;
use layout::context::LayoutContext;
use layout::debug::BoxedDebugMethods;
use layout::debug::BoxedMutDebugMethods;
use layout::display_list_builder::DisplayListBuilder;
use layout::inline::{InlineFlowData, InlineLayout, NodeRange};
use layout::root::{RootFlowData, RootLayout};
@ -54,7 +54,7 @@ pub enum FlowContext {
TableFlow(FlowData)
}
enum FlowContextType {
pub enum FlowContextType {
Flow_Absolute,
Flow_Block,
Flow_Float,
@ -66,22 +66,22 @@ enum FlowContextType {
/* A particular kind of layout context. It manages the positioning of
render boxes within the context. */
struct FlowData {
mut node: Option<AbstractNode>,
pub struct FlowData {
node: Option<AbstractNode>,
/* reference to parent, children flow contexts */
tree: tree::Tree<@FlowContext>,
tree: tree::Tree<@mut FlowContext>,
/* TODO (Issue #87): debug only */
mut id: int,
id: int,
/* layout computations */
// TODO: min/pref and position are used during disjoint phases of
// layout; maybe combine into a single enum to save space.
mut min_width: Au,
mut pref_width: Au,
mut position: Rect<Au>,
min_width: Au,
pref_width: Au,
position: Rect<Au>,
}
fn FlowData(id: int) -> FlowData {
pub fn FlowData(id: int) -> FlowData {
FlowData {
node: None,
tree: tree::empty(),
@ -93,41 +93,43 @@ fn FlowData(id: int) -> FlowData {
}
}
impl FlowContext {
pure fn d(&self) -> &self/FlowData {
pub impl FlowContext {
pure fn d(&mut self) -> &self/mut FlowData {
unsafe {
match *self {
AbsoluteFlow(ref d) => d,
BlockFlow(ref d, _) => d,
FloatFlow(ref d) => d,
InlineBlockFlow(ref d) => d,
InlineFlow(ref d, _) => d,
RootFlow(ref d, _) => d,
TableFlow(ref d) => d
AbsoluteFlow(ref d) => cast::transmute(d),
BlockFlow(ref d, _) => cast::transmute(d),
FloatFlow(ref d) => cast::transmute(d),
InlineBlockFlow(ref d) => cast::transmute(d),
InlineFlow(ref d, _) => cast::transmute(d),
RootFlow(ref d, _) => cast::transmute(d),
TableFlow(ref d) => cast::transmute(d)
}
}
}
pure fn inline(&self) -> &self/InlineFlowData {
match *self {
InlineFlow(_, ref i) => i,
pure fn inline(&mut self) -> &self/mut InlineFlowData {
match self {
&InlineFlow(_, ref i) => unsafe { cast::transmute(i) },
_ => fail!(fmt!("Tried to access inline data of non-inline: f%d", self.d().id))
}
}
pure fn block(&self) -> &self/BlockFlowData {
match *self {
BlockFlow(_, ref b) => b,
pure fn block(&mut self) -> &self/mut BlockFlowData {
match self {
&BlockFlow(_, ref mut b) => unsafe { cast::transmute(b) },
_ => fail!(fmt!("Tried to access block data of non-block: f%d", self.d().id))
}
}
pure fn root(&self) -> &self/RootFlowData {
match *self {
RootFlow(_, ref r) => r,
pure fn root(&mut self) -> &self/mut RootFlowData {
match self {
&RootFlow(_, ref r) => unsafe { cast::transmute(r) },
_ => 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 {
@BlockFlow(*) => self.bubble_widths_block(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 {
@BlockFlow(*) => self.assign_widths_block(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 {
@BlockFlow(*) => self.assign_height_block(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>) {
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
pure fn foldl_all_boxes<B: Copy>(seed: B,
cb: pure fn&(a: B,@RenderBox) -> B) -> B {
pure fn foldl_all_boxes<B: Copy>(&mut self,
seed: B,
cb: &pure fn(a: B,@mut RenderBox) -> B) -> B {
match self {
RootFlow(*) => option::map_default(&self.root().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) },
&RootFlow(*) => option::map_default(&self.root().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) },
_ => 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,
cb: pure fn&(a: B,@RenderBox) -> B)
cb: &pure fn(a: B,@mut RenderBox) -> B)
-> B {
do self.foldl_all_boxes(seed) |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 {
RootFlow(*) => do self.root().box.iter |box| { cb(*box); },
BlockFlow(*) => do self.block().box.iter |box| { cb(*box); },
InlineFlow(*) => for self.inline().boxes.each |box| { cb(*box); },
&RootFlow(*) => for self.root().box.each |box| { cb(*box); },
&BlockFlow(*) => for self.block().box.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))
}
}
pure fn iter_boxes_for_node<T>(node: AbstractNode,
cb: pure fn&(@RenderBox) -> T) {
pure fn iter_boxes_for_node<T>(&mut self,
node: AbstractNode,
cb: &pure fn(@mut RenderBox) -> T) {
do self.iter_all_boxes |box| {
if box.d().node == node { cb(box); }
}
@ -208,39 +213,41 @@ impl FlowContext {
pub enum FlowTree { 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) )
}
}
impl tree::ReadMethods<@FlowContext> for FlowTree {
fn with_tree_fields<R>(box: &@FlowContext, f: fn(&tree::Tree<@FlowContext>) -> R) -> R {
f(&box.d().tree)
impl tree::ReadMethods<@mut FlowContext> for FlowTree {
fn with_tree_fields<R>(box: &@mut FlowContext, f: fn(&mut tree::Tree<@mut FlowContext>) -> R) -> R {
let tree = &mut box.d().tree;
f(tree)
}
}
impl FlowTree {
fn add_child(parent: @FlowContext, child: @FlowContext) {
fn add_child(parent: @mut FlowContext, child: @mut FlowContext) {
tree::add_child(&self, parent, child)
}
}
impl tree::WriteMethods<@FlowContext> for FlowTree {
pure fn tree_eq(a: &@FlowContext, b: &@FlowContext) -> bool { core::managed::ptr_eq(*a, *b) }
impl tree::WriteMethods<@mut FlowContext> for FlowTree {
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 {
f(&box.d().tree)
fn with_tree_fields<R>(box: &@mut FlowContext, f: fn(&mut tree::Tree<@mut FlowContext>) -> R) -> R {
let tree = &mut box.d().tree;
f(tree)
}
}
impl BoxedDebugMethods for FlowContext {
pure fn dump(@self) {
impl BoxedMutDebugMethods for FlowContext {
pure fn dump(@mut self) {
self.dump_indent(0u);
}
/** 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 = ~"|";
for uint::range(0u, indent) |_i| {
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 {
InlineFlow(*) => {
let mut s = self.inline().boxes.foldl(~"InlineFlow(children=", |s, box| {

View file

@ -2,21 +2,26 @@ use core;
use dom::node::AbstractNode;
use layout::box::*;
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::text::{TextBoxData, UnscannedMethods};
use layout::text::{TextBoxData, UnscannedMethods, adapt_textbox_with_range};
use util::tree;
use core::dlist::DList;
use core::dvec::DVec;
use geom::{Point2D, Rect, Size2D};
use gfx::display_list::DisplayList;
use gfx::font::FontStyle;
use gfx::geometry::Au;
use gfx::image::holder;
use gfx::text::text_run::TextRun;
use gfx::text::util::*;
use gfx::util::range::Range;
use newcss::values::{CSSTextAlignCenter, CSSTextAlignJustify, CSSTextAlignLeft, CSSTextAlignRight};
use newcss::units::{BoxAuto, BoxLength, Px};
use std::arc;
use core::mutable::Mut;
/*
Lineboxes are represented as offsets into the child list, rather than
@ -55,7 +60,7 @@ struct ElementMapping {
priv entries: DVec<NodeRange>,
}
impl ElementMapping {
pub impl ElementMapping {
static pure fn new() -> ElementMapping {
ElementMapping { entries: DVec() }
}
@ -64,19 +69,19 @@ impl ElementMapping {
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) }
}
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) }
}
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) }
}
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: ---");
for old_boxes.eachi |i, box| {
debug!("%u --> %s", i, box.debug_str());
@ -104,7 +109,7 @@ impl ElementMapping {
};
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
let mut entries_k = 0;
@ -161,10 +166,11 @@ 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;
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());
let out_boxes = DVec();
@ -187,7 +193,7 @@ priv impl TextRunScanner {
}
// 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 right_i > 0 && right_i < boxes.len();
assert left_i != right_i;
@ -213,10 +219,10 @@ priv impl TextRunScanner {
// recursively borrow or swap the flow's dvec of boxes. When all
// boxes are appended, the caller swaps the flow's box list.
fn flush_clump_to_list(&mut self,
ctx: &LayoutContext,
flow: @FlowContext,
in_boxes: &[@RenderBox],
out_boxes: &DVec<@RenderBox>) {
ctx: &mut LayoutContext,
flow: @mut FlowContext,
in_boxes: &[@mut RenderBox],
out_boxes: &DVec<@mut RenderBox>) {
assert self.clump.length() > 0;
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 run = @fontgroup.create_textrun(transformed_text);
debug!("TextRunScanner: pushing single text box in range: %?", self.clump);
let new_box = layout::text::adapt_textbox_with_range(old_box.d(),
run,
&const Range::new(0, run.char_len()));
let new_box = adapt_textbox_with_range(old_box.d(),
run,
&const Range::new(0, run.char_len()));
out_boxes.push(new_box);
},
(false, true) => {
@ -294,7 +300,7 @@ priv impl TextRunScanner {
in_boxes[i].debug_str());
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);
}
}
@ -313,7 +319,8 @@ priv impl TextRunScanner {
debug!("------------------");
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!("--------------------");
@ -323,19 +330,19 @@ priv impl TextRunScanner {
}
struct PendingLine {
mut range: Range,
mut width: Au
range: Range,
width: Au
}
struct LineboxScanner {
flow: @FlowContext,
new_boxes: DVec<@RenderBox>,
work_list: @mut DList<@RenderBox>,
flow: @mut FlowContext,
new_boxes: DVec<@mut RenderBox>,
work_list: @mut DList<@mut RenderBox>,
pending_line: PendingLine,
line_spans: DVec<Range>,
}
fn LineboxScanner(inline: @FlowContext) -> LineboxScanner {
fn LineboxScanner(inline: @mut FlowContext) -> LineboxScanner {
assert inline.starts_inline_flow();
LineboxScanner {
@ -363,7 +370,7 @@ impl LineboxScanner {
pub fn scan_for_lines(&mut self, ctx: &LayoutContext) {
self.reset_scanner();
let boxes = &self.flow.inline().boxes;
let boxes = &mut self.flow.inline().boxes;
let mut i = 0u;
loop {
@ -397,7 +404,9 @@ impl LineboxScanner {
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();
}
@ -406,11 +415,13 @@ impl LineboxScanner {
self.line_spans.len(), self.flow.d().id);
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| {
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.
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 in_box_width = in_box.d().position.size.width;
let line_is_empty: bool = self.pending_line.range.length() == 0;
@ -552,7 +563,7 @@ impl LineboxScanner {
}
// 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());
if self.pending_line.range.length() == 0 {
@ -568,7 +579,7 @@ impl LineboxScanner {
pub struct InlineFlowData {
// A vec of all inline render boxes. Several boxes may
// correspond to one Node/Element.
boxes: DVec<@RenderBox>,
boxes: DVec<@mut RenderBox>,
// vec of ranges into boxes that represents line positions.
// these ranges are disjoint, and are the result of inline layout.
lines: DVec<Range>,
@ -589,17 +600,17 @@ pub fn InlineFlowData() -> InlineFlowData {
pub trait InlineLayout {
pure fn starts_inline_flow() -> bool;
fn bubble_widths_inline(@self, ctx: &LayoutContext);
fn assign_widths_inline(@self, ctx: &LayoutContext);
fn assign_height_inline(@self, ctx: &LayoutContext);
fn build_display_list_inline(@self, a: &DisplayListBuilder, b: &Rect<Au>, c: &Point2D<Au>,
fn bubble_widths_inline(@mut self, ctx: &mut LayoutContext);
fn assign_widths_inline(@mut self, ctx: &mut LayoutContext);
fn assign_height_inline(@mut self, ctx: &mut LayoutContext);
fn build_display_list_inline(@mut self, a: &DisplayListBuilder, b: &Rect<Au>, c: &Point2D<Au>,
d: &Mut<DisplayList>);
}
impl InlineLayout for FlowContext {
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();
let mut scanner = TextRunScanner::new();
@ -608,7 +619,8 @@ impl InlineLayout for FlowContext {
let mut min_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());
min_width = Au::max(min_width, box.get_min_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
contexts and boxes. When called on this context, the context has
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();
// initialize (content) box widths, if they haven't been
// already. This could be combined with LineboxScanner's walk
// over the box list, and/or put into RenderBox.
for self.inline().boxes.each |box| {
box.d().position.size.width = match *box {
@ImageBox(_, ref img) => {
Au::from_px(img.get_size().get_or_default(Size2D(0,0)).width)
let boxes = &mut self.inline().boxes;
for boxes.each |&box| {
let box2 = &mut *box;
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
},
// 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))
};
} // for boxes.each |box|
@ -653,7 +668,7 @@ impl InlineLayout for FlowContext {
// '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
// containing block's style to determine minimum linebox height.
// 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 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);
// coords relative to left baseline
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| {
let cur_box = boxes[box_i];
let mut cur_box = boxes[box_i];
// compute box height.
cur_box.d().position.size.height = match cur_box {
@ -731,7 +747,7 @@ impl InlineLayout for FlowContext {
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>) {
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
debug!("FlowContext[%d]: building display list for %u inline boxes",
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)
}

View file

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

View file

@ -13,7 +13,7 @@ use util::tree;
use core::mutable::Mut;
pub struct RootFlowData {
mut box: Option<@RenderBox>
box: Option<@mut RenderBox>
}
pub fn RootFlowData() -> RootFlowData {
@ -25,10 +25,10 @@ pub fn RootFlowData() -> RootFlowData {
pub trait RootLayout {
pure fn starts_root_flow() -> bool;
fn bubble_widths_root(@self, ctx: &LayoutContext);
fn assign_widths_root(@self, ctx: &LayoutContext);
fn assign_height_root(@self, ctx: &LayoutContext);
fn build_display_list_root(@self, a: &DisplayListBuilder, b: &Rect<Au>,
fn bubble_widths_root(@mut self, ctx: &LayoutContext);
fn assign_widths_root(@mut self, ctx: &LayoutContext);
fn assign_height_root(@mut self, ctx: &LayoutContext);
fn build_display_list_root(@mut self, a: &DisplayListBuilder, b: &Rect<Au>,
c: &Point2D<Au>, d: &Mut<DisplayList>);
}
@ -41,12 +41,12 @@ impl RootLayout for FlowContext {
}
/* 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();
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();
self.d().position.origin = Au::zero_point();
@ -55,7 +55,7 @@ impl RootLayout for FlowContext {
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();
// 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>) {
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,
range: &const Range) -> @RenderBox {
pub fn adapt_textbox_with_range(box_data: &mut RenderBoxData, run: @TextRun,
range: &const Range) -> @mut RenderBox {
assert range.begin() < run.char_len();
assert range.end() <= run.char_len();
assert range.length() > 0;
debug!("Creating textbox with span: (strlen=%u, off=%u, len=%u) of textrun: %s",
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 metrics = run.metrics_for_range(range);
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 {
pure fn raw_text(&self) -> ~str;
pure fn raw_text(&mut self) -> ~str;
}
impl UnscannedMethods for RenderBox {
pure fn raw_text(&self) -> ~str {
pure fn raw_text(&mut self) -> ~str {
match self {
&UnscannedTextBox(_, ref s) => copy *s,
_ => fail!(~"unsupported operation: box.raw_text() on non-unscanned text box.")

View file

@ -1,18 +1,18 @@
use layout::flow::{FlowContext, FlowTree};
/** Trait for running tree-based traversals over layout contexts */
trait FlowContextTraversals {
fn traverse_preorder(preorder_cb: &fn(@FlowContext));
fn traverse_postorder(postorder_cb: &fn(@FlowContext));
pub trait FlowContextTraversals {
fn traverse_preorder(preorder_cb: &fn(@mut FlowContext));
fn traverse_postorder(postorder_cb: &fn(@mut FlowContext));
}
impl FlowContextTraversals for @FlowContext {
fn traverse_preorder(preorder_cb: &fn(@FlowContext)) {
impl FlowContextTraversals for @mut FlowContext {
fn traverse_preorder(preorder_cb: &fn(@mut FlowContext)) {
preorder_cb(self);
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 }
postorder_cb(self);
}

View file

@ -15,12 +15,13 @@ use gfx::compositor::{Compositor, LayerBuffer, LayerBufferSet};
use gfx::opts::Opts;
use gfx::util::time;
use layers::layers::ImageLayer;
use std::cell::Cell;
use core::cell::Cell;
use std::cmp::FuzzyEq;
use glut::glut;
use layers;
use sharegl;
use sharegl::ShareGlContext;
use sharegl::base::ShareContext;
pub struct OSMain {
chan: SharedChan<Msg>
@ -81,13 +82,13 @@ struct AzureDrawTargetImageData {
}
impl layers::layers::ImageData for AzureDrawTargetImageData {
fn size() -> Size2D<uint> { self.size }
fn stride() -> uint { self.data_source_surface.get_size().width as uint }
fn format() -> layers::layers::Format {
fn size(&self) -> Size2D<uint> { self.size }
fn stride(&self) -> uint { self.data_source_surface.get_size().width as uint }
fn format(&self) -> layers::layers::Format {
// FIXME: This is not always correct. We should query the Azure draw target for the format.
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| {
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 root_layer = @layers::layers::ContainerLayer();
let root_layer = @mut layers::layers::ContainerLayer();
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,
layers::layers::RGB24Format,
~[]);
let image = @layers::layers::Image::new(image_data as @layers::layers::ImageData);
let image_layer = @layers::layers::ImageLayer(image);
//XXXjdm How can we obtain a @mut @ImageData without transmute?
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;
image_layer.common.set_transform(original_layer_transform.scale(800.0, 600.0, 1.0));
root_layer.add_child(layers::layers::ImageLayerKind(image_layer));
@ -141,8 +144,8 @@ fn mainloop(mode: Mode,
identity());
let done = @mut false;
let resize_rate_limiter = @ResizeRateLimiter(dom_event_chan);
let check_for_messages = fn@() {
let resize_rate_limiter = @mut ResizeRateLimiter(dom_event_chan);
let check_for_messages: @fn() = || {
// Periodically check if content responded to our last resize event
resize_rate_limiter.check_resize_response();
@ -169,20 +172,21 @@ fn mainloop(mode: Mode,
debug!("osmain: compositing buffer rect %?", &buffer.rect);
let image_data = @AzureDrawTargetImageData {
let image_data = @mut AzureDrawTargetImageData {
draw_target: buffer.draw_target.clone(),
data_source_surface: buffer.draw_target.snapshot().get_data_surface(),
size: Size2D(width, height)
};
let image = @layers::layers::Image::new(
image_data as @layers::layers::ImageData);
//XXXjdm How can we extract a @mut @ImageData without transmute?
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.
let image_layer;
current_layer_child = match current_layer_child {
None => {
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));
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_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);
};
let composite: fn@() = || {
let composite: @fn() = || {
//#debug("osmain: drawing to screen");
do time::time(~"compositing") {
@ -276,20 +280,20 @@ Implementation to allow the osmain channel to be used as a graphics
compositor for the renderer
*/
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))
}
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))
}
}
struct SurfaceSet {
mut front: Surface,
mut back: Surface,
front: 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?
assert surfaces.front.have;
// Ok then take it
@ -316,7 +320,7 @@ fn lend_surface(surfaces: &SurfaceSet, receiver: comm::Chan<LayerBufferSet>) {
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);
// We have room for a return
assert surfaces.front.have;
@ -334,7 +338,7 @@ fn SurfaceSet(backend: BackendType) -> SurfaceSet {
struct Surface {
layer_buffer_set: LayerBufferSet,
mut have: bool,
have: bool,
}
fn Surface(backend: BackendType) -> Surface {
@ -348,7 +352,7 @@ fn Surface(backend: BackendType) -> Surface {
}
/// 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();
do task::task().sched_mode(task::PlatformThread).spawn {
let (po, ch) = comm::stream();

View file

@ -11,9 +11,9 @@ pub struct ResizeRateLimiter {
/// The channel we send resize events on
/* priv */ dom_event_chan: comm::SharedChan<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
/* 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 {
@ -24,8 +24,8 @@ pub fn ResizeRateLimiter(dom_event_chan: comm::SharedChan<Event>) -> ResizeRateL
}
}
impl ResizeRateLimiter {
fn window_resized(width: uint, height: uint) {
pub impl ResizeRateLimiter {
fn window_resized(&mut self, width: uint, height: uint) {
match self.last_response_port {
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 {
Some((copy width, copy height)) => {
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();
self.dom_event_chan.send(ResizeEvent(width, height, chan));
self.last_response_port = Some(port);

View file

@ -1,8 +1,8 @@
use core::cell::Cell;
use core::comm::{Chan, Port};
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();
do task::spawn {
let (po, ch) = comm::stream();
@ -12,7 +12,7 @@ pub fn spawn_listener<A: Owned>(f: fn~(Port<A>)) -> Chan<A> {
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 to_parent = Cell(to_parent);
let to_child = do spawn_listener |from_parent| {

View file

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

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