mirror of
https://github.com/servo/servo.git
synced 2025-08-07 14:35:33 +01:00
Update for language changes
This commit is contained in:
parent
6a92e84105
commit
2483797f48
48 changed files with 281 additions and 336 deletions
2
src/rust
2
src/rust
|
@ -1 +1 @@
|
||||||
Subproject commit 6366e74fe3bb07762a4c314a83af21cd1daacc98
|
Subproject commit a782efc4f16fed52f1f82af5869bfb5285bbc3f4
|
|
@ -1 +1 @@
|
||||||
Subproject commit 11a7fe3f073612df8d7245a831bdd5ebb572099d
|
Subproject commit 28dbde9f94091de97035246155b5bff08f768fdc
|
|
@ -1 +1 @@
|
||||||
Subproject commit 349ccf644408358debab0cde6da8c574a936411e
|
Subproject commit c90b66a7ec392a231ce26c717a7e11de219f4bd8
|
|
@ -1 +1 @@
|
||||||
Subproject commit 488df0c7cd29cc58002eb9ccf3ae864de08c6e50
|
Subproject commit 1152347b9fc8ed51a4079071a84015ae5c6b75b4
|
|
@ -1 +1 @@
|
||||||
Subproject commit f53aaa1cdc5b210d5390be71b92e7c8cc51ac8d2
|
Subproject commit bc86ccb773758b3e2ad7f689b67f77165048b9e6
|
|
@ -1 +1 @@
|
||||||
Subproject commit b8382613e38459101a7b42b9a1fa5dbb40c8644c
|
Subproject commit d3f318c2f7de0ac0c676abc0965591ecc3329a60
|
|
@ -1 +1 @@
|
||||||
Subproject commit bb4952656c180cb263aa8c437b1691670a76fe66
|
Subproject commit 0d2d600ecafdccda56c54f9f693d83592b2ec4d4
|
|
@ -1 +1 @@
|
||||||
Subproject commit b67e3ad2ae08e0cd001586895a6a693b3353e35b
|
Subproject commit 29e5fa637965d7ce2c1b9b1347d8fe6054a71243
|
|
@ -1 +1 @@
|
||||||
Subproject commit 6e1ef6cf8bd81b3587a124acd8e601b935f96536
|
Subproject commit 916004c3f4bc30515085fe4bb888338805a06aa9
|
|
@ -1 +1 @@
|
||||||
Subproject commit fce9c5b323bd47f94682cb344afebadd2e2c3a45
|
Subproject commit 90612c9e26dc024429212b79e50d99a19c3476c1
|
|
@ -1 +1 @@
|
||||||
Subproject commit aa3af27f6ea1f08539004bdb957978bb2b15ef29
|
Subproject commit 3bd2b9e7194eb39efc036a4a982027b56b1717e1
|
|
@ -1 +1 @@
|
||||||
Subproject commit 4d62a3f9ac1b8ac1c4298a274b476914ded8333a
|
Subproject commit 020deaffff282f36d8b1be8a98ee0e68f4a2b13b
|
|
@ -1 +1 @@
|
||||||
Subproject commit 474d25966ead7efe73bfa26cbdc3d09c54b7b941
|
Subproject commit 584299c9d2c7a48bb31bbb8a64a1d20d99083796
|
|
@ -1 +1 @@
|
||||||
Subproject commit abd987990ba5faf23137d46c642dc1fdc3606791
|
Subproject commit f060d17c2e738f0136a3a1a57eb6363eddf9ca78
|
|
@ -1 +1 @@
|
||||||
Subproject commit 2ebaccbd8519cb11576a812a6ba5f0340fa8706f
|
Subproject commit 0e50f2459cbcefd516c5bfe25552821f1a2d5991
|
|
@ -1 +1 @@
|
||||||
Subproject commit 6cf88b9dc0f5c223b7219fd52b177d9756108984
|
Subproject commit 8d512d5944c11bba56182970548a67ebbcdafc21
|
|
@ -1 +1 @@
|
||||||
Subproject commit 1713d537a8f9cc88ddb8b587e16720b059f9c8f8
|
Subproject commit 5be46dce95aad3e0dc2773045bf3d163da51e41d
|
|
@ -46,6 +46,7 @@ impl DisplayItem {
|
||||||
match self {
|
match self {
|
||||||
&SolidColor(_, color) => ctx.draw_solid_color(&self.d().bounds, color),
|
&SolidColor(_, color) => ctx.draw_solid_color(&self.d().bounds, color),
|
||||||
&Text(_, ref run, ref range, color) => {
|
&Text(_, ref run, ref range, color) => {
|
||||||
|
debug!("drawing text at %?", self.d().bounds);
|
||||||
let new_run = @run.deserialize(ctx.font_ctx);
|
let new_run = @run.deserialize(ctx.font_ctx);
|
||||||
let font = new_run.font;
|
let font = new_run.font;
|
||||||
let origin = self.d().bounds.origin;
|
let origin = self.d().bounds.origin;
|
||||||
|
@ -76,12 +77,12 @@ impl DisplayItem {
|
||||||
run: ~SendableTextRun,
|
run: ~SendableTextRun,
|
||||||
range: Range,
|
range: Range,
|
||||||
color: Color) -> DisplayItem {
|
color: Color) -> DisplayItem {
|
||||||
Text(DisplayItemData::new(bounds), move run, move range, color)
|
Text(DisplayItemData::new(bounds), run, range, color)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ARC should be cloned into ImageData, but Images are not sendable
|
// ARC should be cloned into ImageData, but Images are not sendable
|
||||||
static pure fn new_Image(bounds: &Rect<Au>, image: ARC<~Image>) -> DisplayItem {
|
static pure fn new_Image(bounds: &Rect<Au>, image: ARC<~Image>) -> DisplayItem {
|
||||||
Image(DisplayItemData::new(bounds), move image)
|
Image(DisplayItemData::new(bounds), image)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -98,7 +99,7 @@ pub impl DisplayList {
|
||||||
fn append_item(&mut self, item: ~DisplayItem) {
|
fn append_item(&mut self, item: ~DisplayItem) {
|
||||||
// FIXME(Issue #150): crashes
|
// FIXME(Issue #150): crashes
|
||||||
//debug!("Adding display item %u: %?", self.len(), item);
|
//debug!("Adding display item %u: %?", self.len(), item);
|
||||||
self.list.push(move item);
|
self.list.push(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw_into_context(ctx: &RenderContext) {
|
fn draw_into_context(ctx: &RenderContext) {
|
||||||
|
|
|
@ -53,13 +53,19 @@ pub trait FontHandleMethods {
|
||||||
|
|
||||||
pub impl FontHandle {
|
pub impl FontHandle {
|
||||||
#[cfg(target_os = "macos")]
|
#[cfg(target_os = "macos")]
|
||||||
static pub fn new_from_buffer(fctx: &native::FontContextHandle, buf: ~[u8], style: &SpecifiedFontStyle) -> Result<FontHandle, ()> {
|
static pub fn new_from_buffer(fctx: &native::FontContextHandle,
|
||||||
quartz::font::QuartzFontHandle::new_from_buffer(fctx, move buf, style)
|
buf: ~[u8],
|
||||||
|
style: &SpecifiedFontStyle)
|
||||||
|
-> Result<FontHandle, ()> {
|
||||||
|
quartz::font::QuartzFontHandle::new_from_buffer(fctx, buf, style)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
static pub fn new_from_buffer(fctx: &native::FontContextHandle, buf: ~[u8], style: &SpecifiedFontStyle) -> Result<FontHandle, ()> {
|
static pub fn new_from_buffer(fctx: &native::FontContextHandle,
|
||||||
freetype_impl::font::FreeTypeFontHandle::new_from_buffer(fctx, @move buf, style)
|
buf: ~[u8],
|
||||||
|
style: &SpecifiedFontStyle)
|
||||||
|
-> Result<FontHandle, ()> {
|
||||||
|
freetype_impl::font::FreeTypeFontHandle::new_from_buffer(fctx, @buf, style)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,7 +78,7 @@ trait FontTableTagConversions {
|
||||||
pub pure fn tag_to_str() -> ~str;
|
pub pure fn tag_to_str() -> ~str;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FontTableTag : FontTableTagConversions {
|
impl FontTableTagConversions for FontTableTag {
|
||||||
pub pure fn tag_to_str() -> ~str {
|
pub pure fn tag_to_str() -> ~str {
|
||||||
unsafe {
|
unsafe {
|
||||||
let reversed = str::raw::from_buf_len(cast::transmute(&self), 4);
|
let reversed = str::raw::from_buf_len(cast::transmute(&self), 4);
|
||||||
|
@ -106,6 +112,7 @@ pub struct FontMetrics {
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(Issue #200): use enum from CSS bindings for 'font-weight'
|
// TODO(Issue #200): use enum from CSS bindings for 'font-weight'
|
||||||
|
#[deriving_eq]
|
||||||
pub enum CSSFontWeight {
|
pub enum CSSFontWeight {
|
||||||
FontWeight100,
|
FontWeight100,
|
||||||
FontWeight200,
|
FontWeight200,
|
||||||
|
@ -117,10 +124,6 @@ pub enum CSSFontWeight {
|
||||||
FontWeight800,
|
FontWeight800,
|
||||||
FontWeight900,
|
FontWeight900,
|
||||||
}
|
}
|
||||||
pub impl CSSFontWeight : cmp::Eq {
|
|
||||||
pure fn eq(&self, other: &CSSFontWeight) -> bool { (*self as uint) == (*other as uint) }
|
|
||||||
pure fn ne(&self, other: &CSSFontWeight) -> bool { !(*self).eq(other) }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub impl CSSFontWeight {
|
pub impl CSSFontWeight {
|
||||||
pub pure fn is_bold() -> bool {
|
pub pure fn is_bold() -> bool {
|
||||||
|
@ -137,6 +140,7 @@ pub impl CSSFontWeight {
|
||||||
// the instance's properties.
|
// the instance's properties.
|
||||||
//
|
//
|
||||||
// For now, the cases are differentiated with a typedef
|
// For now, the cases are differentiated with a typedef
|
||||||
|
#[deriving_eq]
|
||||||
pub struct FontStyle {
|
pub struct FontStyle {
|
||||||
pt_size: float,
|
pt_size: float,
|
||||||
weight: CSSFontWeight,
|
weight: CSSFontWeight,
|
||||||
|
@ -146,20 +150,6 @@ pub struct FontStyle {
|
||||||
// TODO(Issue #198): font-stretch, text-decoration, font-variant, size-adjust
|
// TODO(Issue #198): font-stretch, text-decoration, font-variant, size-adjust
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(Issue #181): use deriving for trivial cmp::Eq implementations
|
|
||||||
pub impl FontStyle : cmp::Eq {
|
|
||||||
pure fn eq(&self, other: &FontStyle) -> bool {
|
|
||||||
use std::cmp::FuzzyEq;
|
|
||||||
|
|
||||||
self.pt_size.fuzzy_eq(&other.pt_size) &&
|
|
||||||
self.weight == other.weight &&
|
|
||||||
self.italic == other.italic &&
|
|
||||||
self.oblique == other.oblique &&
|
|
||||||
self.families == other.families
|
|
||||||
}
|
|
||||||
pure fn ne(&self, other: &FontStyle) -> bool { !(*self).eq(other) }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub type SpecifiedFontStyle = FontStyle;
|
pub type SpecifiedFontStyle = FontStyle;
|
||||||
pub type UsedFontStyle = FontStyle;
|
pub type UsedFontStyle = FontStyle;
|
||||||
|
|
||||||
|
@ -175,48 +165,28 @@ struct ResolvedFont {
|
||||||
// It's used to swizzle/unswizzle gfx::Font instances when
|
// It's used to swizzle/unswizzle gfx::Font instances when
|
||||||
// communicating across tasks, such as the display list between layout
|
// communicating across tasks, such as the display list between layout
|
||||||
// and render tasks.
|
// and render tasks.
|
||||||
|
#[deriving_eq]
|
||||||
pub struct FontDescriptor {
|
pub struct FontDescriptor {
|
||||||
style: UsedFontStyle,
|
style: UsedFontStyle,
|
||||||
selector: FontSelector,
|
selector: FontSelector,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// TODO(Issue #181): use deriving for trivial cmp::Eq implementations
|
|
||||||
pub impl FontDescriptor : cmp::Eq {
|
|
||||||
pure fn eq(&self, other: &FontDescriptor) -> bool {
|
|
||||||
self.style == other.style &&
|
|
||||||
self.selector == other.selector
|
|
||||||
}
|
|
||||||
pure fn ne(&self, other: &FontDescriptor) -> bool { !(*self).eq(other) }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub impl FontDescriptor {
|
pub impl FontDescriptor {
|
||||||
static pure fn new(style: UsedFontStyle, selector: FontSelector) -> FontDescriptor {
|
static pure fn new(style: UsedFontStyle, selector: FontSelector) -> FontDescriptor {
|
||||||
FontDescriptor {
|
FontDescriptor {
|
||||||
style: move style,
|
style: style,
|
||||||
selector: move selector,
|
selector: selector,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// A FontSelector is a platform-specific strategy for serializing face names.
|
// A FontSelector is a platform-specific strategy for serializing face names.
|
||||||
|
#[deriving_eq]
|
||||||
pub enum FontSelector {
|
pub enum FontSelector {
|
||||||
SelectorPlatformIdentifier(~str),
|
SelectorPlatformIdentifier(~str),
|
||||||
SelectorStubDummy, // aka, use Josephin Sans
|
SelectorStubDummy, // aka, use Josephin Sans
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(Issue #181): use deriving for trivial cmp::Eq implementations
|
|
||||||
pub impl FontSelector : cmp::Eq {
|
|
||||||
pure fn eq(&self, other: &FontSelector) -> bool {
|
|
||||||
match (self, other) {
|
|
||||||
(&SelectorPlatformIdentifier(ref a), &SelectorPlatformIdentifier(ref b)) => a == b,
|
|
||||||
(&SelectorStubDummy, &SelectorStubDummy) => true,
|
|
||||||
_ => false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pure fn ne(&self, other: &FontSelector) -> bool { !(*self).eq(other) }
|
|
||||||
}
|
|
||||||
|
|
||||||
// This struct is the result of mapping a specified FontStyle into the
|
// This struct is the result of mapping a specified FontStyle into the
|
||||||
// available fonts on the system. It contains an ordered list of font
|
// available fonts on the system. It contains an ordered list of font
|
||||||
// instances to be used in case the prior font cannot be used for
|
// instances to be used in case the prior font cannot be used for
|
||||||
|
@ -237,7 +207,7 @@ pub impl FontGroup {
|
||||||
FontGroup {
|
FontGroup {
|
||||||
families: families,
|
families: families,
|
||||||
style: copy *style,
|
style: copy *style,
|
||||||
fonts: move fonts,
|
fonts: fonts,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -245,7 +215,7 @@ pub impl FontGroup {
|
||||||
assert self.fonts.len() > 0;
|
assert self.fonts.len() > 0;
|
||||||
|
|
||||||
// TODO(Issue #177): Actually fall back through the FontGroup when a font is unsuitable.
|
// TODO(Issue #177): Actually fall back through the FontGroup when a font is unsuitable.
|
||||||
return TextRun::new(self.fonts[0], move text);
|
return TextRun::new(self.fonts[0], text);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -273,12 +243,14 @@ pub struct Font {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub impl Font {
|
pub impl Font {
|
||||||
static fn new_from_buffer(ctx: &FontContext, buffer: ~[u8],
|
static fn new_from_buffer(ctx: &FontContext,
|
||||||
style: &SpecifiedFontStyle, backend: BackendType) -> Result<@Font, ()> {
|
buffer: ~[u8],
|
||||||
|
style: &SpecifiedFontStyle,
|
||||||
let handle = FontHandle::new_from_buffer(&ctx.handle, move buffer, style);
|
backend: BackendType)
|
||||||
|
-> Result<@Font, ()> {
|
||||||
|
let handle = FontHandle::new_from_buffer(&ctx.handle, buffer, style);
|
||||||
let handle = if handle.is_ok() {
|
let handle = if handle.is_ok() {
|
||||||
result::unwrap(move handle)
|
result::unwrap(handle)
|
||||||
} else {
|
} else {
|
||||||
return Err(handle.get_err());
|
return Err(handle.get_err());
|
||||||
};
|
};
|
||||||
|
@ -287,11 +259,11 @@ pub impl Font {
|
||||||
// TODO(Issue #179): convert between specified and used font style here?
|
// TODO(Issue #179): convert between specified and used font style here?
|
||||||
|
|
||||||
return Ok(@Font {
|
return Ok(@Font {
|
||||||
handle : move handle,
|
handle: handle,
|
||||||
azure_font: None,
|
azure_font: None,
|
||||||
shaper: None,
|
shaper: None,
|
||||||
style: copy *style,
|
style: copy *style,
|
||||||
metrics: move metrics,
|
metrics: metrics,
|
||||||
backend: backend,
|
backend: backend,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -301,11 +273,11 @@ pub impl Font {
|
||||||
let metrics = handle.get_metrics();
|
let metrics = handle.get_metrics();
|
||||||
|
|
||||||
@Font {
|
@Font {
|
||||||
handle : move handle,
|
handle: handle,
|
||||||
azure_font: None,
|
azure_font: None,
|
||||||
shaper: None,
|
shaper: None,
|
||||||
style: copy *style,
|
style: copy *style,
|
||||||
metrics: move metrics,
|
metrics: metrics,
|
||||||
backend: backend,
|
backend: backend,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -315,11 +287,11 @@ pub impl Font {
|
||||||
|
|
||||||
// TODO(Issue #179): convert between specified and used font style here?
|
// TODO(Issue #179): convert between specified and used font style here?
|
||||||
let styled_handle = match handle.clone_with_style(&fctx.handle, style) {
|
let styled_handle = match handle.clone_with_style(&fctx.handle, style) {
|
||||||
Ok(move result) => move result,
|
Ok(result) => result,
|
||||||
Err(()) => return Err(())
|
Err(()) => return Err(())
|
||||||
};
|
};
|
||||||
|
|
||||||
return Ok(Font::new_from_adopted_handle(fctx, move styled_handle, style, backend));
|
return Ok(Font::new_from_adopted_handle(fctx, styled_handle, style, backend));
|
||||||
}
|
}
|
||||||
|
|
||||||
priv fn get_shaper(@self) -> @Shaper {
|
priv fn get_shaper(@self) -> @Shaper {
|
||||||
|
@ -342,7 +314,7 @@ pub impl Font {
|
||||||
status, tag.tag_to_str(),
|
status, tag.tag_to_str(),
|
||||||
self.handle.family_name(), self.handle.face_name());
|
self.handle.family_name(), self.handle.face_name());
|
||||||
|
|
||||||
return move result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: this should return a borrowed pointer, but I can't figure
|
// TODO: this should return a borrowed pointer, but I can't figure
|
||||||
|
@ -356,7 +328,7 @@ pub impl Font {
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut scaled_font = self.create_azure_font();
|
let mut scaled_font = self.create_azure_font();
|
||||||
self.azure_font = Some(move scaled_font);
|
self.azure_font = Some(scaled_font);
|
||||||
// try again.
|
// try again.
|
||||||
return self.get_azure_font();
|
return self.get_azure_font();
|
||||||
}
|
}
|
||||||
|
@ -418,13 +390,13 @@ pub impl Font {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
origin = Point2D(origin.x + glyph_advance, origin.y);
|
origin = Point2D(origin.x + glyph_advance, origin.y);
|
||||||
azglyphs.push(move azglyph)
|
azglyphs.push(azglyph)
|
||||||
};
|
};
|
||||||
|
|
||||||
let azglyph_buf_len = azglyphs.len();
|
let azglyph_buf_len = azglyphs.len();
|
||||||
if azglyph_buf_len == 0 { return; } // Otherwise the Quartz backend will assert.
|
if azglyph_buf_len == 0 { return; } // Otherwise the Quartz backend will assert.
|
||||||
|
|
||||||
let azglyph_buf = dvec::unwrap(move azglyphs);
|
let azglyph_buf = dvec::unwrap(azglyphs);
|
||||||
let glyphbuf = unsafe {
|
let glyphbuf = unsafe {
|
||||||
struct__AzGlyphBuffer {
|
struct__AzGlyphBuffer {
|
||||||
mGlyphs: vec::raw::to_ptr(azglyph_buf),
|
mGlyphs: vec::raw::to_ptr(azglyph_buf),
|
||||||
|
@ -457,7 +429,7 @@ pub impl Font {
|
||||||
|
|
||||||
RunMetrics {
|
RunMetrics {
|
||||||
advance_width: advance,
|
advance_width: advance,
|
||||||
bounding_box: move bounds,
|
bounding_box: bounds,
|
||||||
ascent: self.metrics.ascent,
|
ascent: self.metrics.ascent,
|
||||||
descent: self.metrics.descent,
|
descent: self.metrics.descent,
|
||||||
}
|
}
|
||||||
|
@ -526,8 +498,8 @@ fn should_get_glyph_advance_stress() {
|
||||||
|
|
||||||
for iter::repeat(100) {
|
for iter::repeat(100) {
|
||||||
let (chan, port) = pipes::stream();
|
let (chan, port) = pipes::stream();
|
||||||
ports += [@move port];
|
ports += [@port];
|
||||||
do task::spawn |move chan| {
|
do task::spawn {
|
||||||
let fctx = @FontContext();
|
let fctx = @FontContext();
|
||||||
let matcher = @FontMatcher(fctx);
|
let matcher = @FontMatcher(fctx);
|
||||||
let _font = matcher.get_test_font();
|
let _font = matcher.get_test_font();
|
||||||
|
|
|
@ -86,11 +86,12 @@ pub impl FontContext {
|
||||||
|
|
||||||
FontContext {
|
FontContext {
|
||||||
// TODO(Rust #3902): remove extraneous type parameters once they are inferred correctly.
|
// TODO(Rust #3902): remove extraneous type parameters once they are inferred correctly.
|
||||||
instance_cache: Cache::new::<FontDescriptor,@Font,MonoCache<FontDescriptor,@Font>>(10),
|
instance_cache:
|
||||||
font_list: move font_list,
|
Cache::new::<FontDescriptor,@Font,MonoCache<FontDescriptor,@Font>>(10),
|
||||||
handle: move handle,
|
font_list: font_list,
|
||||||
|
handle: handle,
|
||||||
backend: backend,
|
backend: backend,
|
||||||
generic_fonts: move generic_fonts,
|
generic_fonts: generic_fonts,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -123,8 +124,8 @@ pub impl FontContext {
|
||||||
let family = family.to_str();
|
let family = family.to_str();
|
||||||
debug!("(transform family) searching for `%s`", family);
|
debug!("(transform family) searching for `%s`", family);
|
||||||
match self.generic_fonts.find(&family) {
|
match self.generic_fonts.find(&family) {
|
||||||
None => move family,
|
None => family,
|
||||||
Some(move mapped_family) => copy *mapped_family
|
Some(mapped_family) => copy *mapped_family
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -174,7 +175,7 @@ pub impl FontContext {
|
||||||
|
|
||||||
debug!("(create font group) --- finished ---");
|
debug!("(create font group) --- finished ---");
|
||||||
|
|
||||||
@FontGroup::new(style.families.to_managed(), &used_style, dvec::unwrap(move fonts))
|
@FontGroup::new(style.families.to_managed(), &used_style, dvec::unwrap(fonts))
|
||||||
}
|
}
|
||||||
|
|
||||||
priv fn create_font_instance(desc: &FontDescriptor) -> Result<@Font, ()> {
|
priv fn create_font_instance(desc: &FontDescriptor) -> Result<@Font, ()> {
|
||||||
|
@ -186,11 +187,8 @@ pub impl FontContext {
|
||||||
&SelectorPlatformIdentifier(ref identifier) => {
|
&SelectorPlatformIdentifier(ref identifier) => {
|
||||||
let result_handle = self.handle.create_font_from_identifier(copy *identifier,
|
let result_handle = self.handle.create_font_from_identifier(copy *identifier,
|
||||||
copy desc.style);
|
copy desc.style);
|
||||||
result::chain(move result_handle, |handle| {
|
result::chain(result_handle, |handle| {
|
||||||
Ok(Font::new_from_adopted_handle(&self,
|
Ok(Font::new_from_adopted_handle(&self, handle, &desc.style, self.backend))
|
||||||
move handle,
|
|
||||||
&desc.style,
|
|
||||||
self.backend))
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -46,11 +46,11 @@ pub impl FontList {
|
||||||
static fn new(fctx: &native::FontContextHandle) -> FontList {
|
static fn new(fctx: &native::FontContextHandle) -> FontList {
|
||||||
let handle = result::unwrap(FontListHandle::new(fctx));
|
let handle = result::unwrap(FontListHandle::new(fctx));
|
||||||
let list = FontList {
|
let list = FontList {
|
||||||
handle: move handle,
|
handle: handle,
|
||||||
family_map: linear::LinearMap::new(),
|
family_map: linear::LinearMap::new(),
|
||||||
};
|
};
|
||||||
list.refresh(fctx);
|
list.refresh(fctx);
|
||||||
return move list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
priv fn refresh(_fctx: &native::FontContextHandle) {
|
priv fn refresh(_fctx: &native::FontContextHandle) {
|
||||||
|
@ -156,7 +156,7 @@ pub impl FontEntry {
|
||||||
face_name: handle.face_name(),
|
face_name: handle.face_name(),
|
||||||
weight: handle.boldness(),
|
weight: handle.boldness(),
|
||||||
italic: handle.is_italic(),
|
italic: handle.is_italic(),
|
||||||
handle: move handle
|
handle: handle
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -109,7 +109,7 @@ pub impl FontconfigFontListHandle {
|
||||||
let font_handle = font_handle.unwrap();
|
let font_handle = font_handle.unwrap();
|
||||||
|
|
||||||
debug!("Creating new FontEntry for face: %s", font_handle.face_name());
|
debug!("Creating new FontEntry for face: %s", font_handle.face_name());
|
||||||
let entry = @FontEntry::new(family, move font_handle);
|
let entry = @FontEntry::new(family, font_handle);
|
||||||
family.entries.push(entry);
|
family.entries.push(entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -158,4 +158,4 @@ pub fn path_from_identifier(name: ~str) -> Result<~str, ()> {
|
||||||
}
|
}
|
||||||
Ok(str::raw::from_buf(file as *u8))
|
Ok(str::raw::from_buf(file as *u8))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -72,9 +72,9 @@ pub struct FreeTypeFontTable {
|
||||||
bogus: ()
|
bogus: ()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub impl FreeTypeFontTable : FontTableMethods {
|
pub impl FontTableMethods for FreeTypeFontTable {
|
||||||
fn with_buffer(_blk: fn&(*u8, uint)) {
|
fn with_buffer(_blk: fn&(*u8, uint)) {
|
||||||
fail
|
fail!()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -185,7 +185,7 @@ pub impl FreeTypeFontHandle {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub impl FreeTypeFontHandle : FontHandleMethods {
|
pub impl FontHandleMethods for FreeTypeFontHandle {
|
||||||
// an identifier usable by FontContextHandle to recreate this FontHandle.
|
// an identifier usable by FontContextHandle to recreate this FontHandle.
|
||||||
pure fn face_identifier() -> ~str {
|
pure fn face_identifier() -> ~str {
|
||||||
/* FT_Get_Postscript_Name seems like a better choice here, but it
|
/* FT_Get_Postscript_Name seems like a better choice here, but it
|
||||||
|
|
|
@ -44,13 +44,12 @@ pub impl FreeTypeFontContextHandle {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub impl FreeTypeFontContextHandle : FontContextHandleMethods {
|
pub impl FontContextHandleMethods for FreeTypeFontContextHandle {
|
||||||
pure fn clone(&const self) -> FreeTypeFontContextHandle {
|
pure fn clone(&const self) -> FreeTypeFontContextHandle {
|
||||||
FreeTypeFontContextHandle { ctx: self.ctx }
|
FreeTypeFontContextHandle { ctx: self.ctx }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_font_from_identifier(name: ~str, style: UsedFontStyle)
|
fn create_font_from_identifier(name: ~str, style: UsedFontStyle) -> Result<FontHandle, ()> {
|
||||||
-> Result<FontHandle, ()> {
|
|
||||||
debug!("Creating font handle for %s", name);
|
debug!("Creating font handle for %s", name);
|
||||||
do path_from_identifier(name).chain |file_name| {
|
do path_from_identifier(name).chain |file_name| {
|
||||||
debug!("Opening font face %s", file_name);
|
debug!("Opening font face %s", file_name);
|
||||||
|
|
|
@ -6,7 +6,7 @@ use stb_image = stb_image::image;
|
||||||
pub type Image = stb_image::Image<u8>;
|
pub type Image = stb_image::Image<u8>;
|
||||||
|
|
||||||
pub fn Image(width: uint, height: uint, depth: uint, data: ~[u8]) -> Image {
|
pub fn Image(width: uint, height: uint, depth: uint, data: ~[u8]) -> Image {
|
||||||
stb_image::new_image(width, height, depth, move data)
|
stb_image::new_image(width, height, depth, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
const TEST_IMAGE: [u8 * 4962] = include_bin!("test.jpeg");
|
const TEST_IMAGE: [u8 * 4962] = include_bin!("test.jpeg");
|
||||||
|
@ -38,7 +38,7 @@ pub fn load_from_memory(buffer: &[u8]) -> Option<Image> {
|
||||||
|
|
||||||
assert image.data.len() == data.len();
|
assert image.data.len() == data.len();
|
||||||
|
|
||||||
Some(Image(image.width, image.height, image.depth, move data))
|
Some(Image(image.width, image.height, image.depth, data))
|
||||||
}
|
}
|
||||||
stb_image::ImageF32(_image) => fail!(~"HDR images not implemented"),
|
stb_image::ImageF32(_image) => fail!(~"HDR images not implemented"),
|
||||||
stb_image::Error => None
|
stb_image::Error => None
|
||||||
|
|
|
@ -26,7 +26,7 @@ impl ImageHolder {
|
||||||
static pub fn new(url: Url, local_image_cache: @LocalImageCache) -> ImageHolder {
|
static pub fn new(url: Url, local_image_cache: @LocalImageCache) -> ImageHolder {
|
||||||
debug!("ImageHolder::new() %?", url.to_str());
|
debug!("ImageHolder::new() %?", url.to_str());
|
||||||
let holder = ImageHolder {
|
let holder = ImageHolder {
|
||||||
url: move url,
|
url: url,
|
||||||
image: None,
|
image: None,
|
||||||
cached_size: Size2D(0,0),
|
cached_size: Size2D(0,0),
|
||||||
local_image_cache: local_image_cache,
|
local_image_cache: local_image_cache,
|
||||||
|
@ -40,7 +40,7 @@ impl ImageHolder {
|
||||||
local_image_cache.prefetch(&holder.url);
|
local_image_cache.prefetch(&holder.url);
|
||||||
local_image_cache.decode(&holder.url);
|
local_image_cache.decode(&holder.url);
|
||||||
|
|
||||||
move holder
|
holder
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -75,8 +75,8 @@ impl ImageHolder {
|
||||||
// the image and store it for the future
|
// the image and store it for the future
|
||||||
if self.image.is_none() {
|
if self.image.is_none() {
|
||||||
match self.local_image_cache.get_image(&self.url).recv() {
|
match self.local_image_cache.get_image(&self.url).recv() {
|
||||||
ImageReady(move image) => {
|
ImageReady(image) => {
|
||||||
self.image = Some(move image);
|
self.image = Some(image);
|
||||||
}
|
}
|
||||||
ImageNotReady => {
|
ImageNotReady => {
|
||||||
debug!("image not ready for %s", self.url.to_str());
|
debug!("image not ready for %s", self.url.to_str());
|
||||||
|
@ -95,8 +95,8 @@ impl ImageHolder {
|
||||||
None => None
|
None => None
|
||||||
};
|
};
|
||||||
|
|
||||||
replace(&mut self.image, move image);
|
replace(&mut self.image, image);
|
||||||
|
|
||||||
return move result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,12 +42,12 @@ pub fn from_cmdline_args(args: &[~str]) -> Opts {
|
||||||
};
|
};
|
||||||
|
|
||||||
let render_mode = match getopts::opt_maybe_str(&opt_match, ~"o") {
|
let render_mode = match getopts::opt_maybe_str(&opt_match, ~"o") {
|
||||||
Some(move output_file) => { Png(move output_file) }
|
Some(output_file) => Png(output_file),
|
||||||
None => { Screen }
|
None => Screen,
|
||||||
};
|
};
|
||||||
|
|
||||||
let render_backend = match getopts::opt_maybe_str(&opt_match, ~"r") {
|
let render_backend = match getopts::opt_maybe_str(&opt_match, ~"r") {
|
||||||
Some(move backend_str) => {
|
Some(backend_str) => {
|
||||||
if backend_str == ~"direct2d" {
|
if backend_str == ~"direct2d" {
|
||||||
Direct2DBackend
|
Direct2DBackend
|
||||||
} else if backend_str == ~"core-graphics" {
|
} else if backend_str == ~"core-graphics" {
|
||||||
|
@ -66,19 +66,19 @@ pub fn from_cmdline_args(args: &[~str]) -> Opts {
|
||||||
};
|
};
|
||||||
|
|
||||||
let tile_size: uint = match getopts::opt_maybe_str(&opt_match, ~"s") {
|
let tile_size: uint = match getopts::opt_maybe_str(&opt_match, ~"s") {
|
||||||
Some(move tile_size_str) => uint::from_str(tile_size_str).get(),
|
Some(tile_size_str) => uint::from_str(tile_size_str).get(),
|
||||||
None => 512,
|
None => 512,
|
||||||
};
|
};
|
||||||
|
|
||||||
let n_render_threads: uint = match getopts::opt_maybe_str(&opt_match, ~"t") {
|
let n_render_threads: uint = match getopts::opt_maybe_str(&opt_match, ~"t") {
|
||||||
Some(move n_render_threads_str) => uint::from_str(n_render_threads_str).get(),
|
Some(n_render_threads_str) => uint::from_str(n_render_threads_str).get(),
|
||||||
None => 1, // FIXME: Number of cores.
|
None => 1, // FIXME: Number of cores.
|
||||||
};
|
};
|
||||||
|
|
||||||
Opts {
|
Opts {
|
||||||
urls: move urls,
|
urls: urls,
|
||||||
render_mode: move render_mode,
|
render_mode: render_mode,
|
||||||
render_backend: move render_backend,
|
render_backend: render_backend,
|
||||||
n_render_threads: n_render_threads,
|
n_render_threads: n_render_threads,
|
||||||
tile_size: tile_size,
|
tile_size: tile_size,
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,11 +49,11 @@ struct QuartzFontTable {
|
||||||
|
|
||||||
pub impl QuartzFontTable {
|
pub impl QuartzFontTable {
|
||||||
static fn wrap(data: CFData) -> QuartzFontTable {
|
static fn wrap(data: CFData) -> QuartzFontTable {
|
||||||
QuartzFontTable { data: move data }
|
QuartzFontTable { data: data }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub impl QuartzFontTable : FontTableMethods {
|
pub impl FontTableMethods for QuartzFontTable {
|
||||||
fn with_buffer(blk: fn&(*u8, uint)) {
|
fn with_buffer(blk: fn&(*u8, uint)) {
|
||||||
blk(self.data.bytes(), self.data.len());
|
blk(self.data.bytes(), self.data.len());
|
||||||
}
|
}
|
||||||
|
@ -77,35 +77,35 @@ pub impl QuartzFontHandle {
|
||||||
let ctfont = quartz::font::core_text::font::new_from_CGFont(&cgfont, style.pt_size);
|
let ctfont = quartz::font::core_text::font::new_from_CGFont(&cgfont, style.pt_size);
|
||||||
|
|
||||||
let result = Ok(QuartzFontHandle {
|
let result = Ok(QuartzFontHandle {
|
||||||
cgfont : Some(move cgfont),
|
cgfont: Some(cgfont),
|
||||||
ctfont : move ctfont,
|
ctfont: ctfont,
|
||||||
});
|
});
|
||||||
|
|
||||||
return move result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static fn new_from_CTFont(_fctx: &QuartzFontContextHandle, ctfont: CTFont) -> Result<QuartzFontHandle, ()> {
|
static fn new_from_CTFont(_fctx: &QuartzFontContextHandle, ctfont: CTFont) -> Result<QuartzFontHandle, ()> {
|
||||||
let result = Ok(QuartzFontHandle {
|
let result = Ok(QuartzFontHandle {
|
||||||
mut cgfont: None,
|
mut cgfont: None,
|
||||||
ctfont: move ctfont,
|
ctfont: ctfont,
|
||||||
});
|
});
|
||||||
|
|
||||||
return move result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_CGFont() -> CGFont {
|
fn get_CGFont() -> CGFont {
|
||||||
match self.cgfont {
|
match self.cgfont {
|
||||||
Some(ref font) => move CFWrapper::wrap_shared(*font.borrow_ref()),
|
Some(ref font) => CFWrapper::wrap_shared(*font.borrow_ref()),
|
||||||
None => {
|
None => {
|
||||||
let cgfont = self.ctfont.copy_to_CGFont();
|
let cgfont = self.ctfont.copy_to_CGFont();
|
||||||
self.cgfont = Some(CFWrapper::clone(&cgfont));
|
self.cgfont = Some(CFWrapper::clone(&cgfont));
|
||||||
move cgfont
|
cgfont
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub impl QuartzFontHandle : FontHandleMethods {
|
pub impl FontHandleMethods for QuartzFontHandle {
|
||||||
pure fn family_name() -> ~str {
|
pure fn family_name() -> ~str {
|
||||||
self.ctfont.family_name()
|
self.ctfont.family_name()
|
||||||
}
|
}
|
||||||
|
@ -136,7 +136,7 @@ pub impl QuartzFontHandle : FontHandleMethods {
|
||||||
|
|
||||||
fn clone_with_style(fctx: &QuartzFontContextHandle, style: &SpecifiedFontStyle) -> Result<QuartzFontHandle,()> {
|
fn clone_with_style(fctx: &QuartzFontContextHandle, style: &SpecifiedFontStyle) -> Result<QuartzFontHandle,()> {
|
||||||
let new_font = self.ctfont.clone_with_font_size(style.pt_size);
|
let new_font = self.ctfont.clone_with_font_size(style.pt_size);
|
||||||
return QuartzFontHandle::new_from_CTFont(fctx, move new_font);
|
return QuartzFontHandle::new_from_CTFont(fctx, new_font);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn glyph_index(codepoint: char) -> Option<GlyphIndex> {
|
fn glyph_index(codepoint: char) -> Option<GlyphIndex> {
|
||||||
|
@ -193,8 +193,8 @@ pub impl QuartzFontHandle : FontHandleMethods {
|
||||||
|
|
||||||
fn get_table_for_tag(tag: FontTableTag) -> Option<FontTable> {
|
fn get_table_for_tag(tag: FontTableTag) -> Option<FontTable> {
|
||||||
let result : Option<CFData> = self.ctfont.get_font_table(tag);
|
let result : Option<CFData> = self.ctfont.get_font_table(tag);
|
||||||
return option::chain(move result, |data| {
|
return option::chain(result, |data| {
|
||||||
Some(QuartzFontTable::wrap(move data))
|
Some(QuartzFontTable::wrap(data))
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,16 +22,16 @@ pub impl QuartzFontContextHandle {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub impl QuartzFontContextHandle : FontContextHandleMethods {
|
pub impl FontContextHandleMethods for QuartzFontContextHandle {
|
||||||
pure fn clone(&const self) -> QuartzFontContextHandle {
|
pure fn clone(&const self) -> QuartzFontContextHandle {
|
||||||
QuartzFontContextHandle { ctx: self.ctx }
|
QuartzFontContextHandle { ctx: self.ctx }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_font_from_identifier(name: ~str, style: UsedFontStyle) -> Result<FontHandle, ()> {
|
fn create_font_from_identifier(name: ~str, style: UsedFontStyle) -> Result<FontHandle, ()> {
|
||||||
let ctfont_result = quartz::font_context::core_text::font::new_from_name(move name,
|
let ctfont_result = quartz::font_context::core_text::font::new_from_name(name,
|
||||||
style.pt_size);
|
style.pt_size);
|
||||||
do result::chain(move ctfont_result) |ctfont| {
|
do result::chain(ctfont_result) |ctfont| {
|
||||||
QuartzFontHandle::new_from_CTFont(&self, move ctfont)
|
QuartzFontHandle::new_from_CTFont(&self, ctfont)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,9 +39,9 @@ pub impl QuartzFontListHandle {
|
||||||
debug!("Creating new FontFamily for family: %s", family_name);
|
debug!("Creating new FontFamily for family: %s", family_name);
|
||||||
|
|
||||||
let new_family = @FontFamily::new(family_name);
|
let new_family = @FontFamily::new(family_name);
|
||||||
family_map.insert(move family_name, new_family);*/
|
family_map.insert(family_name, new_family);*/
|
||||||
}
|
}
|
||||||
return move family_map;
|
return family_map;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn load_variations_for_family(family: @FontFamily) {
|
fn load_variations_for_family(family: @FontFamily) {
|
||||||
|
@ -53,10 +53,10 @@ pub impl QuartzFontListHandle {
|
||||||
for family_collection.get_descriptors().each |descref: &CTFontDescriptorRef| {
|
for family_collection.get_descriptors().each |descref: &CTFontDescriptorRef| {
|
||||||
let desc = CFWrapper::wrap_shared(*descref);
|
let desc = CFWrapper::wrap_shared(*descref);
|
||||||
let font = quartz::font_list::core_text::font::new_from_descriptor(&desc, 0.0);
|
let font = quartz::font_list::core_text::font::new_from_descriptor(&desc, 0.0);
|
||||||
let handle = result::unwrap(QuartzFontHandle::new_from_CTFont(&self.fctx, move font));
|
let handle = result::unwrap(QuartzFontHandle::new_from_CTFont(&self.fctx, font));
|
||||||
|
|
||||||
debug!("Creating new FontEntry for face: %s", handle.face_name());
|
debug!("Creating new FontEntry for face: %s", handle.face_name());
|
||||||
let entry = @FontEntry::new(family, move handle);
|
let entry = @FontEntry::new(family, handle);
|
||||||
family.entries.push(entry);
|
family.entries.push(entry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,12 +61,15 @@ impl RenderContext {
|
||||||
let dest_rect = bounds.to_azure_rect();
|
let dest_rect = bounds.to_azure_rect();
|
||||||
let draw_surface_options = DrawSurfaceOptions(Linear, true);
|
let draw_surface_options = DrawSurfaceOptions(Linear, true);
|
||||||
let draw_options = DrawOptions(1.0f as AzFloat, 0);
|
let draw_options = DrawOptions(1.0f as AzFloat, 0);
|
||||||
draw_target_ref.draw_surface(move azure_surface, dest_rect, source_rect,
|
draw_target_ref.draw_surface(azure_surface,
|
||||||
draw_surface_options, draw_options);
|
dest_rect,
|
||||||
|
source_rect,
|
||||||
|
draw_surface_options,
|
||||||
|
draw_options);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn clear(&self) {
|
fn clear(&self) {
|
||||||
let pattern = ColorPattern(Color(1f as AzFloat, 1f as AzFloat, 1f as AzFloat, 1f as AzFloat));
|
let pattern = ColorPattern(Color(1.0, 1.0, 1.0, 1.0));
|
||||||
let rect = Rect(Point2D(self.canvas.rect.origin.x as AzFloat,
|
let rect = Rect(Point2D(self.canvas.rect.origin.x as AzFloat,
|
||||||
self.canvas.rect.origin.y as AzFloat),
|
self.canvas.rect.origin.y as AzFloat),
|
||||||
Size2D(self.canvas.rect.size.width as AzFloat,
|
Size2D(self.canvas.rect.size.width as AzFloat,
|
||||||
|
@ -79,7 +82,7 @@ trait to_float {
|
||||||
fn to_float() -> float;
|
fn to_float() -> float;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl u8 : to_float {
|
impl to_float for u8 {
|
||||||
fn to_float() -> float {
|
fn to_float() -> float {
|
||||||
(self as float) / 255f
|
(self as float) / 255f
|
||||||
}
|
}
|
||||||
|
@ -90,7 +93,7 @@ trait ToAzureRect {
|
||||||
fn to_azure_snapped_rect() -> Rect<AzFloat>;
|
fn to_azure_snapped_rect() -> Rect<AzFloat>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Rect<Au> : ToAzureRect {
|
impl ToAzureRect for Rect<Au> {
|
||||||
fn to_azure_rect() -> Rect<AzFloat> {
|
fn to_azure_rect() -> Rect<AzFloat> {
|
||||||
Rect(Point2D(self.origin.x.to_px() as AzFloat, self.origin.y.to_px() as AzFloat),
|
Rect(Point2D(self.origin.x.to_px() as AzFloat, self.origin.y.to_px() as AzFloat),
|
||||||
Size2D(self.size.width.to_px() as AzFloat, self.size.height.to_px() as AzFloat))
|
Size2D(self.size.width.to_px() as AzFloat, self.size.height.to_px() as AzFloat))
|
||||||
|
|
|
@ -33,7 +33,7 @@ pub fn render_layers(layer_ref: *RenderLayer,
|
||||||
f: RenderFn) -> LayerBufferSet {
|
f: RenderFn) -> LayerBufferSet {
|
||||||
let tile_size = opts.tile_size;
|
let tile_size = opts.tile_size;
|
||||||
|
|
||||||
let mut _buffers = match move buffer_set { LayerBufferSet { buffers: move b } => move b };
|
let mut _buffers = match buffer_set { LayerBufferSet { buffers: b } => b };
|
||||||
|
|
||||||
// FIXME: Try not to create a new array here.
|
// FIXME: Try not to create a new array here.
|
||||||
let new_buffer_ports = dvec::DVec();
|
let new_buffer_ports = dvec::DVec();
|
||||||
|
@ -100,7 +100,7 @@ pub fn render_layers(layer_ref: *RenderLayer,
|
||||||
|
|
||||||
buffer = LayerBuffer {
|
buffer = LayerBuffer {
|
||||||
draw_target: DrawTarget::new_with_data(opts.render_backend,
|
draw_target: DrawTarget::new_with_data(opts.render_backend,
|
||||||
move data,
|
data,
|
||||||
offset,
|
offset,
|
||||||
size,
|
size,
|
||||||
size.width * 4,
|
size.width * 4,
|
||||||
|
@ -114,10 +114,10 @@ pub fn render_layers(layer_ref: *RenderLayer,
|
||||||
let (new_buffer_port, new_buffer_chan) = pipes::stream();
|
let (new_buffer_port, new_buffer_chan) = pipes::stream();
|
||||||
|
|
||||||
// Send the buffer to the child.
|
// Send the buffer to the child.
|
||||||
f(layer_ref, move buffer, move new_buffer_chan);
|
f(layer_ref, buffer, new_buffer_chan);
|
||||||
|
|
||||||
// Enqueue the port.
|
// Enqueue the port.
|
||||||
new_buffer_ports.push(move new_buffer_port);
|
new_buffer_ports.push(new_buffer_port);
|
||||||
|
|
||||||
x += tile_size;
|
x += tile_size;
|
||||||
}
|
}
|
||||||
|
@ -132,6 +132,6 @@ pub fn render_layers(layer_ref: *RenderLayer,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return LayerBufferSet { buffers: move dvec::unwrap(move new_buffers) };
|
return LayerBufferSet { buffers: dvec::unwrap(new_buffers) };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,37 +27,36 @@ pub enum Msg {
|
||||||
pub type RenderTask = SharedChan<Msg>;
|
pub type RenderTask = SharedChan<Msg>;
|
||||||
|
|
||||||
pub fn RenderTask<C:Compositor + Owned>(compositor: C, opts: Opts) -> RenderTask {
|
pub fn RenderTask<C:Compositor + Owned>(compositor: C, opts: Opts) -> RenderTask {
|
||||||
let compositor_cell = Cell(move compositor);
|
let compositor_cell = Cell(compositor);
|
||||||
let opts_cell = Cell(move opts);
|
let opts_cell = Cell(opts);
|
||||||
let render_task = do spawn_listener |po: Port<Msg>| {
|
let render_task = do spawn_listener |po: Port<Msg>| {
|
||||||
let (layer_buffer_set_port, layer_buffer_channel) = pipes::stream();
|
let (layer_buffer_set_port, layer_buffer_channel) = pipes::stream();
|
||||||
|
|
||||||
let compositor = compositor_cell.take();
|
let compositor = compositor_cell.take();
|
||||||
compositor.begin_drawing(move layer_buffer_channel);
|
compositor.begin_drawing(layer_buffer_channel);
|
||||||
|
|
||||||
// FIXME: Annoying three-cell dance here. We need one-shot closures.
|
// FIXME: Annoying three-cell dance here. We need one-shot closures.
|
||||||
let opts = opts_cell.with_ref(|o| copy *o);
|
let opts = opts_cell.with_ref(|o| copy *o);
|
||||||
let n_threads = opts.n_render_threads;
|
let n_threads = opts.n_render_threads;
|
||||||
let new_opts_cell = Cell(move opts);
|
let new_opts_cell: Cell<Opts> = Cell(opts);
|
||||||
|
|
||||||
let thread_pool = do TaskPool::new(n_threads, Some(SingleThreaded))
|
let thread_pool = do TaskPool::new(n_threads, Some(SingleThreaded)) {
|
||||||
|move new_opts_cell| {
|
let opts_cell: Cell<Opts> = Cell(new_opts_cell.with_ref(|o| copy *o));
|
||||||
let opts_cell = Cell(new_opts_cell.with_ref(|o| copy *o));
|
let f: ~fn(uint) -> ThreadRenderContext = |thread_index| {
|
||||||
let f: ~fn(uint) -> ThreadRenderContext = |thread_index, move opts_cell| {
|
|
||||||
ThreadRenderContext {
|
ThreadRenderContext {
|
||||||
thread_index: thread_index,
|
thread_index: thread_index,
|
||||||
font_ctx: @FontContext::new(opts_cell.with_ref(|o| o.render_backend), false),
|
font_ctx: @FontContext::new(opts_cell.with_ref(|o| o.render_backend), false),
|
||||||
opts: opts_cell.with_ref(|o| copy *o),
|
opts: opts_cell.with_ref(|o| copy *o),
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
move f
|
f
|
||||||
};
|
};
|
||||||
|
|
||||||
Renderer {
|
Renderer {
|
||||||
port: po,
|
port: po,
|
||||||
compositor: move compositor,
|
compositor: compositor,
|
||||||
mut layer_buffer_set_port: Cell(move layer_buffer_set_port),
|
mut layer_buffer_set_port: Cell(layer_buffer_set_port),
|
||||||
thread_pool: move thread_pool,
|
thread_pool: thread_pool,
|
||||||
opts: opts_cell.take()
|
opts: opts_cell.take()
|
||||||
}.start();
|
}.start();
|
||||||
};
|
};
|
||||||
|
@ -85,7 +84,7 @@ impl<C: Compositor Owned> Renderer<C> {
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
match self.port.recv() {
|
match self.port.recv() {
|
||||||
RenderMsg(move render_layer) => self.render(move render_layer),
|
RenderMsg(render_layer) => self.render(render_layer),
|
||||||
ExitMsg(response_ch) => {
|
ExitMsg(response_ch) => {
|
||||||
response_ch.send(());
|
response_ch.send(());
|
||||||
break;
|
break;
|
||||||
|
@ -105,10 +104,10 @@ impl<C: Compositor Owned> Renderer<C> {
|
||||||
|
|
||||||
let layer_buffer_set = layer_buffer_set_port.recv();
|
let layer_buffer_set = layer_buffer_set_port.recv();
|
||||||
let (new_layer_buffer_set_port, layer_buffer_set_channel) = pipes::stream();
|
let (new_layer_buffer_set_port, layer_buffer_set_channel) = pipes::stream();
|
||||||
self.layer_buffer_set_port.put_back(move new_layer_buffer_set_port);
|
self.layer_buffer_set_port.put_back(new_layer_buffer_set_port);
|
||||||
|
|
||||||
let layer_buffer_set_cell = Cell(move layer_buffer_set);
|
let layer_buffer_set_cell = Cell(layer_buffer_set);
|
||||||
let layer_buffer_set_channel_cell = Cell(move layer_buffer_set_channel);
|
let layer_buffer_set_channel_cell = Cell(layer_buffer_set_channel);
|
||||||
|
|
||||||
debug!("renderer: rendering");
|
debug!("renderer: rendering");
|
||||||
|
|
||||||
|
@ -116,15 +115,10 @@ impl<C: Compositor Owned> Renderer<C> {
|
||||||
let layer_buffer_set = layer_buffer_set_cell.take();
|
let layer_buffer_set = layer_buffer_set_cell.take();
|
||||||
let layer_buffer_set_channel = layer_buffer_set_channel_cell.take();
|
let layer_buffer_set_channel = layer_buffer_set_channel_cell.take();
|
||||||
|
|
||||||
let layer_buffer_set = do render_layers(ptr::to_unsafe_ptr(&render_layer),
|
let layer_buffer_set = do render_layers(&render_layer, layer_buffer_set, &self.opts)
|
||||||
move layer_buffer_set,
|
|
||||||
&self.opts)
|
|
||||||
|render_layer_ref, layer_buffer, buffer_chan| {
|
|render_layer_ref, layer_buffer, buffer_chan| {
|
||||||
let layer_buffer_cell = Cell(move layer_buffer);
|
let layer_buffer_cell = Cell(layer_buffer);
|
||||||
do self.thread_pool.execute |thread_render_context,
|
do self.thread_pool.execute |thread_render_context| {
|
||||||
move render_layer_ref,
|
|
||||||
move buffer_chan,
|
|
||||||
move layer_buffer_cell| {
|
|
||||||
do layer_buffer_cell.with_ref |layer_buffer| {
|
do layer_buffer_cell.with_ref |layer_buffer| {
|
||||||
// Build the render context.
|
// Build the render context.
|
||||||
let ctx = RenderContext {
|
let ctx = RenderContext {
|
||||||
|
@ -155,7 +149,7 @@ impl<C: Compositor Owned> Renderer<C> {
|
||||||
};
|
};
|
||||||
|
|
||||||
debug!("renderer: returning surface");
|
debug!("renderer: returning surface");
|
||||||
self.compositor.draw(move layer_buffer_set_channel, move layer_buffer_set);
|
self.compositor.draw(layer_buffer_set_channel, layer_buffer_set);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@ pub fn factory() -> LoaderTask {
|
||||||
Ok(reader) => {
|
Ok(reader) => {
|
||||||
while !reader.eof() {
|
while !reader.eof() {
|
||||||
let data = reader.read_bytes(READ_SIZE);
|
let data = reader.read_bytes(READ_SIZE);
|
||||||
progress_chan.send(Payload(move data));
|
progress_chan.send(Payload(data));
|
||||||
}
|
}
|
||||||
progress_chan.send(Done(Ok(())));
|
progress_chan.send(Done(Ok(())));
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@ pub fn factory() -> LoaderTask {
|
||||||
debug!("http_loader: got data from %?", url);
|
debug!("http_loader: got data from %?", url);
|
||||||
let mut junk = None;
|
let mut junk = None;
|
||||||
*data <-> junk;
|
*data <-> junk;
|
||||||
progress_chan.send(Payload(option::unwrap(move junk)));
|
progress_chan.send(Payload(option::unwrap(junk)));
|
||||||
}
|
}
|
||||||
http_client::Error(*) => {
|
http_client::Error(*) => {
|
||||||
debug!("http_loader: error loading %?", url);
|
debug!("http_loader: error loading %?", url);
|
||||||
|
|
|
@ -58,7 +58,7 @@ impl ImageResponseMsg {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ImageResponseMsg: cmp::Eq {
|
impl Eq for ImageResponseMsg {
|
||||||
pure fn eq(&self, other: &ImageResponseMsg) -> bool {
|
pure fn eq(&self, other: &ImageResponseMsg) -> bool {
|
||||||
// FIXME: Bad copies
|
// FIXME: Bad copies
|
||||||
match (self.clone(), other.clone()) {
|
match (self.clone(), other.clone()) {
|
||||||
|
@ -90,11 +90,11 @@ pub fn ImageCacheTask_(resource_task: ResourceTask,
|
||||||
// FIXME: Doing some dancing to avoid copying decoder_factory, our test
|
// FIXME: Doing some dancing to avoid copying decoder_factory, our test
|
||||||
// version of which contains an uncopyable type which rust will currently
|
// version of which contains an uncopyable type which rust will currently
|
||||||
// copy unsoundly
|
// copy unsoundly
|
||||||
let decoder_factory_cell = Cell(move decoder_factory);
|
let decoder_factory_cell = Cell(decoder_factory);
|
||||||
|
|
||||||
let (port, chan) = stream();
|
let (port, chan) = stream();
|
||||||
let chan = SharedChan(move chan);
|
let chan = SharedChan(chan);
|
||||||
let port_cell = Cell(move port);
|
let port_cell = Cell(port);
|
||||||
let chan_cell = Cell(chan.clone());
|
let chan_cell = Cell(chan.clone());
|
||||||
|
|
||||||
do spawn {
|
do spawn {
|
||||||
|
@ -109,12 +109,12 @@ pub fn ImageCacheTask_(resource_task: ResourceTask,
|
||||||
}.run();
|
}.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
move chan
|
chan
|
||||||
}
|
}
|
||||||
|
|
||||||
fn SyncImageCacheTask(resource_task: ResourceTask) -> ImageCacheTask {
|
fn SyncImageCacheTask(resource_task: ResourceTask) -> ImageCacheTask {
|
||||||
let (port, chan) = stream();
|
let (port, chan) = stream();
|
||||||
let port_cell = Cell(move port);
|
let port_cell = Cell(port);
|
||||||
|
|
||||||
do spawn {
|
do spawn {
|
||||||
let port = port_cell.take();
|
let port = port_cell.take();
|
||||||
|
@ -123,20 +123,20 @@ fn SyncImageCacheTask(resource_task: ResourceTask) -> ImageCacheTask {
|
||||||
loop {
|
loop {
|
||||||
let msg: Msg = port.recv();
|
let msg: Msg = port.recv();
|
||||||
|
|
||||||
match move msg {
|
match msg {
|
||||||
GetImage(move url, move response) => {
|
GetImage(url, response) => {
|
||||||
inner_cache.send(WaitForImage(move url, move response));
|
inner_cache.send(WaitForImage(url, response));
|
||||||
}
|
}
|
||||||
Exit(move response) => {
|
Exit(response) => {
|
||||||
inner_cache.send(Exit(move response));
|
inner_cache.send(Exit(response));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
move msg => inner_cache.send(move msg)
|
msg => inner_cache.send(msg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return move SharedChan(move chan);
|
return SharedChan(chan);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ImageCache {
|
struct ImageCache {
|
||||||
|
@ -185,28 +185,28 @@ impl ImageCache {
|
||||||
|
|
||||||
debug!("image_cache_task: received: %?", msg);
|
debug!("image_cache_task: received: %?", msg);
|
||||||
|
|
||||||
match move msg {
|
match msg {
|
||||||
Prefetch(move url) => self.prefetch(move url),
|
Prefetch(url) => self.prefetch(url),
|
||||||
StorePrefetchedImageData(move url, move data) => {
|
StorePrefetchedImageData(url, data) => {
|
||||||
self.store_prefetched_image_data(move url, move data);
|
self.store_prefetched_image_data(url, data);
|
||||||
}
|
}
|
||||||
Decode(move url) => self.decode(move url),
|
Decode(url) => self.decode(url),
|
||||||
StoreImage(move url, move image) => self.store_image(move url, move image),
|
StoreImage(url, image) => self.store_image(url, image),
|
||||||
GetImage(move url, move response) => self.get_image(move url, move response),
|
GetImage(url, response) => self.get_image(url, response),
|
||||||
WaitForImage(move url, move response) => {
|
WaitForImage(url, response) => {
|
||||||
self.wait_for_image(move url, move response)
|
self.wait_for_image(url, response)
|
||||||
}
|
}
|
||||||
OnMsg(move handler) => msg_handlers.push(handler),
|
OnMsg(handler) => msg_handlers.push(handler),
|
||||||
Exit(move response) => {
|
Exit(response) => {
|
||||||
assert self.need_exit.is_none();
|
assert self.need_exit.is_none();
|
||||||
self.need_exit = Some(move response);
|
self.need_exit = Some(response);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let need_exit = replace(&mut self.need_exit, None);
|
let need_exit = replace(&mut self.need_exit, None);
|
||||||
|
|
||||||
match move need_exit {
|
match need_exit {
|
||||||
Some(move response) => {
|
Some(response) => {
|
||||||
// Wait until we have no outstanding requests and subtasks
|
// Wait until we have no outstanding requests and subtasks
|
||||||
// before exiting
|
// before exiting
|
||||||
let mut can_exit = true;
|
let mut can_exit = true;
|
||||||
|
@ -223,7 +223,7 @@ impl ImageCache {
|
||||||
response.send(());
|
response.send(());
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
self.need_exit = Some(move response);
|
self.need_exit = Some(response);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None => ()
|
None => ()
|
||||||
|
@ -232,14 +232,14 @@ impl ImageCache {
|
||||||
}
|
}
|
||||||
|
|
||||||
priv fn get_state(url: Url) -> ImageState {
|
priv fn get_state(url: Url) -> ImageState {
|
||||||
match move self.state_map.find(&url) {
|
match self.state_map.find(&url) {
|
||||||
Some(move state) => move state,
|
Some(state) => state,
|
||||||
None => Init
|
None => Init
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
priv fn set_state(url: Url, state: ImageState) {
|
priv fn set_state(url: Url, state: ImageState) {
|
||||||
self.state_map.insert(move url, move state);
|
self.state_map.insert(url, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
priv fn prefetch(url: Url) {
|
priv fn prefetch(url: Url) {
|
||||||
|
@ -256,15 +256,15 @@ impl ImageCache {
|
||||||
let image = load_image_data(copy url, resource_task.clone());
|
let image = load_image_data(copy url, resource_task.clone());
|
||||||
|
|
||||||
let result = if image.is_ok() {
|
let result = if image.is_ok() {
|
||||||
Ok(Cell(result::unwrap(move image)))
|
Ok(Cell(result::unwrap(image)))
|
||||||
} else {
|
} else {
|
||||||
Err(())
|
Err(())
|
||||||
};
|
};
|
||||||
to_cache.send(StorePrefetchedImageData(copy url, move result));
|
to_cache.send(StorePrefetchedImageData(copy url, result));
|
||||||
debug!("image_cache_task: ended fetch for %s", (copy url).to_str());
|
debug!("image_cache_task: ended fetch for %s", (copy url).to_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
self.set_state(move url, Prefetching(DoNotDecode));
|
self.set_state(url, Prefetching(DoNotDecode));
|
||||||
}
|
}
|
||||||
|
|
||||||
Prefetching(*) | Prefetched(*) | Decoding | Decoded(*) | Failed => {
|
Prefetching(*) | Prefetched(*) | Decoding | Decoded(*) | Failed => {
|
||||||
|
@ -279,15 +279,15 @@ impl ImageCache {
|
||||||
match data {
|
match data {
|
||||||
Ok(data_cell) => {
|
Ok(data_cell) => {
|
||||||
let data = data_cell.take();
|
let data = data_cell.take();
|
||||||
self.set_state(copy url, Prefetched(@Cell(move data)));
|
self.set_state(copy url, Prefetched(@Cell(data)));
|
||||||
match next_step {
|
match next_step {
|
||||||
DoDecode => self.decode(move url),
|
DoDecode => self.decode(url),
|
||||||
_ => ()
|
_ => ()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(*) => {
|
Err(*) => {
|
||||||
self.set_state(copy url, Failed);
|
self.set_state(copy url, Failed);
|
||||||
self.purge_waiters(move url, || ImageFailed);
|
self.purge_waiters(url, || ImageFailed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -308,7 +308,7 @@ impl ImageCache {
|
||||||
|
|
||||||
Prefetching(DoNotDecode) => {
|
Prefetching(DoNotDecode) => {
|
||||||
// We don't have the data yet, queue up the decode
|
// We don't have the data yet, queue up the decode
|
||||||
self.set_state(move url, Prefetching(DoDecode))
|
self.set_state(url, Prefetching(DoDecode))
|
||||||
}
|
}
|
||||||
|
|
||||||
Prefetching(DoDecode) => {
|
Prefetching(DoDecode) => {
|
||||||
|
@ -323,20 +323,20 @@ impl ImageCache {
|
||||||
let url_cell = Cell(copy url);
|
let url_cell = Cell(copy url);
|
||||||
let decode = (self.decoder_factory)();
|
let decode = (self.decoder_factory)();
|
||||||
|
|
||||||
do spawn |move url_cell, move decode, move data, move to_cache| {
|
do spawn {
|
||||||
let url = url_cell.take();
|
let url = url_cell.take();
|
||||||
debug!("image_cache_task: started image decode for %s", url.to_str());
|
debug!("image_cache_task: started image decode for %s", url.to_str());
|
||||||
let image = decode(data);
|
let image = decode(data);
|
||||||
let image = if image.is_some() {
|
let image = if image.is_some() {
|
||||||
Some(ARC(~option::unwrap(move image)))
|
Some(ARC(~option::unwrap(image)))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
to_cache.send(StoreImage(copy url, move image));
|
to_cache.send(StoreImage(copy url, image));
|
||||||
debug!("image_cache_task: ended image decode for %s", url.to_str());
|
debug!("image_cache_task: ended image decode for %s", url.to_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
self.set_state(move url, Decoding);
|
self.set_state(url, Decoding);
|
||||||
}
|
}
|
||||||
|
|
||||||
Decoding | Decoded(*) | Failed => {
|
Decoding | Decoded(*) | Failed => {
|
||||||
|
@ -352,11 +352,11 @@ impl ImageCache {
|
||||||
match image {
|
match image {
|
||||||
Some(image) => {
|
Some(image) => {
|
||||||
self.set_state(copy url, Decoded(@clone_arc(&image)));
|
self.set_state(copy url, Decoded(@clone_arc(&image)));
|
||||||
self.purge_waiters(move url, || ImageReady(clone_arc(&image)) );
|
self.purge_waiters(url, || ImageReady(clone_arc(&image)) );
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
self.set_state(copy url, Failed);
|
self.set_state(copy url, Failed);
|
||||||
self.purge_waiters(move url, || ImageFailed );
|
self.purge_waiters(url, || ImageFailed );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -426,10 +426,10 @@ impl ImageCache {
|
||||||
// We don't have this image yet
|
// We don't have this image yet
|
||||||
match self.wait_map.find(&url) {
|
match self.wait_map.find(&url) {
|
||||||
Some(waiters) => {
|
Some(waiters) => {
|
||||||
vec::push(&mut *waiters, move response);
|
vec::push(&mut *waiters, response);
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
self.wait_map.insert(move url, @mut ~[move response]);
|
self.wait_map.insert(url, @mut ~[response]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -451,19 +451,17 @@ trait ImageCacheTaskClient {
|
||||||
fn exit();
|
fn exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ImageCacheTask: ImageCacheTaskClient {
|
impl ImageCacheTaskClient for ImageCacheTask {
|
||||||
|
|
||||||
fn exit() {
|
fn exit() {
|
||||||
let (response_port, response_chan) = stream();
|
let (response_port, response_chan) = stream();
|
||||||
self.send(Exit(move response_chan));
|
self.send(Exit(response_chan));
|
||||||
response_port.recv();
|
response_port.recv();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn load_image_data(url: Url, resource_task: ResourceTask) -> Result<~[u8], ()> {
|
fn load_image_data(url: Url, resource_task: ResourceTask) -> Result<~[u8], ()> {
|
||||||
let (response_port, response_chan) = stream();
|
let (response_port, response_chan) = stream();
|
||||||
resource_task.send(resource_task::Load(move url, response_chan));
|
resource_task.send(resource_task::Load(url, response_chan));
|
||||||
|
|
||||||
let mut image_data = ~[];
|
let mut image_data = ~[];
|
||||||
|
|
||||||
|
@ -473,7 +471,7 @@ fn load_image_data(url: Url, resource_task: ResourceTask) -> Result<~[u8], ()> {
|
||||||
image_data += data;
|
image_data += data;
|
||||||
}
|
}
|
||||||
resource_task::Done(result::Ok(*)) => {
|
resource_task::Done(result::Ok(*)) => {
|
||||||
return Ok(move image_data);
|
return Ok(image_data);
|
||||||
}
|
}
|
||||||
resource_task::Done(result::Err(*)) => {
|
resource_task::Done(result::Err(*)) => {
|
||||||
return Err(());
|
return Err(());
|
||||||
|
@ -488,7 +486,7 @@ fn default_decoder_factory() -> ~fn(&[u8]) -> Option<Image> {
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
fn mock_resource_task(on_load: ~fn(resource: Chan<resource_task::ProgressMsg>)) -> ResourceTask {
|
fn mock_resource_task(on_load: ~fn(resource: Chan<resource_task::ProgressMsg>)) -> ResourceTask {
|
||||||
do spawn_listener |port: Port<resource_task::ControlMsg>, move on_load| {
|
do spawn_listener |port: Port<resource_task::ControlMsg>| {
|
||||||
loop {
|
loop {
|
||||||
match port.recv() {
|
match port.recv() {
|
||||||
resource_task::Load(_, response) => {
|
resource_task::Load(_, response) => {
|
||||||
|
@ -522,7 +520,7 @@ fn should_fail_if_unprefetched_image_is_requested() {
|
||||||
let url = make_url(~"file", None);
|
let url = make_url(~"file", None);
|
||||||
|
|
||||||
let (chan, port) = stream();
|
let (chan, port) = stream();
|
||||||
image_cache_task.send(GetImage(move url, move chan));
|
image_cache_task.send(GetImage(url, chan));
|
||||||
port.recv();
|
port.recv();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -539,7 +537,7 @@ fn should_request_url_from_resource_task_on_prefetch() {
|
||||||
let image_cache_task = ImageCacheTask(mock_resource_task);
|
let image_cache_task = ImageCacheTask(mock_resource_task);
|
||||||
let url = make_url(~"file", None);
|
let url = make_url(~"file", None);
|
||||||
|
|
||||||
image_cache_task.send(Prefetch(move url));
|
image_cache_task.send(Prefetch(url));
|
||||||
url_requested.recv();
|
url_requested.recv();
|
||||||
image_cache_task.exit();
|
image_cache_task.exit();
|
||||||
mock_resource_task.send(resource_task::Exit);
|
mock_resource_task.send(resource_task::Exit);
|
||||||
|
@ -555,7 +553,7 @@ fn should_fail_if_requesting_decode_of_an_unprefetched_image() {
|
||||||
let image_cache_task = ImageCacheTask(mock_resource_task);
|
let image_cache_task = ImageCacheTask(mock_resource_task);
|
||||||
let url = make_url(~"file", None);
|
let url = make_url(~"file", None);
|
||||||
|
|
||||||
image_cache_task.send(Decode(move url));
|
image_cache_task.send(Decode(url));
|
||||||
image_cache_task.exit();
|
image_cache_task.exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -574,7 +572,7 @@ fn should_fail_if_requesting_image_before_requesting_decode() {
|
||||||
// no decode message
|
// no decode message
|
||||||
|
|
||||||
let (chan, _port) = stream();
|
let (chan, _port) = stream();
|
||||||
image_cache_task.send(GetImage(move url, move chan));
|
image_cache_task.send(GetImage(url, chan));
|
||||||
|
|
||||||
image_cache_task.exit();
|
image_cache_task.exit();
|
||||||
mock_resource_task.send(resource_task::Exit);
|
mock_resource_task.send(resource_task::Exit);
|
||||||
|
@ -594,7 +592,7 @@ fn should_not_request_url_from_resource_task_on_multiple_prefetches() {
|
||||||
let url = make_url(~"file", None);
|
let url = make_url(~"file", None);
|
||||||
|
|
||||||
image_cache_task.send(Prefetch(copy url));
|
image_cache_task.send(Prefetch(copy url));
|
||||||
image_cache_task.send(Prefetch(move url));
|
image_cache_task.send(Prefetch(url));
|
||||||
url_requested.recv();
|
url_requested.recv();
|
||||||
image_cache_task.exit();
|
image_cache_task.exit();
|
||||||
mock_resource_task.send(resource_task::Exit);
|
mock_resource_task.send(resource_task::Exit);
|
||||||
|
@ -606,7 +604,7 @@ fn should_return_image_not_ready_if_data_has_not_arrived() {
|
||||||
|
|
||||||
let (wait_chan, wait_port) = pipes::stream();
|
let (wait_chan, wait_port) = pipes::stream();
|
||||||
|
|
||||||
let mock_resource_task = do mock_resource_task |response, move wait_port| {
|
let mock_resource_task = do mock_resource_task |response| {
|
||||||
// Don't send the data until after the client requests
|
// Don't send the data until after the client requests
|
||||||
// the image
|
// the image
|
||||||
wait_port.recv();
|
wait_port.recv();
|
||||||
|
@ -620,7 +618,7 @@ fn should_return_image_not_ready_if_data_has_not_arrived() {
|
||||||
image_cache_task.send(Prefetch(copy url));
|
image_cache_task.send(Prefetch(copy url));
|
||||||
image_cache_task.send(Decode(copy url));
|
image_cache_task.send(Decode(copy url));
|
||||||
let (response_chan, response_port) = stream();
|
let (response_chan, response_port) = stream();
|
||||||
image_cache_task.send(GetImage(move url, move response_chan));
|
image_cache_task.send(GetImage(url, response_chan));
|
||||||
assert response_port.recv() == ImageNotReady;
|
assert response_port.recv() == ImageNotReady;
|
||||||
wait_chan.send(());
|
wait_chan.send(());
|
||||||
image_cache_task.exit();
|
image_cache_task.exit();
|
||||||
|
@ -655,7 +653,7 @@ fn should_return_decoded_image_data_if_data_has_arrived() {
|
||||||
wait_for_image_chan.recv();
|
wait_for_image_chan.recv();
|
||||||
|
|
||||||
let (response_chan, response_port) = stream();
|
let (response_chan, response_port) = stream();
|
||||||
image_cache_task.send(GetImage(move url, move response_chan));
|
image_cache_task.send(GetImage(url, response_chan));
|
||||||
match response_port.recv() {
|
match response_port.recv() {
|
||||||
ImageReady(_) => (),
|
ImageReady(_) => (),
|
||||||
_ => fail
|
_ => fail
|
||||||
|
@ -694,7 +692,7 @@ fn should_return_decoded_image_data_for_multiple_requests() {
|
||||||
|
|
||||||
for iter::repeat(2) {
|
for iter::repeat(2) {
|
||||||
let (response_chan, response_port) = stream();
|
let (response_chan, response_port) = stream();
|
||||||
image_cache_task.send(GetImage(copy url, move response_chan));
|
image_cache_task.send(GetImage(copy url, response_chan));
|
||||||
match response_port.recv() {
|
match response_port.recv() {
|
||||||
ImageReady(_) => (),
|
ImageReady(_) => (),
|
||||||
_ => fail
|
_ => fail
|
||||||
|
@ -826,7 +824,7 @@ fn should_return_failed_if_image_bin_cannot_be_fetched() {
|
||||||
wait_for_prefetech.recv();
|
wait_for_prefetech.recv();
|
||||||
|
|
||||||
let (response_chan, response_port) = stream();
|
let (response_chan, response_port) = stream();
|
||||||
image_cache_task.send(GetImage(move url, move response_chan));
|
image_cache_task.send(GetImage(url, response_chan));
|
||||||
match response_port.recv() {
|
match response_port.recv() {
|
||||||
ImageFailed => (),
|
ImageFailed => (),
|
||||||
_ => fail
|
_ => fail
|
||||||
|
@ -865,7 +863,7 @@ fn should_return_failed_for_multiple_get_image_requests_if_image_bin_cannot_be_f
|
||||||
wait_for_prefetech.recv();
|
wait_for_prefetech.recv();
|
||||||
|
|
||||||
let (response_chan, response_port) = stream();
|
let (response_chan, response_port) = stream();
|
||||||
image_cache_task.send(GetImage(copy url, move response_chan));
|
image_cache_task.send(GetImage(copy url, response_chan));
|
||||||
match response_port.recv() {
|
match response_port.recv() {
|
||||||
ImageFailed => (),
|
ImageFailed => (),
|
||||||
_ => fail
|
_ => fail
|
||||||
|
@ -873,7 +871,7 @@ fn should_return_failed_for_multiple_get_image_requests_if_image_bin_cannot_be_f
|
||||||
|
|
||||||
// And ask again, we should get the same response
|
// And ask again, we should get the same response
|
||||||
let (response_chan, response_port) = stream();
|
let (response_chan, response_port) = stream();
|
||||||
image_cache_task.send(GetImage(move url, move response_chan));
|
image_cache_task.send(GetImage(url, response_chan));
|
||||||
match response_port.recv() {
|
match response_port.recv() {
|
||||||
ImageFailed => (),
|
ImageFailed => (),
|
||||||
_ => fail
|
_ => fail
|
||||||
|
@ -893,17 +891,17 @@ fn should_return_not_ready_if_image_is_still_decoding() {
|
||||||
response.send(resource_task::Done(result::Ok(())));
|
response.send(resource_task::Done(result::Ok(())));
|
||||||
};
|
};
|
||||||
|
|
||||||
let wait_to_decode_port_cell = Cell(move wait_to_decode_port);
|
let wait_to_decode_port_cell = Cell(wait_to_decode_port);
|
||||||
let decoder_factory = fn~(move wait_to_decode_port_cell) -> ~fn(&[u8]) -> Option<Image> {
|
let decoder_factory = fn~() -> ~fn(&[u8]) -> Option<Image> {
|
||||||
let wait_to_decode_port = wait_to_decode_port_cell.take();
|
let wait_to_decode_port = wait_to_decode_port_cell.take();
|
||||||
fn~(data: &[u8], move wait_to_decode_port) -> Option<Image> {
|
fn~(data: &[u8]) -> Option<Image> {
|
||||||
// Don't decode until after the client requests the image
|
// Don't decode until after the client requests the image
|
||||||
wait_to_decode_port.recv();
|
wait_to_decode_port.recv();
|
||||||
load_from_memory(data)
|
load_from_memory(data)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let image_cache_task = ImageCacheTask_(mock_resource_task, move decoder_factory);
|
let image_cache_task = ImageCacheTask_(mock_resource_task, decoder_factory);
|
||||||
let url = make_url(~"file", None);
|
let url = make_url(~"file", None);
|
||||||
|
|
||||||
let wait_for_prefetech = comm::Port();
|
let wait_for_prefetech = comm::Port();
|
||||||
|
@ -924,7 +922,7 @@ fn should_return_not_ready_if_image_is_still_decoding() {
|
||||||
|
|
||||||
// Make the request
|
// Make the request
|
||||||
let (response_chan, response_port) = stream();
|
let (response_chan, response_port) = stream();
|
||||||
image_cache_task.send(GetImage(move url, move response_chan));
|
image_cache_task.send(GetImage(url, response_chan));
|
||||||
|
|
||||||
match response_port.recv() {
|
match response_port.recv() {
|
||||||
ImageNotReady => (),
|
ImageNotReady => (),
|
||||||
|
@ -968,7 +966,7 @@ fn should_return_failed_if_image_decode_fails() {
|
||||||
|
|
||||||
// Make the request
|
// Make the request
|
||||||
let (response_chan, response_port) = stream();
|
let (response_chan, response_port) = stream();
|
||||||
image_cache_task.send(GetImage(move url, move response_chan));
|
image_cache_task.send(GetImage(url, response_chan));
|
||||||
|
|
||||||
match response_port.recv() {
|
match response_port.recv() {
|
||||||
ImageFailed => (),
|
ImageFailed => (),
|
||||||
|
@ -1007,7 +1005,7 @@ fn should_return_image_on_wait_if_image_is_already_loaded() {
|
||||||
wait_for_decode.recv();
|
wait_for_decode.recv();
|
||||||
|
|
||||||
let (response_chan, response_port) = stream();
|
let (response_chan, response_port) = stream();
|
||||||
image_cache_task.send(WaitForImage(move url, move response_chan));
|
image_cache_task.send(WaitForImage(url, response_chan));
|
||||||
match response_port.recv() {
|
match response_port.recv() {
|
||||||
ImageReady(*) => (),
|
ImageReady(*) => (),
|
||||||
_ => fail
|
_ => fail
|
||||||
|
@ -1022,7 +1020,7 @@ fn should_return_image_on_wait_if_image_is_not_yet_loaded() {
|
||||||
|
|
||||||
let (wait_chan, wait_port) = pipes::stream();
|
let (wait_chan, wait_port) = pipes::stream();
|
||||||
|
|
||||||
let mock_resource_task = do mock_resource_task |response, move wait_port| {
|
let mock_resource_task = do mock_resource_task |response| {
|
||||||
wait_port.recv();
|
wait_port.recv();
|
||||||
response.send(resource_task::Payload(test_image_bin()));
|
response.send(resource_task::Payload(test_image_bin()));
|
||||||
response.send(resource_task::Done(result::Ok(())));
|
response.send(resource_task::Done(result::Ok(())));
|
||||||
|
@ -1035,7 +1033,7 @@ fn should_return_image_on_wait_if_image_is_not_yet_loaded() {
|
||||||
image_cache_task.send(Decode(copy url));
|
image_cache_task.send(Decode(copy url));
|
||||||
|
|
||||||
let (response_chan, response_port) = stream();
|
let (response_chan, response_port) = stream();
|
||||||
image_cache_task.send(WaitForImage(move url, move response_chan));
|
image_cache_task.send(WaitForImage(url, response_chan));
|
||||||
|
|
||||||
wait_chan.send(());
|
wait_chan.send(());
|
||||||
|
|
||||||
|
@ -1053,7 +1051,7 @@ fn should_return_image_failed_on_wait_if_image_fails_to_load() {
|
||||||
|
|
||||||
let (wait_chan, wait_port) = pipes::stream();
|
let (wait_chan, wait_port) = pipes::stream();
|
||||||
|
|
||||||
let mock_resource_task = do mock_resource_task |response, move wait_port| {
|
let mock_resource_task = do mock_resource_task |response| {
|
||||||
wait_port.recv();
|
wait_port.recv();
|
||||||
response.send(resource_task::Payload(test_image_bin()));
|
response.send(resource_task::Payload(test_image_bin()));
|
||||||
response.send(resource_task::Done(result::Err(())));
|
response.send(resource_task::Done(result::Err(())));
|
||||||
|
@ -1066,7 +1064,7 @@ fn should_return_image_failed_on_wait_if_image_fails_to_load() {
|
||||||
image_cache_task.send(Decode(copy url));
|
image_cache_task.send(Decode(copy url));
|
||||||
|
|
||||||
let (response_chan, response_port) = stream();
|
let (response_chan, response_port) = stream();
|
||||||
image_cache_task.send(WaitForImage(move url, move response_chan));
|
image_cache_task.send(WaitForImage(url, response_chan));
|
||||||
|
|
||||||
wait_chan.send(());
|
wait_chan.send(());
|
||||||
|
|
||||||
|
@ -1093,7 +1091,7 @@ fn sync_cache_should_wait_for_images() {
|
||||||
image_cache_task.send(Decode(copy url));
|
image_cache_task.send(Decode(copy url));
|
||||||
|
|
||||||
let (response_chan, response_port) = stream();
|
let (response_chan, response_port) = stream();
|
||||||
image_cache_task.send(GetImage(move url, move response_chan));
|
image_cache_task.send(GetImage(url, response_chan));
|
||||||
match response_port.recv() {
|
match response_port.recv() {
|
||||||
ImageReady(_) => (),
|
ImageReady(_) => (),
|
||||||
_ => fail
|
_ => fail
|
||||||
|
|
|
@ -13,7 +13,7 @@ use util::url::{UrlMap, url_map};
|
||||||
|
|
||||||
pub fn LocalImageCache(image_cache_task: ImageCacheTask) -> LocalImageCache {
|
pub fn LocalImageCache(image_cache_task: ImageCacheTask) -> LocalImageCache {
|
||||||
LocalImageCache {
|
LocalImageCache {
|
||||||
image_cache_task: move image_cache_task,
|
image_cache_task: image_cache_task,
|
||||||
round_number: 1,
|
round_number: 1,
|
||||||
mut on_image_available: None,
|
mut on_image_available: None,
|
||||||
state_map: url_map()
|
state_map: url_map()
|
||||||
|
@ -41,7 +41,7 @@ pub impl LocalImageCache {
|
||||||
// FIXME: 'pub' is an unexpected token?
|
// FIXME: 'pub' is an unexpected token?
|
||||||
/* pub */ fn next_round(on_image_available: @fn() -> ~fn(ImageResponseMsg)) {
|
/* pub */ fn next_round(on_image_available: @fn() -> ~fn(ImageResponseMsg)) {
|
||||||
self.round_number += 1;
|
self.round_number += 1;
|
||||||
self.on_image_available = Some(move on_image_available);
|
self.on_image_available = Some(on_image_available);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn prefetch(url: &Url) {
|
pub fn prefetch(url: &Url) {
|
||||||
|
@ -75,14 +75,14 @@ pub impl LocalImageCache {
|
||||||
unsafe {
|
unsafe {
|
||||||
let (port, chan) = pipes::stream();
|
let (port, chan) = pipes::stream();
|
||||||
chan.send(ImageReady(clone_arc(image)));
|
chan.send(ImageReady(clone_arc(image)));
|
||||||
return move port;
|
return port;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ImageNotReady => {
|
ImageNotReady => {
|
||||||
if last_round == self.round_number {
|
if last_round == self.round_number {
|
||||||
let (port, chan) = pipes::stream();
|
let (port, chan) = pipes::stream();
|
||||||
chan.send(ImageNotReady);
|
chan.send(ImageNotReady);
|
||||||
return move port;
|
return port;
|
||||||
} else {
|
} else {
|
||||||
// We haven't requested the image from the
|
// We haven't requested the image from the
|
||||||
// remote cache this round
|
// remote cache this round
|
||||||
|
@ -91,12 +91,12 @@ pub impl LocalImageCache {
|
||||||
ImageFailed => {
|
ImageFailed => {
|
||||||
let (port, chan) = pipes::stream();
|
let (port, chan) = pipes::stream();
|
||||||
chan.send(ImageFailed);
|
chan.send(ImageFailed);
|
||||||
return move port;
|
return port;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let (response_port, response_chan) = pipes::stream();
|
let (response_port, response_chan) = pipes::stream();
|
||||||
self.image_cache_task.send(GetImage(copy *url, move response_chan));
|
self.image_cache_task.send(GetImage(copy *url, response_chan));
|
||||||
|
|
||||||
let response = response_port.recv();
|
let response = response_port.recv();
|
||||||
match response {
|
match response {
|
||||||
|
@ -110,9 +110,9 @@ pub impl LocalImageCache {
|
||||||
assert self.on_image_available.is_some();
|
assert self.on_image_available.is_some();
|
||||||
let on_image_available = self.on_image_available.get()();
|
let on_image_available = self.on_image_available.get()();
|
||||||
let url = copy *url;
|
let url = copy *url;
|
||||||
do task::spawn |move url, move on_image_available, move image_cache_task| {
|
do task::spawn {
|
||||||
let (response_port, response_chan) = pipes::stream();
|
let (response_port, response_chan) = pipes::stream();
|
||||||
image_cache_task.send(WaitForImage(copy url, move response_chan));
|
image_cache_task.send(WaitForImage(copy url, response_chan));
|
||||||
on_image_available(response_port.recv());
|
on_image_available(response_port.recv());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -125,11 +125,11 @@ pub impl LocalImageCache {
|
||||||
ImageNotReady => ImageNotReady,
|
ImageNotReady => ImageNotReady,
|
||||||
ImageFailed => ImageFailed
|
ImageFailed => ImageFailed
|
||||||
};
|
};
|
||||||
state.last_response = move response_copy;
|
state.last_response = response_copy;
|
||||||
|
|
||||||
let (port, chan) = pipes::stream();
|
let (port, chan) = pipes::stream();
|
||||||
chan.send(move response);
|
chan.send(response);
|
||||||
return move port;
|
return port;
|
||||||
}
|
}
|
||||||
|
|
||||||
priv fn get_state(url: &Url) -> @ImageState {
|
priv fn get_state(url: &Url) -> @ImageState {
|
||||||
|
|
|
@ -47,7 +47,7 @@ pub fn ResourceTask() -> ResourceTask {
|
||||||
(~"file", file_loader_factory),
|
(~"file", file_loader_factory),
|
||||||
(~"http", http_loader_factory)
|
(~"http", http_loader_factory)
|
||||||
];
|
];
|
||||||
create_resource_task_with_loaders(move loaders)
|
create_resource_task_with_loaders(loaders)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_resource_task_with_loaders(loaders: ~[(~str, LoaderTaskFactory)]) -> ResourceTask {
|
fn create_resource_task_with_loaders(loaders: ~[(~str, LoaderTaskFactory)]) -> ResourceTask {
|
||||||
|
@ -69,8 +69,8 @@ pub struct ResourceManager {
|
||||||
pub fn ResourceManager(from_client: Port<ControlMsg>,
|
pub fn ResourceManager(from_client: Port<ControlMsg>,
|
||||||
loaders: ~[(~str, LoaderTaskFactory)]) -> ResourceManager {
|
loaders: ~[(~str, LoaderTaskFactory)]) -> ResourceManager {
|
||||||
ResourceManager {
|
ResourceManager {
|
||||||
from_client : move from_client,
|
from_client: from_client,
|
||||||
loaders : move loaders,
|
loaders: loaders,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,7 +94,7 @@ impl ResourceManager {
|
||||||
match self.get_loader_factory(&url) {
|
match self.get_loader_factory(&url) {
|
||||||
Some(loader_factory) => {
|
Some(loader_factory) => {
|
||||||
debug!("resource_task: loading url: %s", to_str(&url));
|
debug!("resource_task: loading url: %s", to_str(&url));
|
||||||
loader_factory(move url, progress_chan);
|
loader_factory(url, progress_chan);
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
debug!("resource_task: no loader for scheme %s", url.scheme);
|
debug!("resource_task: no loader for scheme %s", url.scheme);
|
||||||
|
@ -144,11 +144,11 @@ fn should_delegate_to_scheme_loader() {
|
||||||
progress_chan.send(Payload(copy payload));
|
progress_chan.send(Payload(copy payload));
|
||||||
progress_chan.send(Done(Ok(())));
|
progress_chan.send(Done(Ok(())));
|
||||||
};
|
};
|
||||||
let loader_factories = ~[(~"snicklefritz", move loader_factory)];
|
let loader_factories = ~[(~"snicklefritz", loader_factory)];
|
||||||
let resource_task = create_resource_task_with_loaders(move loader_factories);
|
let resource_task = create_resource_task_with_loaders(loader_factories);
|
||||||
let progress = Port();
|
let progress = Port();
|
||||||
resource_task.send(Load(url::from_str(~"snicklefritz://heya").get(), progress.chan()));
|
resource_task.send(Load(url::from_str(~"snicklefritz://heya").get(), progress.chan()));
|
||||||
assert progress.recv() == Payload(move payload);
|
assert progress.recv() == Payload(payload);
|
||||||
assert progress.recv() == Done(Ok(()));
|
assert progress.recv() == Done(Ok(()));
|
||||||
resource_task.send(Exit);
|
resource_task.send(Exit);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,10 +3,10 @@ use core::pipes;
|
||||||
|
|
||||||
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) = pipes::stream();
|
let (setup_po, setup_ch) = pipes::stream();
|
||||||
do task::spawn |move f| {
|
do task::spawn {
|
||||||
let (po, ch) = pipes::stream();
|
let (po, ch) = pipes::stream();
|
||||||
setup_ch.send(ch);
|
setup_ch.send(ch);
|
||||||
f(move po);
|
f(po);
|
||||||
}
|
}
|
||||||
setup_po.recv()
|
setup_po.recv()
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,26 +33,13 @@ pure fn GlyphEntry(value: u32) -> GlyphEntry { GlyphEntry { value: value } }
|
||||||
pub type GlyphIndex = u32;
|
pub type GlyphIndex = u32;
|
||||||
|
|
||||||
// TODO: unify with bit flags?
|
// TODO: unify with bit flags?
|
||||||
|
#[deriving_eq]
|
||||||
pub enum BreakType {
|
pub enum BreakType {
|
||||||
BreakTypeNone,
|
BreakTypeNone,
|
||||||
BreakTypeNormal,
|
BreakTypeNormal,
|
||||||
BreakTypeHyphen
|
BreakTypeHyphen
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BreakType : Eq {
|
|
||||||
pure fn eq(&self, other: &BreakType) -> bool {
|
|
||||||
match (*self, *other) {
|
|
||||||
(BreakTypeNone, BreakTypeNone) => true,
|
|
||||||
(BreakTypeNormal, BreakTypeNormal) => true,
|
|
||||||
(BreakTypeHyphen, BreakTypeHyphen) => true,
|
|
||||||
(_,_) => false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pure fn ne(&self, other: &BreakType) -> bool {
|
|
||||||
!(*self).eq(other)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const BREAK_TYPE_NONE : u8 = 0x0u8;
|
const BREAK_TYPE_NONE : u8 = 0x0u8;
|
||||||
const BREAK_TYPE_NORMAL : u8 = 0x1u8;
|
const BREAK_TYPE_NORMAL : u8 = 0x1u8;
|
||||||
const BREAK_TYPE_HYPHEN : u8 = 0x2u8;
|
const BREAK_TYPE_HYPHEN : u8 = 0x2u8;
|
||||||
|
@ -281,6 +268,7 @@ fn DetailedGlyph(index: GlyphIndex,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[deriving_eq]
|
||||||
struct DetailedGlyphRecord {
|
struct DetailedGlyphRecord {
|
||||||
// source string offset/GlyphEntry offset in the TextRun
|
// source string offset/GlyphEntry offset in the TextRun
|
||||||
entry_offset: uint,
|
entry_offset: uint,
|
||||||
|
@ -288,7 +276,7 @@ struct DetailedGlyphRecord {
|
||||||
detail_offset: uint
|
detail_offset: uint
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DetailedGlyphRecord : Ord {
|
impl Ord for DetailedGlyphRecord {
|
||||||
pure fn lt(&self, other: &DetailedGlyphRecord) -> bool {
|
pure fn lt(&self, other: &DetailedGlyphRecord) -> bool {
|
||||||
self.entry_offset < other.entry_offset
|
self.entry_offset < other.entry_offset
|
||||||
}
|
}
|
||||||
|
@ -303,15 +291,6 @@ impl DetailedGlyphRecord : Ord {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DetailedGlyphRecord : Eq {
|
|
||||||
pure fn eq(&self, other : &DetailedGlyphRecord) -> bool {
|
|
||||||
self.entry_offset == other.entry_offset
|
|
||||||
}
|
|
||||||
pure fn ne(&self, other : &DetailedGlyphRecord) -> bool {
|
|
||||||
self.entry_offset != other.entry_offset
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Manages the lookup table for detailed glyphs. Sorting is deferred
|
// Manages the lookup table for detailed glyphs. Sorting is deferred
|
||||||
// until a lookup is actually performed; this matches the expected
|
// until a lookup is actually performed; this matches the expected
|
||||||
// usage pattern of setting/appending all the detailed glyphs, and
|
// usage pattern of setting/appending all the detailed glyphs, and
|
||||||
|
@ -361,7 +340,7 @@ impl DetailedGlyphStore {
|
||||||
// FIXME: Is this right? --pcwalton
|
// FIXME: Is this right? --pcwalton
|
||||||
// TODO: should fix this somewhere else
|
// TODO: should fix this somewhere else
|
||||||
if count == 0 {
|
if count == 0 {
|
||||||
return vec::view(self.detail_buffer, 0, 0);
|
return vec::slice(self.detail_buffer, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
assert (count as uint) <= self.detail_buffer.len();
|
assert (count as uint) <= self.detail_buffer.len();
|
||||||
|
@ -378,8 +357,8 @@ impl DetailedGlyphStore {
|
||||||
None => fail!(~"Invalid index not found in detailed glyph lookup table!"),
|
None => fail!(~"Invalid index not found in detailed glyph lookup table!"),
|
||||||
Some(i) => {
|
Some(i) => {
|
||||||
assert i + (count as uint) <= self.detail_buffer.len();
|
assert i + (count as uint) <= self.detail_buffer.len();
|
||||||
// return a view into the buffer
|
// return a slice into the buffer
|
||||||
vec::view(self.detail_buffer, i, i + count as uint)
|
vec::slice(self.detail_buffer, i, i + count as uint)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -419,9 +398,9 @@ impl DetailedGlyphStore {
|
||||||
// Thar be dragons here. You have been warned. (Tips accepted.)
|
// Thar be dragons here. You have been warned. (Tips accepted.)
|
||||||
let mut unsorted_records : ~[DetailedGlyphRecord] = ~[];
|
let mut unsorted_records : ~[DetailedGlyphRecord] = ~[];
|
||||||
core::util::swap(&mut self.detail_lookup, &mut unsorted_records);
|
core::util::swap(&mut self.detail_lookup, &mut unsorted_records);
|
||||||
let mut_records : ~[mut DetailedGlyphRecord] = vec::cast_to_mut(move unsorted_records);
|
let mut_records : ~[mut DetailedGlyphRecord] = vec::cast_to_mut(unsorted_records);
|
||||||
sort::quick_sort3(mut_records);
|
sort::quick_sort3(mut_records);
|
||||||
let mut sorted_records = vec::cast_from_mut(move mut_records);
|
let mut sorted_records = vec::cast_from_mut(mut_records);
|
||||||
core::util::swap(&mut self.detail_lookup, &mut sorted_records);
|
core::util::swap(&mut self.detail_lookup, &mut sorted_records);
|
||||||
|
|
||||||
self.lookup_is_sorted = true;
|
self.lookup_is_sorted = true;
|
||||||
|
@ -601,13 +580,14 @@ pub impl GlyphStore {
|
||||||
match entry.is_simple() {
|
match entry.is_simple() {
|
||||||
true => {
|
true => {
|
||||||
let proxy = SimpleGlyphInfo(&self, i);
|
let proxy = SimpleGlyphInfo(&self, i);
|
||||||
cb(i, move proxy);
|
cb(i, proxy);
|
||||||
},
|
},
|
||||||
false => {
|
false => {
|
||||||
let glyphs = self.detail_store.get_detailed_glyphs_for_entry(i, entry.glyph_count());
|
let glyphs = self.detail_store.get_detailed_glyphs_for_entry(i,
|
||||||
|
entry.glyph_count());
|
||||||
for uint::range(0, glyphs.len()) |j| {
|
for uint::range(0, glyphs.len()) |j| {
|
||||||
let proxy = DetailGlyphInfo(&self, i, j as u16);
|
let proxy = DetailGlyphInfo(&self, i, j as u16);
|
||||||
cb(i, move proxy);
|
cb(i, proxy);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -135,7 +135,7 @@ pub impl ShapedGlyphData {
|
||||||
cluster: (*glyph_info_i).cluster as uint,
|
cluster: (*glyph_info_i).cluster as uint,
|
||||||
codepoint: (*glyph_info_i).codepoint as GlyphIndex,
|
codepoint: (*glyph_info_i).codepoint as GlyphIndex,
|
||||||
advance: x_advance,
|
advance: x_advance,
|
||||||
offset: move offset,
|
offset: offset,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -417,7 +417,7 @@ pub impl HarfbuzzShaper {
|
||||||
}
|
}
|
||||||
|
|
||||||
// now add the detailed glyph entry.
|
// now add the detailed glyph entry.
|
||||||
glyphs.add_glyphs_for_char_index(char_idx, dvec::unwrap(move datas));
|
glyphs.add_glyphs_for_char_index(char_idx, dvec::unwrap(datas));
|
||||||
|
|
||||||
// set the other chars, who have no glyphs
|
// set the other chars, who have no glyphs
|
||||||
let mut i = covered_byte_span.begin();
|
let mut i = covered_byte_span.begin();
|
||||||
|
|
|
@ -46,11 +46,11 @@ pub impl TextRun {
|
||||||
font.shape_text(text, &mut glyph_store);
|
font.shape_text(text, &mut glyph_store);
|
||||||
|
|
||||||
let run = TextRun {
|
let run = TextRun {
|
||||||
text: move text,
|
text: text,
|
||||||
font: font,
|
font: font,
|
||||||
glyphs: move glyph_store,
|
glyphs: glyph_store,
|
||||||
};
|
};
|
||||||
return move run;
|
return run;
|
||||||
}
|
}
|
||||||
|
|
||||||
static fn compute_potential_breaks(text: &str, glyphs: &mut GlyphStore) {
|
static fn compute_potential_breaks(text: &str, glyphs: &mut GlyphStore) {
|
||||||
|
|
|
@ -5,7 +5,7 @@ enum CompressionMode {
|
||||||
DiscardNewline
|
DiscardNewline
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CompressionMode : cmp::Eq {
|
impl Eq for CompressionMode {
|
||||||
pure fn eq(&self, other: &CompressionMode) -> bool {
|
pure fn eq(&self, other: &CompressionMode) -> bool {
|
||||||
match (*self, *other) {
|
match (*self, *other) {
|
||||||
(CompressNone, CompressNone) => true,
|
(CompressNone, CompressNone) => true,
|
||||||
|
@ -81,7 +81,7 @@ pub fn transform_text(text: &str, mode: CompressionMode) -> ~str {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return move out_str;
|
return out_str;
|
||||||
|
|
||||||
fn is_discardable_char(ch: char, mode: CompressionMode) -> bool {
|
fn is_discardable_char(ch: char, mode: CompressionMode) -> bool {
|
||||||
if is_always_discardable_char(ch) {
|
if is_always_discardable_char(ch) {
|
||||||
|
|
|
@ -12,7 +12,7 @@ pub struct MonoCache<K, V> {
|
||||||
mut entry: Option<(K,V)>,
|
mut entry: Option<(K,V)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub impl<K: Copy Eq, V: Copy> MonoCache<K,V> : Cache<K,V> {
|
pub impl<K: Copy Eq, V: Copy> Cache<K,V> for MonoCache<K,V> {
|
||||||
static fn new(_size: uint) -> MonoCache<K,V> {
|
static fn new(_size: uint) -> MonoCache<K,V> {
|
||||||
MonoCache { entry: None }
|
MonoCache { entry: None }
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,7 @@ pub impl<K: Copy Eq, V: Copy> MonoCache<K,V> : Cache<K,V> {
|
||||||
None => {
|
None => {
|
||||||
let value = blk(key);
|
let value = blk(key);
|
||||||
self.entry = Some((copy *key, copy value));
|
self.entry = Some((copy *key, copy value));
|
||||||
move value
|
value
|
||||||
},
|
},
|
||||||
Some(v) => v
|
Some(v) => v
|
||||||
};
|
};
|
||||||
|
|
|
@ -9,7 +9,7 @@ pub fn time<T>(msg: &str, callback: fn() -> T) -> T{
|
||||||
if ms >= 5 {
|
if ms >= 5 {
|
||||||
debug!("%s took %u ms", msg, ms);
|
debug!("%s took %u ms", msg, ms);
|
||||||
}
|
}
|
||||||
return move val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -28,13 +28,13 @@ pub fn make_url(str_url: ~str, current_url: Option<Url>) -> Url {
|
||||||
} else {
|
} else {
|
||||||
let path = str::split_char(current_url.path, '/');
|
let path = str::split_char(current_url.path, '/');
|
||||||
let path = path.init();
|
let path = path.init();
|
||||||
let path = str::connect(path + ~[move str_url], "/");
|
let path = str::connect(path + ~[str_url], "/");
|
||||||
|
|
||||||
current_url.scheme + "://" + current_url.host + path
|
current_url.scheme + "://" + current_url.host + path
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
move str_url
|
str_url
|
||||||
};
|
};
|
||||||
|
|
||||||
// FIXME: Need to handle errors
|
// FIXME: Need to handle errors
|
||||||
|
@ -46,7 +46,7 @@ mod make_url_tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn should_create_absolute_file_url_if_current_url_is_none_and_str_url_looks_filey() {
|
fn should_create_absolute_file_url_if_current_url_is_none_and_str_url_looks_filey() {
|
||||||
let file = ~"local.html";
|
let file = ~"local.html";
|
||||||
let url = make_url(move file, None);
|
let url = make_url(file, None);
|
||||||
debug!("url: %?", url);
|
debug!("url: %?", url);
|
||||||
assert url.scheme == ~"file";
|
assert url.scheme == ~"file";
|
||||||
assert url.path.contains(os::getcwd().to_str());
|
assert url.path.contains(os::getcwd().to_str());
|
||||||
|
@ -55,9 +55,9 @@ mod make_url_tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn should_create_url_based_on_old_url_1() {
|
fn should_create_url_based_on_old_url_1() {
|
||||||
let old_str = ~"http://example.com";
|
let old_str = ~"http://example.com";
|
||||||
let old_url = make_url(move old_str, None);
|
let old_url = make_url(old_str, None);
|
||||||
let new_str = ~"index.html";
|
let new_str = ~"index.html";
|
||||||
let new_url = make_url(move new_str, Some(move old_url));
|
let new_url = make_url(new_str, Some(old_url));
|
||||||
assert new_url.scheme == ~"http";
|
assert new_url.scheme == ~"http";
|
||||||
assert new_url.host == ~"example.com";
|
assert new_url.host == ~"example.com";
|
||||||
assert new_url.path == ~"/index.html";
|
assert new_url.path == ~"/index.html";
|
||||||
|
@ -66,9 +66,9 @@ mod make_url_tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn should_create_url_based_on_old_url_2() {
|
fn should_create_url_based_on_old_url_2() {
|
||||||
let old_str = ~"http://example.com/";
|
let old_str = ~"http://example.com/";
|
||||||
let old_url = make_url(move old_str, None);
|
let old_url = make_url(old_str, None);
|
||||||
let new_str = ~"index.html";
|
let new_str = ~"index.html";
|
||||||
let new_url = make_url(move new_str, Some(move old_url));
|
let new_url = make_url(new_str, Some(old_url));
|
||||||
assert new_url.scheme == ~"http";
|
assert new_url.scheme == ~"http";
|
||||||
assert new_url.host == ~"example.com";
|
assert new_url.host == ~"example.com";
|
||||||
assert new_url.path == ~"/index.html";
|
assert new_url.path == ~"/index.html";
|
||||||
|
@ -77,9 +77,9 @@ mod make_url_tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn should_create_url_based_on_old_url_3() {
|
fn should_create_url_based_on_old_url_3() {
|
||||||
let old_str = ~"http://example.com/index.html";
|
let old_str = ~"http://example.com/index.html";
|
||||||
let old_url = make_url(move old_str, None);
|
let old_url = make_url(old_str, None);
|
||||||
let new_str = ~"crumpet.html";
|
let new_str = ~"crumpet.html";
|
||||||
let new_url = make_url(move new_str, Some(move old_url));
|
let new_url = make_url(new_str, Some(old_url));
|
||||||
assert new_url.scheme == ~"http";
|
assert new_url.scheme == ~"http";
|
||||||
assert new_url.host == ~"example.com";
|
assert new_url.host == ~"example.com";
|
||||||
assert new_url.path == ~"/crumpet.html";
|
assert new_url.path == ~"/crumpet.html";
|
||||||
|
@ -88,9 +88,9 @@ mod make_url_tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn should_create_url_based_on_old_url_4() {
|
fn should_create_url_based_on_old_url_4() {
|
||||||
let old_str = ~"http://example.com/snarf/index.html";
|
let old_str = ~"http://example.com/snarf/index.html";
|
||||||
let old_url = make_url(move old_str, None);
|
let old_url = make_url(old_str, None);
|
||||||
let new_str = ~"crumpet.html";
|
let new_str = ~"crumpet.html";
|
||||||
let new_url = make_url(move new_str, Some(move old_url));
|
let new_url = make_url(new_str, Some(old_url));
|
||||||
assert new_url.scheme == ~"http";
|
assert new_url.scheme == ~"http";
|
||||||
assert new_url.host == ~"example.com";
|
assert new_url.host == ~"example.com";
|
||||||
assert new_url.path == ~"/snarf/crumpet.html";
|
assert new_url.path == ~"/snarf/crumpet.html";
|
||||||
|
|
|
@ -5,7 +5,7 @@ pub trait BinarySearchMethods<T: Ord Eq> {
|
||||||
pure fn binary_search_index(&self, key: &T) -> Option<uint>;
|
pure fn binary_search_index(&self, key: &T) -> Option<uint>;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub impl<T: Ord Eq> &[T]: BinarySearchMethods<T> {
|
pub impl<T: Ord Eq> BinarySearchMethods<T> for &[T] {
|
||||||
pure fn binary_search(&self, key: &T) -> Option<&self/T> {
|
pure fn binary_search(&self, key: &T) -> Option<&self/T> {
|
||||||
match self.binary_search_index(key) {
|
match self.binary_search_index(key) {
|
||||||
None => None,
|
None => None,
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 0beee76601f94c5601357c239e5e850266a47c2a
|
Subproject commit 0c2a999c2fc4b04a5580670343344e9fced91228
|
Loading…
Add table
Add a link
Reference in a new issue