mirror of
https://github.com/servo/servo.git
synced 2025-08-06 14:10:11 +01:00
Language changes.
This commit is contained in:
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
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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 }
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use io::WriterUtil;
|
||||
use core::io::WriterUtil;
|
||||
use surface;
|
||||
|
||||
fn encode(writer: io::Writer, surface: &surface::ImageSurface) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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]),
|
||||
|
|
|
@ -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 }
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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(())));
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -7,7 +7,7 @@ pub enum format {
|
|||
}
|
||||
|
||||
impl format {
|
||||
fn bpp() -> uint {
|
||||
fn bpp(self) -> uint {
|
||||
match self {
|
||||
fo_rgba_8888 => 32u
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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) }
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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?"),
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)),
|
||||
|
|
|
@ -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
|
||||
//
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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>;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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>
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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>) {
|
||||
|
||||
|
|
|
@ -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| {
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
@ -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") {
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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.")
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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| {
|
||||
|
|
|
@ -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
|
Loading…
Add table
Add a link
Reference in a new issue