Update to Rust 0.6.

This commit is contained in:
Jack Moffitt 2013-04-03 16:29:53 -06:00
parent b9f82b8d05
commit c850b59680
97 changed files with 1049 additions and 1135 deletions

View file

@ -230,6 +230,8 @@ package: servo
else
bindings: $(AUTOGEN_SRC_servo)
.PHONY: package
package:

@ -1 +1 @@
Subproject commit 95b4bd335549b74c4d50f34ecb074122572291ea
Subproject commit c6402195adc8830d4b2eba3f755044842edb3ae6

@ -1 +1 @@
Subproject commit 6fc47a3120d652e68522a0f1dfe85af0c7e23145
Subproject commit 19a4939e13f2387cb7831623480d91301092c202

@ -1 +1 @@
Subproject commit 0ad3a110be9070b87ecd7e1c71d20a02660d8959
Subproject commit 783392f70fcfd6770782796bef06bed47043cabf

@ -1 +1 @@
Subproject commit a016a795bb9a021c06a665563c4aaf793b0b97ca
Subproject commit 5fc77111bbb003fbcd9ba15e4813b31eccf6943c

@ -1 +1 @@
Subproject commit 252672fd902723cca59423a135c829a70a0b3f0b
Subproject commit 861292b11bd66a654286c3731e5d1054da4e5cc4

@ -1 +1 @@
Subproject commit c8cf6f388da1446b267014154b36af85a752a438
Subproject commit 12a7bb3fde3941be1050d46c495fb0fb23aa1880

@ -1 +1 @@
Subproject commit 363b2f0e6b064e7a6fbf850706fe62597af28f03
Subproject commit 2a69e1c0eeb30d659f784e00224647d6a40404df

@ -1 +1 @@
Subproject commit bc86ccb773758b3e2ad7f689b67f77165048b9e6
Subproject commit 12a5b33342fb0efdff9998838542026dd08f1fe9

@ -1 +1 @@
Subproject commit 97949ebdfd8adb13eea639f1799a3bbb93868512
Subproject commit 99d5af7047c219feaf7fa6d723dadfde0545b686

@ -1 +1 @@
Subproject commit 9f406c72c22fb68691d8d137df679a7d047ec135
Subproject commit 200034f493565ddfc12c8899b2615aa113a74521

@ -1 +1 @@
Subproject commit 260f7062a4cae7e3575a3cf97d1119bc076ab221
Subproject commit 2cdbb170c3591c08a872e30584fcaf490680a100

@ -1 +1 @@
Subproject commit b414d3bf445ac63860a9cf44532280228f001a2b
Subproject commit 6852c4a04e44d29dc410666ef551654a7e181d6c

@ -1 +1 @@
Subproject commit cdc1b0b8d173be4e1c79961742a367dac39d7d86
Subproject commit 89e5937773c265b0fd58ed0cedac777442f5c81c

@ -1 +1 @@
Subproject commit 337bc5cb49b2a518527d62cd9af08e169f4f6456
Subproject commit e094a0254778c042229ea031cb9f2b4821e5ed93

@ -1 +1 @@
Subproject commit e416f03f4898825bc8f24cfd890004a130e2457b
Subproject commit e1967e565616a973c4a4ab398cc31bb4142bf35a

@ -1 +1 @@
Subproject commit 886cf481cbf9c9eedfbab0344e5f887c11220497
Subproject commit 26b20203db925e11cb5885da15a236067398c1a6

@ -1 +1 @@
Subproject commit 8e04c939c72083fa311ea709f5aafeaccd83975d
Subproject commit 9045a321b5d40f604da0e3cd8920ef7d6e9e65a5

@ -1 +1 @@
Subproject commit 020deaffff282f36d8b1be8a98ee0e68f4a2b13b
Subproject commit 669971ff0424f9d298ffcdebf3510026cfb354e5

@ -1 +1 @@
Subproject commit 276a57d204f2d0ae74bda4ed76e63b830ca6332b
Subproject commit 92355d7224c16323c9d09b17ebcb340c6011e1e3

@ -1 +1 @@
Subproject commit 62558783027d1aaccb4e689d3ff5aed057a1f5f5
Subproject commit b6a306a26901ed7ce49f2b750c37972215c8ddaa

@ -1 +1 @@
Subproject commit 9b6d463d9045a90e6e3f31e35806af87e46e3852
Subproject commit 6770cdad275cd5c269955dd2ff844448d0947971

@ -1 +1 @@
Subproject commit 7e127420530640c7ec3c79883b702041dfe13b14
Subproject commit 942eac05bfd7397da0c8f9f92280bea4cf6021c4

@ -1 +1 @@
Subproject commit 06b790f226819e30c59b35523407bc671fe4d2ca
Subproject commit fd38ef064bbac1444079a5262922c7bb73311216

@ -1 +1 @@
Subproject commit ce75a42685824a4c3c63a638a2c76762b7fac813
Subproject commit 6a8f6677d38a8d2e85850971ef3e578a550ed6de

@ -1 +1 @@
Subproject commit c8328148ec5d1ec4fb8a496a41e34badf53e7f88
Subproject commit 754ac8e774d9ac7b8577b6a0b775a54e1f00a262

View file

@ -5,7 +5,6 @@ use render_context::RenderContext;
use text::SendableTextRun;
use util::range::Range;
use azure::azure_hl::DrawTarget;
use clone_arc = std::arc::clone;
use geom::Rect;
use geom::Point2D;
@ -15,8 +14,8 @@ struct DisplayItemData {
bounds : Rect<Au>, // TODO: whose coordinate system should this use?
}
impl DisplayItemData {
static pure fn new(bounds: &Rect<Au>) -> DisplayItemData {
pub impl DisplayItemData {
fn new(bounds: &Rect<Au>) -> DisplayItemData {
DisplayItemData { bounds: copy *bounds }
}
}
@ -31,8 +30,8 @@ pub enum DisplayItem {
Border(DisplayItemData, Au, Color)
}
impl DisplayItem {
pure fn d(&self) -> &self/DisplayItemData {
pub impl DisplayItem {
fn d(&self) -> &'self DisplayItemData {
match *self {
SolidColor(ref d, _) => d,
Text(ref d, _, _, _) => d,
@ -68,23 +67,23 @@ impl DisplayItem {
() });
}
static pure fn new_SolidColor(bounds: &Rect<Au>, color: Color) -> DisplayItem {
fn new_SolidColor(bounds: &Rect<Au>, color: Color) -> DisplayItem {
SolidColor(DisplayItemData::new(bounds), color)
}
static pure fn new_Border(bounds: &Rect<Au>, width: Au, color: Color) -> DisplayItem {
fn new_Border(bounds: &Rect<Au>, width: Au, color: Color) -> DisplayItem {
Border(DisplayItemData::new(bounds), width, color)
}
static pure fn new_Text(bounds: &Rect<Au>,
run: ~SendableTextRun,
range: Range,
color: Color) -> DisplayItem {
fn new_Text(bounds: &Rect<Au>,
run: ~SendableTextRun,
range: Range,
color: Color) -> DisplayItem {
Text(DisplayItemData::new(bounds), run, range, color)
}
// ARC should be cloned into ImageData, but Images are not sendable
static pure fn new_Image(bounds: &Rect<Au>, image: ARC<~Image>) -> DisplayItem {
fn new_Image(bounds: &Rect<Au>, image: ARC<~Image>) -> DisplayItem {
Image(DisplayItemData::new(bounds), image)
}
}
@ -95,7 +94,7 @@ pub struct DisplayList {
}
pub impl DisplayList {
static fn new() -> DisplayList {
fn new() -> DisplayList {
DisplayList { list: ~[] }
}

View file

@ -8,8 +8,7 @@ use text::shaper::ShaperMethods;
use text::{Shaper, TextRun};
use text::shaper::ShaperMethods;
use azure::{AzFloat, AzScaledFontRef, struct__AzDrawOptions, struct__AzGlyph};
use azure::{struct__AzGlyphBuffer, struct__AzPoint};
use azure::{AzFloat, AzScaledFontRef};
use azure::scaled_font::ScaledFont;
use azure::azure_hl::{BackendType, ColorPattern};
use geom::{Point2D, Rect, Size2D};
@ -26,18 +25,18 @@ use native;
// resources needed by the graphics layer to draw glyphs.
#[cfg(target_os = "macos")]
pub type FontHandle/& = quartz::font::QuartzFontHandle;
pub type FontHandle = quartz::font::QuartzFontHandle;
#[cfg(target_os = "linux")]
pub type FontHandle/& = freetype_impl::font::FreeTypeFontHandle;
pub type FontHandle = freetype_impl::font::FreeTypeFontHandle;
pub trait FontHandleMethods {
// an identifier usable by FontContextHandle to recreate this FontHandle.
pure fn face_identifier(&self) -> ~str;
pure fn family_name(&self) -> ~str;
pure fn face_name(&self) -> ~str;
pure fn is_italic(&self) -> bool;
pure fn boldness(&self) -> CSSFontWeight;
fn face_identifier(&self) -> ~str;
fn family_name(&self) -> ~str;
fn face_name(&self) -> ~str;
fn is_italic(&self) -> bool;
fn boldness(&self) -> CSSFontWeight;
fn clone_with_style(&self, fctx: &native::FontContextHandle, style: &UsedFontStyle) -> Result<FontHandle, ()>;
fn glyph_index(&self, codepoint: char) -> Option<GlyphIndex>;
@ -53,18 +52,18 @@ pub trait FontHandleMethods {
pub impl FontHandle {
#[cfg(target_os = "macos")]
static pub fn new_from_buffer(fctx: &native::FontContextHandle,
buf: ~[u8],
style: &SpecifiedFontStyle)
-> Result<FontHandle, ()> {
pub fn new_from_buffer(fctx: &native::FontContextHandle,
buf: ~[u8],
style: &SpecifiedFontStyle)
-> Result<FontHandle, ()> {
quartz::font::QuartzFontHandle::new_from_buffer(fctx, buf, style)
}
#[cfg(target_os = "linux")]
static pub fn new_from_buffer(fctx: &native::FontContextHandle,
buf: ~[u8],
style: &SpecifiedFontStyle)
-> Result<FontHandle, ()> {
pub fn new_from_buffer(fctx: &native::FontContextHandle,
buf: ~[u8],
style: &SpecifiedFontStyle)
-> Result<FontHandle, ()> {
freetype_impl::font::FreeTypeFontHandle::new_from_buffer(fctx, @buf, style)
}
}
@ -75,11 +74,11 @@ pub type FractionalPixel = float;
pub type FontTableTag = u32;
trait FontTableTagConversions {
pub pure fn tag_to_str(&self) -> ~str;
pub fn tag_to_str(&self) -> ~str;
}
impl FontTableTagConversions for FontTableTag {
pub pure fn tag_to_str(&self) -> ~str {
pub fn tag_to_str(&self) -> ~str {
unsafe {
let reversed = str::raw::from_buf_len(cast::transmute(self), 4);
return str::from_chars([reversed.char_at(3),
@ -91,10 +90,10 @@ impl FontTableTagConversions for FontTableTag {
}
#[cfg(target_os = "macos")]
pub type FontTable/& = quartz::font::QuartzFontTable;
pub type FontTable = quartz::font::QuartzFontTable;
#[cfg(target_os = "linux")]
pub type FontTable/& = freetype_impl::font::FreeTypeFontTable;
pub type FontTable = freetype_impl::font::FreeTypeFontTable;
pub trait FontTableMethods {
fn with_buffer(&self, &fn(*u8, uint));
@ -112,7 +111,7 @@ pub struct FontMetrics {
}
// TODO(Issue #200): use enum from CSS bindings for 'font-weight'
#[deriving_eq]
#[deriving(Eq)]
pub enum CSSFontWeight {
FontWeight100,
FontWeight200,
@ -126,7 +125,7 @@ pub enum CSSFontWeight {
}
pub impl CSSFontWeight {
pub pure fn is_bold(self) -> bool {
pub fn is_bold(self) -> bool {
match self {
FontWeight900 | FontWeight800 | FontWeight700 | FontWeight600 => true,
_ => false
@ -140,7 +139,7 @@ pub impl CSSFontWeight {
// the instance's properties.
//
// For now, the cases are differentiated with a typedef
#[deriving_eq]
#[deriving(Eq)]
pub struct FontStyle {
pt_size: float,
weight: CSSFontWeight,
@ -165,14 +164,14 @@ struct ResolvedFont {
// It's used to swizzle/unswizzle gfx::Font instances when
// communicating across tasks, such as the display list between layout
// and render tasks.
#[deriving_eq]
#[deriving(Eq)]
pub struct FontDescriptor {
style: UsedFontStyle,
selector: FontSelector,
}
pub impl FontDescriptor {
static pure fn new(style: UsedFontStyle, selector: FontSelector) -> FontDescriptor {
fn new(style: UsedFontStyle, selector: FontSelector) -> FontDescriptor {
FontDescriptor {
style: style,
selector: selector,
@ -181,7 +180,7 @@ pub impl FontDescriptor {
}
// A FontSelector is a platform-specific strategy for serializing face names.
#[deriving_eq]
#[deriving(Eq)]
pub enum FontSelector {
SelectorPlatformIdentifier(~str),
SelectorStubDummy, // aka, use Josephin Sans
@ -203,7 +202,7 @@ pub struct FontGroup {
}
pub impl FontGroup {
static fn new(families: @str, style: &UsedFontStyle, fonts: ~[@mut Font]) -> FontGroup {
fn new(families: @str, style: &UsedFontStyle, fonts: ~[@mut Font]) -> FontGroup {
FontGroup {
families: families,
style: copy *style,
@ -212,7 +211,7 @@ pub impl FontGroup {
}
fn create_textrun(&self, text: ~str) -> TextRun {
fail_unless!(self.fonts.len() > 0);
assert!(self.fonts.len() > 0);
// TODO(Issue #177): Actually fall back through the FontGroup when a font is unsuitable.
return TextRun::new(self.fonts[0], text);
@ -243,11 +242,11 @@ pub struct Font {
}
pub impl Font {
static fn new_from_buffer(ctx: &FontContext,
buffer: ~[u8],
style: &SpecifiedFontStyle,
backend: BackendType)
-> Result<@mut Font, ()> {
fn new_from_buffer(ctx: &FontContext,
buffer: ~[u8],
style: &SpecifiedFontStyle,
backend: BackendType)
-> Result<@mut Font, ()> {
let handle = FontHandle::new_from_buffer(&ctx.handle, buffer, style);
let handle = if handle.is_ok() {
result::unwrap(handle)
@ -268,8 +267,8 @@ pub impl Font {
});
}
static fn new_from_adopted_handle(_fctx: &FontContext, handle: FontHandle,
style: &SpecifiedFontStyle, backend: BackendType) -> @mut Font {
fn new_from_adopted_handle(_fctx: &FontContext, handle: FontHandle,
style: &SpecifiedFontStyle, backend: BackendType) -> @mut Font {
let metrics = handle.get_metrics();
@mut Font {
@ -282,8 +281,8 @@ pub impl Font {
}
}
static fn new_from_existing_handle(fctx: &FontContext, handle: &FontHandle,
style: &SpecifiedFontStyle, backend: BackendType) -> Result<@mut Font,()> {
fn new_from_existing_handle(fctx: &FontContext, handle: &FontHandle,
style: &SpecifiedFontStyle, backend: BackendType) -> Result<@mut Font,()> {
// TODO(Issue #179): convert between specified and used font style here?
let styled_handle = match handle.clone_with_style(&fctx.handle, style) {
@ -334,7 +333,7 @@ pub impl Font {
}
#[cfg(target_os="macos")]
priv fn create_azure_font() -> ScaledFont {
priv fn create_azure_font(&mut self) -> ScaledFont {
let cg_font = self.handle.get_CGFont();
let size = self.style.pt_size as AzFloat;
ScaledFont::new(self.backend, &cg_font, size)
@ -353,26 +352,21 @@ pub impl Font {
fn draw_text_into_context(&mut self,
rctx: &RenderContext,
run: &TextRun,
range: &const Range,
range: &Range,
baseline_origin: Point2D<Au>,
color: Color) {
use core::libc::types::common::c99::{uint16_t, uint32_t};
use azure::{AzDrawOptions,
struct__AzDrawOptions,
AzGlyph,
use azure::{struct__AzDrawOptions,
struct__AzGlyph,
AzGlyphBuffer,
struct__AzGlyphBuffer,
struct__AzPoint};
use azure::azure::bindgen::{AzCreateColorPattern};
use azure::azure::bindgen::{AzDrawTargetFillGlyphs};
use azure::azure::bindgen::{AzReleaseColorPattern};
let target = rctx.get_draw_target();
let azfontref = self.get_azure_font();
let pattern = ColorPattern(color);
let azure_pattern = pattern.azure_color_pattern;
fail_unless!(azure_pattern.is_not_null());
assert!(azure_pattern.is_not_null());
let options = struct__AzDrawOptions {
mAlpha: 1f as AzFloat,
@ -417,7 +411,7 @@ pub impl Font {
ptr::null());
}
fn measure_text(&self, run: &TextRun, range: &const Range) -> RunMetrics {
fn measure_text(&self, run: &TextRun, range: &Range) -> RunMetrics {
// TODO(Issue #199): alter advance direction for RTL
// TODO(Issue #98): using inter-char and inter-word spacing settings when measuring text
let mut advance = Au(0);
@ -479,7 +473,7 @@ fn should_get_glyph_indexes() {
let matcher = @FontMatcher(fctx);
let font = matcher.get_test_font();
let glyph_idx = font.glyph_index('w');
fail_unless!(glyph_idx == Some(40u as GlyphIndex));
assert!(glyph_idx == Some(40u as GlyphIndex));
}
fn should_get_glyph_advance() {
@ -490,7 +484,7 @@ fn should_get_glyph_advance() {
let matcher = @FontMatcher(fctx);
let font = matcher.get_test_font();
let x = font.glyph_h_advance(40u as GlyphIndex);
fail_unless!(x == 15f || x == 16f);
assert!(x == 15f || x == 16f);
}
// Testing thread safety
@ -508,7 +502,7 @@ fn should_get_glyph_advance_stress() {
let matcher = @FontMatcher(fctx);
let _font = matcher.get_test_font();
let x = font.glyph_h_advance(40u as GlyphIndex);
fail_unless!(x == 15f || x == 16f);
assert!(x == 15f || x == 16f);
chan.send(());
}
}

View file

@ -6,8 +6,7 @@ use util::cache::Cache;
use util::cache::MonoCache;
use azure::azure_hl::BackendType;
use core::hashmap::linear::LinearMap;
use core::hashmap::linear;
use core::hashmap::HashMap;
#[cfg(target_os = "macos")]
use quartz;
@ -16,7 +15,7 @@ use freetype_impl;
use font_context;
// TODO(Issue #164): delete, and get default font from font list
const TEST_FONT: [u8 * 33004] = include_bin!("JosefinSans-SemiBold.ttf");
static TEST_FONT: [u8, ..33004] = include_bin!("JosefinSans-SemiBold.ttf");
fn test_font_bin() -> ~[u8] {
return vec::from_fn(33004, |i| TEST_FONT[i]);
@ -36,13 +35,13 @@ pub fn dummy_style() -> FontStyle {
}
#[cfg(target_os = "macos")]
type FontContextHandle/& = quartz::font_context::QuartzFontContextHandle;
type FontContextHandle = quartz::font_context::QuartzFontContextHandle;
#[cfg(target_os = "linux")]
type FontContextHandle/& = freetype_impl::font_context::FreeTypeFontContextHandle;
type FontContextHandle = freetype_impl::font_context::FreeTypeFontContextHandle;
pub trait FontContextHandleMethods {
pure fn clone(&const self) -> FontContextHandle;
fn clone(&self) -> FontContextHandle;
fn create_font_from_identifier(&self, ~str, UsedFontStyle) -> Result<FontHandle, ()>;
}
@ -50,12 +49,12 @@ pub trait FontContextHandleMethods {
// and typedefs not working well together. It should be removed.
pub impl FontContextHandle {
#[cfg(target_os = "macos")]
static pub fn new() -> FontContextHandle {
pub fn new() -> FontContextHandle {
quartz::font_context::QuartzFontContextHandle::new()
}
#[cfg(target_os = "linux")]
static pub fn new() -> FontContextHandle {
pub fn new() -> FontContextHandle {
freetype_impl::font_context::FreeTypeFontContextHandle::new()
}
}
@ -66,17 +65,17 @@ pub struct FontContext {
font_list: Option<FontList>, // only needed by layout
handle: FontContextHandle,
backend: BackendType,
generic_fonts: LinearMap<~str,~str>,
generic_fonts: HashMap<~str,~str>,
}
#[allow(non_implicitly_copyable_typarams)]
pub impl FontContext {
static fn new(backend: BackendType, needs_font_list: bool) -> FontContext {
pub impl<'self> FontContext {
fn new(backend: BackendType, needs_font_list: bool) -> FontContext {
let handle = FontContextHandle::new();
let font_list = if needs_font_list { Some(FontList::new(&handle)) } else { None };
// TODO: Allow users to specify these.
let mut generic_fonts = linear::linear_map_with_capacity(5);
let mut generic_fonts = HashMap::with_capacity(5);
generic_fonts.insert(~"serif", ~"Times New Roman");
generic_fonts.insert(~"sans-serif", ~"Arial");
generic_fonts.insert(~"cursive", ~"Apple Chancery");
@ -94,11 +93,11 @@ pub impl FontContext {
}
}
priv pure fn get_font_list(&self) -> &self/FontList {
option::get_ref(&self.font_list)
priv fn get_font_list(&self) -> &'self FontList {
self.font_list.get_ref()
}
fn get_resolved_font_for_style(&mut self, style: &SpecifiedFontStyle) -> @FontGroup {
fn get_resolved_font_for_style(@mut self, style: &SpecifiedFontStyle) -> @FontGroup {
// TODO(Issue #178, E): implement a cache of FontGroup instances.
self.create_font_group(style)
}
@ -119,7 +118,7 @@ pub impl FontContext {
}
priv fn transform_family(&self, family: &str) -> ~str {
// FIXME: Need a find_like() in LinearMap.
// FIXME: Need a find_like() in HashMap.
let family = family.to_str();
debug!("(transform family) searching for `%s`", family);
match self.generic_fonts.find(&family) {
@ -129,13 +128,13 @@ pub impl FontContext {
}
// TODO:(Issue #196): cache font groups on the font context.
priv fn create_font_group(&mut self, style: &SpecifiedFontStyle) -> @FontGroup {
priv fn create_font_group(@mut self, style: &SpecifiedFontStyle) -> @FontGroup {
let mut fonts = ~[];
debug!("(create font group) --- starting ---");
// TODO(Issue #193): make iteration over 'font-family' more robust.
for str::split_char_each(style.families, ',') |family| {
for str::each_split_char(style.families, ',') |family| {
let family_name = str::trim(family);
let transformed_family_name = self.transform_family(family_name);
debug!("(create font group) transformed family is `%s`", transformed_family_name);
@ -168,7 +167,7 @@ pub impl FontContext {
Err(()) => {}
}
}
fail_unless!(fonts.len() > 0);
assert!(fonts.len() > 0);
// TODO(Issue #179): Split FontStyle into specified and used styles
let used_style = copy *style;

View file

@ -1,9 +1,9 @@
use font::{CSSFontWeight, SpecifiedFontStyle, UsedFontStyle};
use font::{CSSFontWeight, SpecifiedFontStyle};
use gfx_font::FontHandleMethods;
use native::FontHandle;
use gfx_font::FontHandleMethods;
use core::hashmap::linear;
use core::hashmap::HashMap;
#[cfg(target_os = "linux")]
use fontconfig;
@ -13,28 +13,28 @@ use native;
use util::time::time;
#[cfg(target_os = "macos")]
type FontListHandle/& = quartz::font_list::QuartzFontListHandle;
type FontListHandle = quartz::font_list::QuartzFontListHandle;
#[cfg(target_os = "linux")]
type FontListHandle/& = fontconfig::font_list::FontconfigFontListHandle;
type FontListHandle = fontconfig::font_list::FontconfigFontListHandle;
pub impl FontListHandle {
#[cfg(target_os = "macos")]
static pub fn new(fctx: &native::FontContextHandle) -> Result<FontListHandle, ()> {
pub fn new(fctx: &native::FontContextHandle) -> Result<FontListHandle, ()> {
Ok(quartz::font_list::QuartzFontListHandle::new(fctx))
}
#[cfg(target_os = "linux")]
static pub fn new(fctx: &native::FontContextHandle) -> Result<FontListHandle, ()> {
pub fn new(fctx: &native::FontContextHandle) -> Result<FontListHandle, ()> {
Ok(fontconfig::font_list::FontconfigFontListHandle::new(fctx))
}
}
pub type FontFamilyMap = linear::LinearMap<~str, @mut FontFamily>;
pub type FontFamilyMap = HashMap<~str, @mut FontFamily>;
trait FontListHandleMethods {
fn get_available_families(&const self, fctx: &native::FontContextHandle) -> FontFamilyMap;
fn load_variations_for_family(&const self, family: @mut FontFamily);
fn get_available_families(&self, fctx: &native::FontContextHandle) -> FontFamilyMap;
fn load_variations_for_family(&self, family: @mut FontFamily);
}
pub struct FontList {
@ -43,11 +43,11 @@ pub struct FontList {
}
pub impl FontList {
static fn new(fctx: &native::FontContextHandle) -> FontList {
fn new(fctx: &native::FontContextHandle) -> FontList {
let handle = result::unwrap(FontListHandle::new(fctx));
let mut list = FontList {
handle: handle,
family_map: linear::LinearMap::new(),
family_map: HashMap::new(),
};
list.refresh(fctx);
return list;
@ -90,7 +90,7 @@ pub impl FontList {
debug!("FontList: %s font family with name=%s", decision, family_name);
// TODO(Issue #188): look up localized font family names if canonical name not found
return family.map(|f| **f);
family.map(|f| **f)
}
}
@ -101,7 +101,7 @@ pub struct FontFamily {
}
pub impl FontFamily {
static fn new(family_name: &str) -> FontFamily {
fn new(family_name: &str) -> FontFamily {
FontFamily {
family_name: str::from_slice(family_name),
entries: ~[],
@ -109,9 +109,10 @@ pub impl FontFamily {
}
priv fn load_family_variations(@mut self, list: &native::FontListHandle) {
if self.entries.len() > 0 { return; }
let this : &mut FontFamily = self; // FIXME: borrow checker workaround
if this.entries.len() > 0 { return; }
list.load_variations_for_family(self);
fail_unless!(self.entries.len() > 0);
assert!(this.entries.len() > 0);
}
fn find_font_for_style(@mut self, list: &native::FontListHandle, style: &SpecifiedFontStyle) -> Option<@FontEntry> {
@ -124,7 +125,8 @@ pub impl FontFamily {
// TODO(Issue #190): if not in the fast path above, do
// expensive matching of weights, etc.
for self.entries.each |entry| {
let this : &mut FontFamily = self; // FIXME: borrow checker workaround
for this.entries.each |entry| {
if (style.weight.is_bold() == entry.is_bold()) &&
(style.italic == entry.is_italic()) {
@ -151,7 +153,7 @@ pub struct FontEntry {
}
pub impl FontEntry {
static fn new(family: @mut FontFamily, handle: FontHandle) -> FontEntry {
fn new(family: @mut FontFamily, handle: FontHandle) -> FontEntry {
FontEntry {
family: family,
face_name: handle.face_name(),
@ -161,9 +163,9 @@ pub impl FontEntry {
}
}
pure fn is_bold(&self) -> bool {
fn is_bold(&self) -> bool {
self.weight.is_bold()
}
pure fn is_italic(&self) -> bool { self.italic }
fn is_italic(&self) -> bool { self.italic }
}

View file

@ -29,7 +29,7 @@ pub struct FontconfigFontListHandle {
}
pub impl FontconfigFontListHandle {
static pub fn new(fctx: &native::FontContextHandle) -> FontconfigFontListHandle {
pub fn new(fctx: &native::FontContextHandle) -> FontconfigFontListHandle {
FontconfigFontListHandle { fctx: fctx.clone() }
}

View file

@ -100,7 +100,7 @@ impl Drop for FreeTypeFontHandle {
}
pub impl FreeTypeFontHandle {
static priv fn set_char_size(face: FT_Face, pt_size: float) -> Result<(), ()>{
priv fn set_char_size(face: FT_Face, pt_size: float) -> Result<(), ()>{
let char_width = float_to_fixed_ft(pt_size) as FT_F26Dot6;
let char_height = float_to_fixed_ft(pt_size) as FT_F26Dot6;
let h_dpi = 72;
@ -110,8 +110,8 @@ pub impl FreeTypeFontHandle {
if result.succeeded() { Ok(()) } else { Err(()) }
}
static pub fn new_from_file(fctx: &FreeTypeFontContextHandle, file: ~str,
style: &SpecifiedFontStyle) -> Result<FreeTypeFontHandle, ()> {
pub fn new_from_file(fctx: &FreeTypeFontContextHandle, file: ~str,
style: &SpecifiedFontStyle) -> Result<FreeTypeFontHandle, ()> {
let ft_ctx: FT_Library = fctx.ctx.ctx;
if ft_ctx.is_null() { return Err(()); }
@ -131,7 +131,7 @@ pub impl FreeTypeFontHandle {
}
}
static pub fn new_from_file_unstyled(fctx: &FreeTypeFontContextHandle, file: ~str)
pub fn new_from_file_unstyled(fctx: &FreeTypeFontContextHandle, file: ~str)
-> Result<FreeTypeFontHandle, ()> {
let ft_ctx: FT_Library = fctx.ctx.ctx;
if ft_ctx.is_null() { return Err(()); }
@ -149,8 +149,8 @@ pub impl FreeTypeFontHandle {
Ok(FreeTypeFontHandle { source: FontSourceFile(file), face: face })
}
static pub fn new_from_buffer(fctx: &FreeTypeFontContextHandle,
buf: @~[u8], style: &SpecifiedFontStyle) -> Result<FreeTypeFontHandle, ()> {
pub fn new_from_buffer(fctx: &FreeTypeFontContextHandle,
buf: @~[u8], style: &SpecifiedFontStyle) -> Result<FreeTypeFontHandle, ()> {
let ft_ctx: FT_Library = fctx.ctx.ctx;
if ft_ctx.is_null() { return Err(()); }
@ -189,21 +189,21 @@ pub impl FreeTypeFontHandle {
impl FontHandleMethods for FreeTypeFontHandle {
// an identifier usable by FontContextHandle to recreate this FontHandle.
pure fn face_identifier(&self) -> ~str {
fn face_identifier(&self) -> ~str {
/* FT_Get_Postscript_Name seems like a better choice here, but it
doesn't give usable results for fontconfig when deserializing. */
unsafe { str::raw::from_c_str((*self.face).family_name) }
}
pure fn family_name(&self) -> ~str {
fn family_name(&self) -> ~str {
unsafe { str::raw::from_c_str((*self.face).family_name) }
}
pure fn face_name(&self) -> ~str {
fn face_name(&self) -> ~str {
unsafe { str::raw::from_c_str(FT_Get_Postscript_Name(self.face)) }
}
pure fn is_italic(&self) -> bool {
fn is_italic(&self) -> bool {
unsafe { (*self.face).style_flags & FT_STYLE_FLAG_ITALIC != 0 }
}
pure fn boldness(&self) -> CSSFontWeight {
fn boldness(&self) -> CSSFontWeight {
let default_weight = FontWeight400;
if unsafe { (*self.face).style_flags & FT_STYLE_FLAG_BOLD == 0 } {
default_weight
@ -305,7 +305,7 @@ impl FontHandleMethods for FreeTypeFontHandle {
}
pub impl FreeTypeFontHandle {
priv fn get_face_rec(&self) -> &self/FT_FaceRec {
priv fn get_face_rec(&self) -> &'self FT_FaceRec {
unsafe {
&(*self.face)
}

View file

@ -35,7 +35,7 @@ pub struct FreeTypeFontContextHandle {
}
pub impl FreeTypeFontContextHandle {
static pub fn new() -> FreeTypeFontContextHandle {
pub fn new() -> FreeTypeFontContextHandle {
let ctx: FT_Library = ptr::null();
let result = FT_Init_FreeType(ptr::to_unsafe_ptr(&ctx));
if !result.succeeded() { fail!(); }
@ -47,7 +47,7 @@ pub impl FreeTypeFontContextHandle {
}
impl FontContextHandleMethods for FreeTypeFontContextHandle {
pure fn clone(&const self) -> FreeTypeFontContextHandle {
fn clone(&self) -> FreeTypeFontContextHandle {
FreeTypeFontContextHandle { ctx: self.ctx }
}

View file

@ -7,62 +7,62 @@ use core::num::NumCast;
pub struct Au(i32);
impl Add<Au,Au> for Au {
pure fn add(&self, other: &Au) -> Au { Au(**self + **other) }
fn add(&self, other: &Au) -> Au { Au(**self + **other) }
}
impl Sub<Au,Au> for Au {
pure fn sub(&self, other: &Au) -> Au { Au(**self - **other) }
fn sub(&self, other: &Au) -> Au { Au(**self - **other) }
}
impl Mul<Au,Au> for Au {
pure fn mul(&self, other: &Au) -> Au { Au(**self * **other) }
fn mul(&self, other: &Au) -> Au { Au(**self * **other) }
}
impl Div<Au,Au> for Au {
pure fn div(&self, other: &Au) -> Au { Au(**self / **other) }
fn div(&self, other: &Au) -> Au { Au(**self / **other) }
}
impl Modulo<Au,Au> for Au {
pure fn modulo(&self, other: &Au) -> Au { Au(**self % **other) }
fn modulo(&self, other: &Au) -> Au { Au(**self % **other) }
}
impl Neg<Au> for Au {
pure fn neg(&self) -> Au { Au(-**self) }
fn neg(&self) -> Au { Au(-**self) }
}
impl cmp::Ord for Au {
pure fn lt(&self, other: &Au) -> bool { **self < **other }
pure fn le(&self, other: &Au) -> bool { **self <= **other }
pure fn ge(&self, other: &Au) -> bool { **self >= **other }
pure fn gt(&self, other: &Au) -> bool { **self > **other }
fn lt(&self, other: &Au) -> bool { **self < **other }
fn le(&self, other: &Au) -> bool { **self <= **other }
fn ge(&self, other: &Au) -> bool { **self >= **other }
fn gt(&self, other: &Au) -> bool { **self > **other }
}
impl cmp::Eq for Au {
pure fn eq(&self, other: &Au) -> bool { **self == **other }
pure fn ne(&self, other: &Au) -> bool { **self != **other }
fn eq(&self, other: &Au) -> bool { **self == **other }
fn ne(&self, other: &Au) -> bool { **self != **other }
}
pub pure fn min(x: Au, y: Au) -> Au { if x < y { x } else { y } }
pub pure fn max(x: Au, y: Au) -> Au { if x > y { x } else { y } }
pub fn min(x: Au, y: Au) -> Au { if x < y { x } else { y } }
pub fn max(x: Au, y: Au) -> Au { if x > y { x } else { y } }
impl NumCast for Au {
static pure fn from<T:NumCast>(n: T) -> Au { Au(n.to_i32()) }
fn from<T:NumCast>(n: T) -> Au { Au(n.to_i32()) }
pure fn to_u8(&self) -> u8 { (**self).to_u8() }
pure fn to_u16(&self) -> u16 { (**self).to_u16() }
pure fn to_u32(&self) -> u32 { (**self).to_u32() }
pure fn to_u64(&self) -> u64 { (**self).to_u64() }
pure fn to_uint(&self) -> uint { (**self).to_uint() }
fn to_u8(&self) -> u8 { (**self).to_u8() }
fn to_u16(&self) -> u16 { (**self).to_u16() }
fn to_u32(&self) -> u32 { (**self).to_u32() }
fn to_u64(&self) -> u64 { (**self).to_u64() }
fn to_uint(&self) -> uint { (**self).to_uint() }
pure fn to_i8(&self) -> i8 { (**self).to_i8() }
pure fn to_i16(&self) -> i16 { (**self).to_i16() }
pure fn to_i32(&self) -> i32 { (**self).to_i32() }
pure fn to_i64(&self) -> i64 { (**self).to_i64() }
pure fn to_int(&self) -> int { (**self).to_int() }
fn to_i8(&self) -> i8 { (**self).to_i8() }
fn to_i16(&self) -> i16 { (**self).to_i16() }
fn to_i32(&self) -> i32 { (**self).to_i32() }
fn to_i64(&self) -> i64 { (**self).to_i64() }
fn to_int(&self) -> int { (**self).to_int() }
pure fn to_f32(&self) -> f32 { (**self).to_f32() }
pure fn to_f64(&self) -> f64 { (**self).to_f64() }
pure fn to_float(&self) -> float { (**self).to_float() }
fn to_f32(&self) -> f32 { (**self).to_f32() }
fn to_f64(&self) -> f64 { (**self).to_f64() }
fn to_float(&self) -> float { (**self).to_float() }
}
pub fn box<T:Copy + Ord + Add<T,T> + Sub<T,T>>(x: T, y: T, w: T, h: T) -> Rect<T> {
@ -70,76 +70,76 @@ pub fn box<T:Copy + Ord + Add<T,T> + Sub<T,T>>(x: T, y: T, w: T, h: T) -> Rect<T
}
pub impl Au {
pub pure fn scale_by(self, factor: float) -> Au {
pub fn scale_by(self, factor: float) -> Au {
Au(((*self as float) * factor) as i32)
}
static pub pure fn from_px(i: int) -> Au {
pub fn from_px(i: int) -> Au {
NumCast::from(i * 60)
}
pub pure fn to_px(&const self) -> int {
pub fn to_px(&self) -> int {
(**self / 60) as int
}
pub pure fn to_snapped(&const self) -> Au {
pub fn to_snapped(&self) -> Au {
let res = **self % 60i32;
return if res >= 30i32 { return Au(**self - res + 60i32) }
else { return Au(**self - res) };
}
static pub pure fn zero_point() -> Point2D<Au> {
pub fn zero_point() -> Point2D<Au> {
Point2D(Au(0), Au(0))
}
static pub pure fn zero_rect() -> Rect<Au> {
pub fn zero_rect() -> Rect<Au> {
let z = Au(0);
Rect(Point2D(z, z), Size2D(z, z))
}
// assumes 72 points per inch, and 96 px per inch
static pub pure fn from_pt(f: float) -> Au {
pub fn from_pt(f: float) -> Au {
from_px((f / 72f * 96f) as int)
}
static pub pure fn from_frac_px(f: float) -> Au {
pub fn from_frac_px(f: float) -> Au {
Au((f * 60f) as i32)
}
static pub pure fn min(x: Au, y: Au) -> Au { if *x < *y { x } else { y } }
static pub pure fn max(x: Au, y: Au) -> Au { if *x > *y { x } else { y } }
pub fn min(x: Au, y: Au) -> Au { if *x < *y { x } else { y } }
pub fn max(x: Au, y: Au) -> Au { if *x > *y { x } else { y } }
}
pub pure fn zero_rect() -> Rect<Au> {
pub fn zero_rect() -> Rect<Au> {
let z = Au(0);
Rect(Point2D(z, z), Size2D(z, z))
}
pub pure fn zero_point() -> Point2D<Au> {
pub fn zero_point() -> Point2D<Au> {
Point2D(Au(0), Au(0))
}
pub pure fn zero_size() -> Size2D<Au> {
pub fn zero_size() -> Size2D<Au> {
Size2D(Au(0), Au(0))
}
pub pure fn from_frac_px(f: float) -> Au {
pub fn from_frac_px(f: float) -> Au {
Au((f * 60f) as i32)
}
pub pure fn from_px(i: int) -> Au {
pub fn from_px(i: int) -> Au {
NumCast::from(i * 60)
}
pub pure fn to_px(au: Au) -> int {
pub fn to_px(au: Au) -> int {
(*au / 60) as int
}
pub pure fn to_frac_px(au: Au) -> float {
pub fn to_frac_px(au: Au) -> float {
(*au as float) / 60f
}
// assumes 72 points per inch, and 96 px per inch
pub pure fn from_pt(f: float) -> Au {
pub fn from_pt(f: float) -> Au {
from_px((f / 72f * 96f) as int)
}

View file

@ -9,7 +9,7 @@ pub fn Image(width: uint, height: uint, depth: uint, data: ~[u8]) -> Image {
stb_image::new_image(width, height, depth, data)
}
const TEST_IMAGE: [u8 * 4962] = include_bin!("test.jpeg");
static TEST_IMAGE: [u8, ..4962] = include_bin!("test.jpeg");
pub fn test_image_bin() -> ~[u8] {
return vec::from_fn(4962, |i| TEST_IMAGE[i]);
@ -18,11 +18,11 @@ pub fn test_image_bin() -> ~[u8] {
pub fn load_from_memory(buffer: &[u8]) -> Option<Image> {
// Can't remember why we do this. Maybe it's what cairo wants
const FORCE_DEPTH: uint = 4;
static FORCE_DEPTH: uint = 4;
match stb_image::load_from_memory_with_depth(buffer, FORCE_DEPTH, true) {
stb_image::ImageU8(image) => {
fail_unless!(image.depth == 4);
assert!(image.depth == 4);
// Do color space conversion :(
let data = do vec::from_fn(image.width * image.height * 4) |i| {
let color = i % 4;
@ -36,7 +36,7 @@ pub fn load_from_memory(buffer: &[u8]) -> Option<Image> {
}
};
fail_unless!(image.data.len() == data.len());
assert!(image.data.len() == data.len());
Some(Image(image.width, image.height, image.depth, data))
}

View file

@ -1,8 +1,8 @@
use core::io::WriterUtil;
use surface;
fn encode(writer: io::Writer, surface: &surface::ImageSurface) {
fail_unless!(surface.format == surface::fo_rgba_8888);
fn encode(writer: @io::Writer, surface: &surface::ImageSurface) {
assert!(surface.format == surface::fo_rgba_8888);
writer.write_u8(0u8); // identsize
writer.write_u8(0u8); // colourmaptype

View file

@ -1,6 +1,5 @@
use image::base::Image;
use resource::image_cache_task::{ImageCacheTask, ImageReady, ImageNotReady, ImageFailed};
use resource::image_cache_task;
use resource::image_cache_task::{ImageReady, ImageNotReady, ImageFailed};
use resource::local_image_cache::LocalImageCache;
use core::util::replace;
@ -23,25 +22,25 @@ pub struct ImageHolder {
}
pub impl ImageHolder {
static pub fn new(url: Url, local_image_cache: @mut LocalImageCache) -> ImageHolder {
debug!("ImageHolder::new() %?", url.to_str());
let holder = ImageHolder {
url: url,
image: None,
cached_size: Size2D(0,0),
local_image_cache: local_image_cache,
};
pub fn new(url: Url, local_image_cache: @mut LocalImageCache) -> ImageHolder {
debug!("ImageHolder::new() %?", url.to_str());
let holder = ImageHolder {
url: url,
image: None,
cached_size: Size2D(0,0),
local_image_cache: local_image_cache,
};
// Tell the image cache we're going to be interested in this url
// FIXME: These two messages must be sent to prep an image for use
// but they are intended to be spread out in time. Ideally prefetch
// should be done as early as possible and decode only once we
// are sure that the image will be used.
local_image_cache.prefetch(&holder.url);
local_image_cache.decode(&holder.url);
// Tell the image cache we're going to be interested in this url
// FIXME: These two messages must be sent to prep an image for use
// but they are intended to be spread out in time. Ideally prefetch
// should be done as early as possible and decode only once we
// are sure that the image will be used.
local_image_cache.prefetch(&holder.url);
local_image_cache.decode(&holder.url);
holder
}
holder
}
/**
This version doesn't perform any computation, but may be stale w.r.t.
@ -50,7 +49,7 @@ pub impl ImageHolder {
The intent is that the impure version is used during layout when
dimensions are used for computing layout.
*/
pure fn size(&self) -> Size2D<int> {
fn size(&self) -> Size2D<int> {
self.cached_size
}

View file

@ -9,22 +9,19 @@ use gfx_font::{CSSFontWeight, FontHandleMethods, FontMetrics, FontTable, FontTab
use gfx_font::{FontTableTag, FontWeight100, FontWeight200, FontWeight300, FontWeight400};
use gfx_font::{FontWeight500, FontWeight600, FontWeight700, FontWeight800, FontWeight900};
use gfx_font::{FractionalPixel, SpecifiedFontStyle};
use quartz::font::core_foundation::base::{CFIndex, CFTypeRef, CFWrapper};
use quartz::font::core_foundation::data::{CFData, CFDataRef};
use quartz::font::core_foundation::base::{CFIndex, CFWrapper};
use quartz::font::core_foundation::data::CFData;
use quartz::font::core_foundation::string::UniChar;
use quartz::font::core_graphics::base::{CGFloat, CGAffineTransform};
use quartz::font::core_graphics::data_provider::{CGDataProviderRef, CGDataProvider};
use quartz::font::core_graphics::font::{CGFont, CGFontRef, CGGlyph};
use quartz::font::core_graphics::data_provider::CGDataProvider;
use quartz::font::core_graphics::font::{CGFont, CGGlyph};
use quartz::font::core_graphics::geometry::CGRect;
use quartz::font::core_text::font::CTFont;
use quartz::font::core_text::font_descriptor::{SymbolicTraitAccessors};
use quartz::font::core_text::font_descriptor::{kCTFontDefaultOrientation, CTFontSymbolicTraits};
use quartz::font::core_text::font::{CTFont, CTFontMethods, CTFontMethodsPrivate};
use quartz::font::core_text::font_descriptor::{SymbolicTraitAccessors, TraitAccessors};
use quartz::font::core_text::font_descriptor::kCTFontDefaultOrientation;
use quartz::font_context::QuartzFontContextHandle;
use quartz;
use text::glyph::GlyphIndex;
use core::libc::size_t;
struct QuartzFontTable {
data: CFData,
}
@ -34,27 +31,25 @@ struct QuartzFontTable {
impl Drop for QuartzFontTable { fn finalize(&self) {} }
pub impl QuartzFontTable {
static fn wrap(data: CFData) -> QuartzFontTable {
fn wrap(data: CFData) -> QuartzFontTable {
QuartzFontTable { data: data }
}
}
impl FontTableMethods for QuartzFontTable {
fn with_buffer(blk: &fn(*u8, uint)) {
fn with_buffer(&self, blk: &fn(*u8, uint)) {
blk(self.data.bytes(), self.data.len());
}
}
pub struct QuartzFontHandle {
priv mut cgfont: Option<CGFont>,
priv cgfont: Option<CGFont>,
ctfont: CTFont,
drop { }
}
pub impl QuartzFontHandle {
static fn new_from_buffer(_fctx: &QuartzFontContextHandle, buf: ~[u8],
style: &SpecifiedFontStyle) -> Result<QuartzFontHandle, ()> {
fn new_from_buffer(_fctx: &QuartzFontContextHandle, buf: ~[u8],
style: &SpecifiedFontStyle) -> Result<QuartzFontHandle, ()> {
let fontprov : CGDataProvider = vec::as_imm_buf(buf, |cbuf, len| {
quartz::font::core_graphics::data_provider::new_from_buffer(cbuf, len)
});
@ -70,7 +65,7 @@ pub impl QuartzFontHandle {
return result;
}
static fn new_from_CTFont(_fctx: &QuartzFontContextHandle, ctfont: CTFont) -> Result<QuartzFontHandle, ()> {
fn new_from_CTFont(_fctx: &QuartzFontContextHandle, ctfont: CTFont) -> Result<QuartzFontHandle, ()> {
let result = Ok(QuartzFontHandle {
mut cgfont: None,
ctfont: ctfont,
@ -79,9 +74,9 @@ pub impl QuartzFontHandle {
return result;
}
fn get_CGFont() -> CGFont {
fn get_CGFont(&mut self) -> CGFont {
match self.cgfont {
Some(ref font) => CFWrapper::wrap_shared(*font.borrow_ref()),
Some(ref font) => CFWrapper::wrap_shared(*(font.borrow_ref())),
None => {
let cgfont = self.ctfont.copy_to_CGFont();
self.cgfont = Some(CFWrapper::clone(&cgfont));
@ -92,19 +87,19 @@ pub impl QuartzFontHandle {
}
impl FontHandleMethods for QuartzFontHandle {
pure fn family_name() -> ~str {
fn family_name(&self) -> ~str {
self.ctfont.family_name()
}
pure fn face_name() -> ~str {
fn face_name(&self) -> ~str {
self.ctfont.face_name()
}
pure fn is_italic() -> bool {
fn is_italic(&self) -> bool {
self.ctfont.symbolic_traits().is_italic()
}
pure fn boldness() -> CSSFontWeight {
fn boldness(&self) -> CSSFontWeight {
// -1.0 to 1.0
let normalized = unsafe { self.ctfont.all_traits().normalized_weight() };
// 0.0 to 9.0
@ -120,16 +115,16 @@ impl FontHandleMethods for QuartzFontHandle {
return FontWeight900;
}
fn clone_with_style(fctx: &QuartzFontContextHandle,
fn clone_with_style(&self, fctx: &QuartzFontContextHandle,
style: &SpecifiedFontStyle)
-> Result<QuartzFontHandle,()> {
let new_font = self.ctfont.clone_with_font_size(style.pt_size);
return QuartzFontHandle::new_from_CTFont(fctx, new_font);
}
fn glyph_index(codepoint: char) -> Option<GlyphIndex> {
let characters: [UniChar * 1] = [codepoint as UniChar];
let glyphs: [CGGlyph * 1] = [0 as CGGlyph];
fn glyph_index(&self, codepoint: char) -> Option<GlyphIndex> {
let characters: [UniChar, ..1] = [codepoint as UniChar];
let glyphs: [CGGlyph, ..1] = [0 as CGGlyph];
let count: CFIndex = 1;
let result = self.ctfont.get_glyphs_for_characters(ptr::to_unsafe_ptr(&characters[0]),
@ -141,11 +136,11 @@ impl FontHandleMethods for QuartzFontHandle {
return None;
}
fail_unless!(glyphs[0] != 0); // FIXME: error handling
assert!(glyphs[0] != 0); // FIXME: error handling
return Some(glyphs[0] as GlyphIndex);
}
fn glyph_h_advance(glyph: GlyphIndex) -> Option<FractionalPixel> {
fn glyph_h_advance(&self, glyph: GlyphIndex) -> Option<FractionalPixel> {
let glyphs = [glyph as CGGlyph];
unsafe {
let advance = self.ctfont.get_advances_for_glyphs(kCTFontDefaultOrientation,
@ -156,7 +151,7 @@ impl FontHandleMethods for QuartzFontHandle {
}
}
fn get_metrics() -> FontMetrics {
fn get_metrics(&self) -> FontMetrics {
let bounding_rect: CGRect = self.ctfont.bounding_box();
let ascent = Au::from_pt(self.ctfont.ascent() as float);
let descent = Au::from_pt(self.ctfont.descent() as float);
@ -181,14 +176,14 @@ impl FontHandleMethods for QuartzFontHandle {
return metrics;
}
fn get_table_for_tag(tag: FontTableTag) -> Option<FontTable> {
fn get_table_for_tag(&self, tag: FontTableTag) -> Option<FontTable> {
let result : Option<CFData> = self.ctfont.get_font_table(tag);
return option::chain(result, |data| {
result.chain(|data| {
Some(QuartzFontTable::wrap(data))
});
})
}
pure fn face_identifier() -> ~str {
fn face_identifier(&self) -> ~str {
self.ctfont.postscript_name()
}
}

View file

@ -4,34 +4,31 @@ extern mod core_text;
use quartz;
use quartz::font::QuartzFontHandle;
use quartz::font_context::core_text::font::CTFont;
use gfx_font::{FontHandle, UsedFontStyle};
use gfx_font_context::FontContextHandleMethods;
pub struct QuartzFontContextHandle {
ctx: (),
drop { }
ctx: ()
}
pub impl QuartzFontContextHandle {
// this is a placeholder until NSFontManager or whatever is bound in here.
static pub fn new() -> QuartzFontContextHandle {
pub fn new() -> QuartzFontContextHandle {
QuartzFontContextHandle { ctx: () }
}
}
impl FontContextHandleMethods for QuartzFontContextHandle {
pure fn clone(&const self) -> QuartzFontContextHandle {
fn clone(&self) -> QuartzFontContextHandle {
QuartzFontContextHandle { ctx: self.ctx }
}
fn create_font_from_identifier(name: ~str, style: UsedFontStyle) -> Result<FontHandle, ()> {
fn create_font_from_identifier(&self, name: ~str, style: UsedFontStyle) -> Result<FontHandle, ()> {
let ctfont_result = quartz::font_context::core_text::font::new_from_name(name,
style.pt_size);
do result::chain(ctfont_result) |ctfont| {
QuartzFontHandle::new_from_CTFont(&self, ctfont)
QuartzFontHandle::new_from_CTFont(self, ctfont)
}
}
}

View file

@ -7,45 +7,43 @@ use quartz::font_list::core_foundation::array::CFArray;
use quartz::font_list::core_foundation::base::CFWrapper;
use quartz::font_list::core_foundation::string::{CFString, CFStringRef};
use quartz::font_list::core_text::font::{CTFont, debug_font_names, debug_font_traits};
use quartz::font_list::core_text::font_collection::CTFontCollection;
use quartz::font_list::core_text::font_descriptor::{CTFontDescriptor, CTFontDescriptorRef};
use quartz::font_list::core_text::font_descriptor::{debug_descriptor};
use quartz::font_list::core_text::font_descriptor::CTFontDescriptorRef;
use quartz::font_list::core_text::font_collection::CTFontCollectionMethods;
use quartz::font::QuartzFontHandle;
use quartz::font_context::QuartzFontContextHandle;
use gfx_font::{FontHandle, FontHandleMethods};
use gfx_font::FontHandleMethods;
use gfx_font_context::FontContextHandleMethods;
use gfx_font_list::{FontEntry, FontFamily, FontFamilyMap};
use core::dvec::DVec;
use core::hashmap::linear::LinearMap;
use core::hashmap::HashMap;
pub struct QuartzFontListHandle {
fctx: QuartzFontContextHandle,
}
pub impl QuartzFontListHandle {
static fn new(fctx: &native::FontContextHandle) -> QuartzFontListHandle {
fn new(fctx: &native::FontContextHandle) -> QuartzFontListHandle {
QuartzFontListHandle { fctx: fctx.clone() }
}
fn get_available_families() -> FontFamilyMap {
fn get_available_families(&self) -> FontFamilyMap {
let family_names: CFArray<CFStringRef> =
quartz::font_list::core_text::font_collection::get_family_names();
let mut family_map : FontFamilyMap = LinearMap::new();
let mut family_map : FontFamilyMap = HashMap::new();
for family_names.each |&strref: &CFStringRef| {
let family_name = CFString::wrap_extern(strref).to_str();
debug!("Creating new FontFamily for family: %s", family_name);
let new_family = @FontFamily::new(family_name);
let new_family = @mut FontFamily::new(family_name);
family_map.insert(family_name, new_family);
}
return family_map;
}
fn load_variations_for_family(family: @FontFamily) {
let family_name = &family.family_name;
fn load_variations_for_family(&self, family: @mut FontFamily) {
let fam : &mut FontFamily = family; // FIXME: borrow checker workaround
let family_name = &fam.family_name;
debug!("Looking for faces of family: %s", *family_name);
let family_collection =

View file

@ -3,27 +3,25 @@ use font_context::FontContext;
use geometry::Au;
use image::base::Image;
use opts::Opts;
use text::TextRun;
use azure::azure_hl::{AsAzureRect, B8G8R8A8, Color, ColorPattern, DrawOptions};
use azure::azure_hl::{B8G8R8A8, Color, ColorPattern, DrawOptions};
use azure::azure_hl::{DrawSurfaceOptions, DrawTarget, Linear, StrokeOptions};
use azure::{AzDrawOptions, AzFloat};
use azure::AzFloat;
use core::libc::types::common::c99::uint16_t;
use core::ptr::to_unsafe_ptr;
use geom::point::Point2D;
use geom::rect::Rect;
use geom::size::Size2D;
use std::arc;
use std::arc::ARC;
pub struct RenderContext {
pub struct RenderContext<'self> {
canvas: &'self LayerBuffer,
font_ctx: @mut FontContext,
opts: &'self Opts
}
pub impl<'self> RenderContext<'self> {
pub fn get_draw_target(&self) -> &self/DrawTarget {
pub fn get_draw_target(&self) -> &'self DrawTarget {
&self.canvas.draw_target
}

View file

@ -3,25 +3,20 @@ use display_list::DisplayList;
use opts::Opts;
use util::time;
use azure::AzFloat;
use azure::azure_hl::{B8G8R8A8, DrawTarget};
use core::libc::c_int;
use core::comm::Chan;
use geom::matrix2d::Matrix2D;
use geom::point::Point2D;
use geom::rect::Rect;
use geom::size::Size2D;
use std::arc::ARC;
use std::arc;
pub struct RenderLayer {
display_list: DisplayList,
size: Size2D<uint>
}
type RenderFn = &'self fn(layer: *RenderLayer,
buffer: LayerBuffer,
return_buffer: Chan<LayerBuffer>);
type RenderFn<'self> = &'self fn(layer: *RenderLayer,
buffer: LayerBuffer,
return_buffer: Chan<LayerBuffer>);
/// Given a layer and a buffer, either reuses the buffer (if it's of the right size and format)
/// or creates a new buffer (if it's not of the appropriate size and format) and invokes the
@ -56,8 +51,8 @@ pub fn render_layers(layer_ref: *RenderLayer,
if stride % 32 != 0 {
stride = (stride & !(32 - 1)) + 32;
}
fail_unless!(stride % 32 == 0);
fail_unless!(stride >= width);
assert!(stride % 32 == 0);
assert!(stride >= width);
debug!("tile stride %u", stride);

View file

@ -10,13 +10,9 @@ use render_layers::{RenderLayer, render_layers};
use resource::util::spawn_listener;
use util::time::time;
use core::libc::size_t;
use core::libc::types::common::c99::uint16_t;
use core::cell::Cell;
use core::comm::{Chan, Port, SharedChan};
use core::comm::{Port, SharedChan};
use core::task::SingleThreaded;
use std::arc::ARC;
use std::arc;
use std::task_pool::TaskPool;
pub enum Msg {

View file

@ -1,14 +1,12 @@
use core::comm::Chan;
use core::task::spawn;
use resource::resource_task::{ProgressMsg, Payload, Done, LoaderTask};
use std::net::url::Url;
use resource::resource_task::{Payload, Done, LoaderTask};
use core::io::{file_reader, ReaderUtil};
const READ_SIZE: uint = 1024;
static READ_SIZE: uint = 1024;
pub fn factory() -> LoaderTask {
let f: LoaderTask = |url, progress_chan| {
fail_unless!(url.scheme == ~"file");
assert!(url.scheme == ~"file");
do spawn {
// FIXME: Resolve bug prevents us from moving the path out of the URL.
match file_reader(&Path(url.path)) {

View file

@ -1,25 +1,23 @@
use core::comm::{Chan, SharedChan};
use core::comm::SharedChan;
use core::task::spawn;
use resource::resource_task::{ProgressMsg, Payload, Done, LoaderTask};
use core::cell::Cell;
use std::net::url::Url;
use resource::resource_task::{Payload, Done, LoaderTask};
use http_client;
use http_client::{uv_http_request};
pub fn factory() -> LoaderTask {
let f: LoaderTask = |url, progress_chan| {
fail_unless!(url.scheme == ~"http");
assert!(url.scheme == ~"http");
let progress_chan = SharedChan(progress_chan);
do spawn {
debug!("http_loader: requesting via http: %?", copy url);
let mut request = uv_http_request(copy url);
debug!("http_loader: requesting via http: %?", url.clone());
let mut request = uv_http_request(url.clone());
let errored = @mut false;
let url = copy url;
let url = url.clone();
{
let progress_chan = progress_chan.clone();
do request.begin |event| {
let url = copy url;
let url = url.clone();
match event {
http_client::Status(*) => { }
http_client::Payload(data) => {

View file

@ -1,12 +1,11 @@
use image::base::{Image, load_from_memory, test_image_bin};
use image::base::{Image, load_from_memory};
use resource::resource_task;
use resource::resource_task::ResourceTask;
use util::url::{make_url, UrlMap, url_map};
use util::url::{UrlMap, url_map};
use clone_arc = std::arc::clone;
use core::comm::{Chan, Port, SharedChan, stream};
use core::task::spawn;
use resource::util::spawn_listener;
use core::to_str::ToStr;
use core::util::replace;
use std::arc::ARC;
@ -49,7 +48,7 @@ pub enum ImageResponseMsg {
}
impl ImageResponseMsg {
pure fn clone(&self) -> ImageResponseMsg {
fn clone(&self) -> ImageResponseMsg {
match *self {
ImageReady(ref img) => ImageReady(unsafe { clone_arc(img) }),
ImageNotReady => ImageNotReady,
@ -59,7 +58,7 @@ impl ImageResponseMsg {
}
impl Eq for ImageResponseMsg {
pure fn eq(&self, other: &ImageResponseMsg) -> bool {
fn eq(&self, other: &ImageResponseMsg) -> bool {
// FIXME: Bad copies
match (self.clone(), other.clone()) {
(ImageReady(*), ImageReady(*)) => fail!(~"unimplemented comparison"),
@ -71,7 +70,7 @@ impl Eq for ImageResponseMsg {
| (ImageFailed, _) => false
}
}
pure fn ne(&self, other: &ImageResponseMsg) -> bool {
fn ne(&self, other: &ImageResponseMsg) -> bool {
return !(*self).eq(other);
}
}
@ -199,7 +198,7 @@ impl ImageCache {
}
OnMsg(handler) => msg_handlers.push(handler),
Exit(response) => {
fail_unless!(self.need_exit.is_none());
assert!(self.need_exit.is_none());
self.need_exit = Some(response);
}
}
@ -234,7 +233,7 @@ impl ImageCache {
priv fn get_state(&self, url: Url) -> ImageState {
match self.state_map.find(&url) {
Some(state) => state,
Some(state) => *state,
None => Init
}
}
@ -317,7 +316,7 @@ impl ImageCache {
}
Prefetched(data_cell) => {
fail_unless!(!data_cell.is_empty());
assert!(!data_cell.is_empty());
let data = data_cell.take();
let to_cache = self.chan.clone();
@ -329,7 +328,7 @@ impl ImageCache {
debug!("image_cache_task: started image decode for %s", url.to_str());
let image = decode(data);
let image = if image.is_some() {
Some(ARC(~option::unwrap(image)))
Some(ARC(~image.unwrap()))
} else {
None
};
@ -376,7 +375,7 @@ impl ImageCache {
priv fn purge_waiters(&self, url: Url, f: &fn() -> ImageResponseMsg) {
match self.wait_map.find(&url) {
Some(waiters) => {
let waiters = &mut *waiters;
let waiters = *waiters;
let mut new_waiters = ~[];
new_waiters <-> *waiters;
@ -427,7 +426,7 @@ impl ImageCache {
// We don't have this image yet
match self.wait_map.find(&url) {
Some(waiters) => {
vec::push(&mut *waiters, response);
vec::push(*waiters, response);
}
None => {
self.wait_map.insert(url, @mut ~[response]);
@ -598,7 +597,7 @@ fn should_not_request_url_from_resource_task_on_multiple_prefetches() {
url_requested.recv();
image_cache_task.exit();
mock_resource_task.send(resource_task::Exit);
fail_unless!(!url_requested.peek())
assert!(!url_requested.peek())
}
#[test]
@ -621,7 +620,7 @@ fn should_return_image_not_ready_if_data_has_not_arrived() {
image_cache_task.send(Decode(copy url));
let (response_chan, response_port) = stream();
image_cache_task.send(GetImage(url, response_chan));
fail_unless!(response_port.recv() == ImageNotReady);
assert!(response_port.recv() == ImageNotReady);
wait_chan.send(());
image_cache_task.exit();
mock_resource_task.send(resource_task::Exit);
@ -747,7 +746,7 @@ fn should_not_request_image_from_resource_task_if_image_is_already_available() {
// Our resource task should not have received another request for the image
// because it's already cached
fail_unless!(!image_bin_sent.peek());
assert!(!image_bin_sent.peek());
}
#[test]
@ -794,7 +793,7 @@ fn should_not_request_image_from_resource_task_if_image_fetch_already_failed() {
// Our resource task should not have received another request for the image
// because it's already cached
fail_unless!(!image_bin_sent.peek());
assert!(!image_bin_sent.peek());
}
#[test]

View file

@ -6,7 +6,7 @@ multiple times and thus triggering reflows multiple times.
use clone_arc = std::arc::clone;
use std::net::url::Url;
use core::comm::{Port, Chan, stream};
use core::comm::Port;
use resource::image_cache_task::{ImageCacheTask, ImageResponseMsg, Prefetch, Decode, GetImage};
use resource::image_cache_task::{ WaitForImage, ImageReady, ImageNotReady, ImageFailed};
use util::url::{UrlMap, url_map};
@ -107,7 +107,7 @@ pub impl LocalImageCache {
// the compositor should be resonsible for waiting
// on the image to load and triggering layout
let image_cache_task = self.image_cache_task.clone();
fail_unless!(self.on_image_available.is_some());
assert!(self.on_image_available.is_some());
let on_image_available = self.on_image_available.get()();
let url = copy *url;
do task::spawn {
@ -134,7 +134,7 @@ pub impl LocalImageCache {
priv fn get_state(&self, url: &Url) -> @mut ImageState {
match self.state_map.find(url) {
Some(state) => state,
Some(state) => *state,
None => {
let new_state = @mut ImageState {
prefetched: false,

View file

@ -7,7 +7,6 @@ A task that takes a URL and streams back the binary data
use core::cell::Cell;
use core::comm::{Chan, Port, SharedChan};
use resource::util::spawn_listener;
use std::net::url;
use std::net::url::{Url, to_str};
use super::{file_loader, http_loader};
@ -18,7 +17,7 @@ pub enum ControlMsg {
}
/// Messages sent in response to a `Load` message
#[deriving_eq]
#[deriving(Eq)]
pub enum ProgressMsg {
/// Binary data - there may be multiple of these
Payload(~[u8]),
@ -80,7 +79,7 @@ impl ResourceManager {
loop {
match self.from_client.recv() {
Load(url, progress_chan) => {
self.load(copy url, progress_chan)
self.load(url.clone(), progress_chan)
}
Exit => {
break
@ -130,7 +129,7 @@ fn test_bad_scheme() {
let progress = Port();
resource_task.send(Load(url::from_str(~"bogus://whatever").get(), progress.chan()));
match progress.recv() {
Done(result) => { fail_unless!(result.is_err()) }
Done(result) => { assert!(result.is_err()) }
_ => fail
}
resource_task.send(Exit);
@ -148,7 +147,7 @@ fn should_delegate_to_scheme_loader() {
let resource_task = create_resource_task_with_loaders(loader_factories);
let progress = Port();
resource_task.send(Load(url::from_str(~"snicklefritz://heya").get(), progress.chan()));
fail_unless!(progress.recv() == Payload(payload));
fail_unless!(progress.recv() == Done(Ok(())));
assert!(progress.recv() == Payload(payload));
assert!(progress.recv() == Done(Ok(())));
resource_task.send(Exit);
}

View file

@ -11,6 +11,14 @@ extern mod http_client;
extern mod stb_image;
extern mod std;
pub use servo_util = util;
pub use gfx_font = font;
pub use gfx_font_context = font_context;
pub use gfx_font_list = font_list;
pub use servo_gfx_font = font;
pub use servo_gfx_font_list = font_list;
pub use servo_gfx_util = util;
priv mod render_context;
// Rendering
@ -82,12 +90,3 @@ pub mod util {
pub mod url;
pub mod vec;
}
pub use servo_util = util;
pub use gfx_font = font;
pub use gfx_font_context = font_context;
pub use gfx_font_list = font_list;
pub use servo_gfx_font = font;
pub use servo_gfx_font_list = font_list;
pub use servo_gfx_util = util;

View file

@ -1,6 +1,6 @@
use geom::size::Size2D;
#[deriving_eq]
#[deriving(Eq)]
pub enum format {
fo_rgba_8888
// TODO: RGB 565, others?
@ -21,12 +21,12 @@ pub struct ImageSurface {
}
impl ImageSurface {
static pub fn new(size: Size2D<int>, format: format) -> ImageSurface {
ImageSurface {
size: copy size,
format: format,
buffer: vec::from_elem((size.area() as uint) * format.bpp(), 0u8)
}
pub fn new(size: Size2D<int>, format: format) -> ImageSurface {
ImageSurface {
size: copy size,
format: format,
buffer: vec::from_elem((size.area() as uint) * format.bpp(), 0u8)
}
}
}

View file

@ -26,30 +26,30 @@ struct GlyphEntry {
value : u32
}
pure fn GlyphEntry(value: u32) -> GlyphEntry { GlyphEntry { value: value } }
fn GlyphEntry(value: u32) -> GlyphEntry { GlyphEntry { value: value } }
/// The index of a particular glyph within a font
pub type GlyphIndex = u32;
// TODO: unify with bit flags?
#[deriving_eq]
#[deriving(Eq)]
pub enum BreakType {
BreakTypeNone,
BreakTypeNormal,
BreakTypeHyphen
}
const BREAK_TYPE_NONE : u8 = 0x0u8;
const BREAK_TYPE_NORMAL : u8 = 0x1u8;
const BREAK_TYPE_HYPHEN : u8 = 0x2u8;
static BREAK_TYPE_NONE : u8 = 0x0u8;
static BREAK_TYPE_NORMAL : u8 = 0x1u8;
static BREAK_TYPE_HYPHEN : u8 = 0x2u8;
pure fn break_flag_to_enum(flag: u8) -> BreakType {
fn break_flag_to_enum(flag: u8) -> BreakType {
if (flag & BREAK_TYPE_NORMAL) != 0 { return BreakTypeNormal; }
if (flag & BREAK_TYPE_HYPHEN) != 0 { return BreakTypeHyphen; }
BreakTypeNone
}
pure fn break_enum_to_flag(e: BreakType) -> u8 {
fn break_enum_to_flag(e: BreakType) -> u8 {
match e {
BreakTypeNone => BREAK_TYPE_NONE,
BreakTypeNormal => BREAK_TYPE_NORMAL,
@ -59,16 +59,16 @@ pure fn break_enum_to_flag(e: BreakType) -> u8 {
// TODO: make this more type-safe.
const FLAG_CHAR_IS_SPACE : u32 = 0x10000000u32;
static FLAG_CHAR_IS_SPACE : u32 = 0x10000000u32;
// These two bits store some BREAK_TYPE_* flags
const FLAG_CAN_BREAK_MASK : u32 = 0x60000000u32;
const FLAG_CAN_BREAK_SHIFT : u32 = 29;
const FLAG_IS_SIMPLE_GLYPH : u32 = 0x80000000u32;
static FLAG_CAN_BREAK_MASK : u32 = 0x60000000u32;
static FLAG_CAN_BREAK_SHIFT : u32 = 29;
static FLAG_IS_SIMPLE_GLYPH : u32 = 0x80000000u32;
// glyph advance; in Au's.
const GLYPH_ADVANCE_MASK : u32 = 0x0FFF0000u32;
const GLYPH_ADVANCE_SHIFT : u32 = 16;
const GLYPH_ID_MASK : u32 = 0x0000FFFFu32;
static GLYPH_ADVANCE_MASK : u32 = 0x0FFF0000u32;
static GLYPH_ADVANCE_SHIFT : u32 = 16;
static GLYPH_ID_MASK : u32 = 0x0000FFFFu32;
// Non-simple glyphs (more than one glyph per char; missing glyph,
// newline, tab, large advance, or nonzero x/y offsets) may have one
@ -79,38 +79,38 @@ const GLYPH_ID_MASK : u32 = 0x0000FFFFu32;
// The number of detailed glyphs for this char. If the char couldn't
// be mapped to a glyph (!FLAG_NOT_MISSING), then this actually holds
// the UTF8 code point instead.
const GLYPH_COUNT_MASK : u32 = 0x00FFFF00u32;
const GLYPH_COUNT_SHIFT : u32 = 8;
static GLYPH_COUNT_MASK : u32 = 0x00FFFF00u32;
static GLYPH_COUNT_SHIFT : u32 = 8;
// N.B. following Gecko, these are all inverted so that a lot of
// missing chars can be memset with zeros in one fell swoop.
const FLAG_NOT_MISSING : u32 = 0x00000001u32;
const FLAG_NOT_CLUSTER_START : u32 = 0x00000002u32;
const FLAG_NOT_LIGATURE_GROUP_START : u32 = 0x00000004u32;
static FLAG_NOT_MISSING : u32 = 0x00000001u32;
static FLAG_NOT_CLUSTER_START : u32 = 0x00000002u32;
static FLAG_NOT_LIGATURE_GROUP_START : u32 = 0x00000004u32;
const FLAG_CHAR_IS_TAB : u32 = 0x00000008u32;
const FLAG_CHAR_IS_NEWLINE : u32 = 0x00000010u32;
const FLAG_CHAR_IS_LOW_SURROGATE : u32 = 0x00000020u32;
const CHAR_IDENTITY_FLAGS_MASK : u32 = 0x00000038u32;
static FLAG_CHAR_IS_TAB : u32 = 0x00000008u32;
static FLAG_CHAR_IS_NEWLINE : u32 = 0x00000010u32;
static FLAG_CHAR_IS_LOW_SURROGATE : u32 = 0x00000020u32;
static CHAR_IDENTITY_FLAGS_MASK : u32 = 0x00000038u32;
pure fn is_simple_glyph_id(glyphId: GlyphIndex) -> bool {
fn is_simple_glyph_id(glyphId: GlyphIndex) -> bool {
((glyphId as u32) & GLYPH_ID_MASK) == glyphId
}
pure fn is_simple_advance(advance: Au) -> bool {
fn is_simple_advance(advance: Au) -> bool {
let unsignedAu = advance.to_int() as u32;
(unsignedAu & (GLYPH_ADVANCE_MASK >> GLYPH_ADVANCE_SHIFT)) == unsignedAu
}
type DetailedGlyphCount = u16;
pure fn InitialGlyphEntry() -> GlyphEntry {
fn InitialGlyphEntry() -> GlyphEntry {
GlyphEntry { value: 0 }
}
// Creates a GlyphEntry for the common case
pure fn SimpleGlyphEntry(index: GlyphIndex, advance: Au) -> GlyphEntry {
fail_unless!(is_simple_glyph_id(index));
fail_unless!(is_simple_advance(advance));
fn SimpleGlyphEntry(index: GlyphIndex, advance: Au) -> GlyphEntry {
assert!(is_simple_glyph_id(index));
assert!(is_simple_advance(advance));
let index_mask = index as u32;
let advance_mask = (*advance as u32) << GLYPH_ADVANCE_SHIFT;
@ -122,8 +122,8 @@ pure fn SimpleGlyphEntry(index: GlyphIndex, advance: Au) -> GlyphEntry {
// Create a GlyphEntry for uncommon case; should be accompanied by
// initialization of the actual DetailedGlyph data in DetailedGlyphStore
pure fn ComplexGlyphEntry(startsCluster: bool, startsLigature: bool, glyphCount: uint) -> GlyphEntry {
fail_unless!(glyphCount <= u16::max_value as uint);
fn ComplexGlyphEntry(startsCluster: bool, startsLigature: bool, glyphCount: uint) -> GlyphEntry {
assert!(glyphCount <= u16::max_value as uint);
debug!("Creating complex glyph entry: startsCluster=%?, startsLigature=%?, glyphCount=%?",
startsCluster, startsLigature, glyphCount);
@ -145,8 +145,8 @@ pure fn ComplexGlyphEntry(startsCluster: bool, startsLigature: bool, glyphCount:
// Create a GlyphEntry for the case where glyphs couldn't be found
// for the specified character.
pure fn MissingGlyphsEntry(glyphCount: uint) -> GlyphEntry {
fail_unless!(glyphCount <= u16::max_value as uint);
fn MissingGlyphsEntry(glyphCount: uint) -> GlyphEntry {
assert!(glyphCount <= u16::max_value as uint);
GlyphEntry {
value: (glyphCount as u32) << GLYPH_COUNT_SHIFT
@ -158,91 +158,91 @@ pure fn MissingGlyphsEntry(glyphCount: uint) -> GlyphEntry {
impl GlyphEntry {
// getter methods
#[inline(always)]
pure fn advance(&self) -> Au {
//fail_unless!(self.is_simple());
fn advance(&self) -> Au {
//assert!(self.is_simple());
NumCast::from((self.value & GLYPH_ADVANCE_MASK) >> GLYPH_ADVANCE_SHIFT)
}
pure fn index(&self) -> GlyphIndex {
//fail_unless!(self.is_simple());
fn index(&self) -> GlyphIndex {
//assert!(self.is_simple());
self.value & GLYPH_ID_MASK
}
pure fn offset(&self) -> Point2D<Au> {
//fail_unless!(self.is_simple());
fn offset(&self) -> Point2D<Au> {
//assert!(self.is_simple());
Point2D(Au(0), Au(0))
}
pure fn is_ligature_start(&self) -> bool {
fn is_ligature_start(&self) -> bool {
self.has_flag(!FLAG_NOT_LIGATURE_GROUP_START)
}
pure fn is_cluster_start(&self) -> bool {
fn is_cluster_start(&self) -> bool {
self.has_flag(!FLAG_NOT_CLUSTER_START)
}
// True if original char was normal (U+0020) space. Other chars may
// map to space glyph, but this does not account for them.
pure fn char_is_space(&self) -> bool {
fn char_is_space(&self) -> bool {
self.has_flag(FLAG_CHAR_IS_SPACE)
}
pure fn char_is_tab(&self) -> bool {
fn char_is_tab(&self) -> bool {
!self.is_simple() && self.has_flag(FLAG_CHAR_IS_TAB)
}
pure fn char_is_newline(&self) -> bool {
fn char_is_newline(&self) -> bool {
!self.is_simple() && self.has_flag(FLAG_CHAR_IS_NEWLINE)
}
pure fn can_break_before(&self) -> BreakType {
fn can_break_before(&self) -> BreakType {
let flag = ((self.value & FLAG_CAN_BREAK_MASK) >> FLAG_CAN_BREAK_SHIFT) as u8;
break_flag_to_enum(flag)
}
// setter methods
#[inline(always)]
pure fn set_char_is_space(&self) -> GlyphEntry {
fn set_char_is_space(&self) -> GlyphEntry {
GlyphEntry(self.value | FLAG_CHAR_IS_SPACE)
}
#[inline(always)]
pure fn set_char_is_tab(&self) -> GlyphEntry {
fail_unless!(!self.is_simple());
fn set_char_is_tab(&self) -> GlyphEntry {
assert!(!self.is_simple());
GlyphEntry(self.value | FLAG_CHAR_IS_TAB)
}
#[inline(always)]
pure fn set_char_is_newline(&self) -> GlyphEntry {
fail_unless!(!self.is_simple());
fn set_char_is_newline(&self) -> GlyphEntry {
assert!(!self.is_simple());
GlyphEntry(self.value | FLAG_CHAR_IS_NEWLINE)
}
#[inline(always)]
pure fn set_can_break_before(&self, e: BreakType) -> GlyphEntry {
fn set_can_break_before(&self, e: BreakType) -> GlyphEntry {
let flag = (break_enum_to_flag(e) as u32) << FLAG_CAN_BREAK_SHIFT;
GlyphEntry(self.value | flag)
}
// helper methods
/*priv*/ pure fn glyph_count(&self) -> u16 {
fail_unless!(!self.is_simple());
/*priv*/ fn glyph_count(&self) -> u16 {
assert!(!self.is_simple());
((self.value & GLYPH_COUNT_MASK) >> GLYPH_COUNT_SHIFT) as u16
}
#[inline(always)]
pure fn is_simple(&self) -> bool {
fn is_simple(&self) -> bool {
self.has_flag(FLAG_IS_SIMPLE_GLYPH)
}
#[inline(always)]
/*priv*/ pure fn has_flag(&self, flag: u32) -> bool {
/*priv*/ fn has_flag(&self, flag: u32) -> bool {
(self.value & flag) != 0
}
#[inline(always)]
pure fn adapt_character_flags_of_entry(&self, other: GlyphEntry) -> GlyphEntry {
fn adapt_character_flags_of_entry(&self, other: GlyphEntry) -> GlyphEntry {
GlyphEntry { value: self.value | other.value }
}
}
@ -267,7 +267,7 @@ fn DetailedGlyph(index: GlyphIndex,
}
}
#[deriving_eq]
#[deriving(Eq)]
struct DetailedGlyphRecord {
// source string offset/GlyphEntry offset in the TextRun
entry_offset: uint,
@ -276,16 +276,16 @@ struct DetailedGlyphRecord {
}
impl Ord for DetailedGlyphRecord {
pure fn lt(&self, other: &DetailedGlyphRecord) -> bool {
fn lt(&self, other: &DetailedGlyphRecord) -> bool {
self.entry_offset < other.entry_offset
}
pure fn le(&self, other: &DetailedGlyphRecord) -> bool {
fn le(&self, other: &DetailedGlyphRecord) -> bool {
self.entry_offset <= other.entry_offset
}
pure fn ge(&self, other: &DetailedGlyphRecord) -> bool {
fn ge(&self, other: &DetailedGlyphRecord) -> bool {
self.entry_offset >= other.entry_offset
}
pure fn gt(&self, other: &DetailedGlyphRecord) -> bool {
fn gt(&self, other: &DetailedGlyphRecord) -> bool {
self.entry_offset > other.entry_offset
}
}
@ -333,7 +333,7 @@ impl DetailedGlyphStore {
self.lookup_is_sorted = false;
}
pure fn get_detailed_glyphs_for_entry(&self, entry_offset: uint, count: u16) -> &self/[DetailedGlyph] {
fn get_detailed_glyphs_for_entry(&self, entry_offset: uint, count: u16) -> &'self [DetailedGlyph] {
debug!("Requesting detailed glyphs[n=%u] for entry[off=%u]", count as uint, entry_offset);
// FIXME: Is this right? --pcwalton
@ -342,8 +342,8 @@ impl DetailedGlyphStore {
return vec::slice(self.detail_buffer, 0, 0);
}
fail_unless!((count as uint) <= self.detail_buffer.len());
fail_unless!(self.lookup_is_sorted);
assert!((count as uint) <= self.detail_buffer.len());
assert!(self.lookup_is_sorted);
let key = DetailedGlyphRecord {
entry_offset: entry_offset,
@ -355,19 +355,19 @@ impl DetailedGlyphStore {
match records.binary_search_index(&key) {
None => fail!(~"Invalid index not found in detailed glyph lookup table!"),
Some(i) => {
fail_unless!(i + (count as uint) <= self.detail_buffer.len());
assert!(i + (count as uint) <= self.detail_buffer.len());
// return a slice into the buffer
vec::slice(self.detail_buffer, i, i + count as uint)
}
}
}
pure fn get_detailed_glyph_with_index(&self,
entry_offset: uint,
detail_offset: u16)
-> &self/DetailedGlyph {
fail_unless!((detail_offset as uint) <= self.detail_buffer.len());
fail_unless!(self.lookup_is_sorted);
fn get_detailed_glyph_with_index(&self,
entry_offset: uint,
detail_offset: u16)
-> &'self DetailedGlyph {
assert!((detail_offset as uint) <= self.detail_buffer.len());
assert!(self.lookup_is_sorted);
let key = DetailedGlyphRecord {
entry_offset: entry_offset,
@ -379,7 +379,7 @@ impl DetailedGlyphStore {
match records.binary_search_index(&key) {
None => fail!(~"Invalid index not found in detailed glyph lookup table!"),
Some(i) => {
fail_unless!(i + (detail_offset as uint) < self.detail_buffer.len());
assert!(i + (detail_offset as uint) < self.detail_buffer.len());
&self.detail_buffer[i+(detail_offset as uint)]
}
}
@ -417,13 +417,12 @@ pub struct GlyphData {
ligature_start: bool,
}
pub pure fn GlyphData(index: GlyphIndex,
advance: Au,
offset: Option<Point2D<Au>>,
is_missing: bool,
cluster_start: bool,
ligature_start: bool) -> GlyphData {
pub fn GlyphData(index: GlyphIndex,
advance: Au,
offset: Option<Point2D<Au>>,
is_missing: bool,
cluster_start: bool,
ligature_start: bool) -> GlyphData {
let _offset = match offset {
None => geometry::zero_point(),
Some(o) => o
@ -443,7 +442,7 @@ pub pure fn GlyphData(index: GlyphIndex,
// through glyphs (either for a particular TextRun offset, or all glyphs).
// Rather than eagerly assembling and copying glyph data, it only retrieves
// values as they are needed from the GlyphStore, using provided offsets.
enum GlyphInfo {
enum GlyphInfo<'self> {
SimpleGlyphInfo(&'self GlyphStore, uint),
DetailGlyphInfo(&'self GlyphStore, uint, u16)
}
@ -496,8 +495,8 @@ pub struct GlyphStore {
pub impl GlyphStore {
// Initializes the glyph store, but doesn't actually shape anything.
// Use the set_glyph, set_glyphs() methods to store glyph data.
static fn new(length: uint) -> GlyphStore {
fail_unless!(length > 0);
fn new(length: uint) -> GlyphStore {
assert!(length > 0);
GlyphStore {
entry_buffer: vec::from_elem(length, InitialGlyphEntry()),
@ -511,15 +510,15 @@ pub impl GlyphStore {
fn add_glyph_for_char_index(&mut self, i: uint, data: &GlyphData) {
pure fn glyph_is_compressible(data: &GlyphData) -> bool {
fn glyph_is_compressible(data: &GlyphData) -> bool {
is_simple_glyph_id(data.index)
&& is_simple_advance(data.advance)
&& data.offset == geometry::zero_point()
&& data.cluster_start // others are stored in detail buffer
}
fail_unless!(data.ligature_start); // can't compress ligature continuation glyphs.
fail_unless!(i < self.entry_buffer.len());
assert!(data.ligature_start); // can't compress ligature continuation glyphs.
assert!(i < self.entry_buffer.len());
let entry = match (data.is_missing, glyph_is_compressible(data)) {
(true, _) => MissingGlyphsEntry(1),
@ -535,8 +534,8 @@ pub impl GlyphStore {
}
fn add_glyphs_for_char_index(&mut self, i: uint, data_for_glyphs: &[GlyphData]) {
fail_unless!(i < self.entry_buffer.len());
fail_unless!(data_for_glyphs.len() > 0);
assert!(i < self.entry_buffer.len());
assert!(data_for_glyphs.len() > 0);
let glyph_count = data_for_glyphs.len();
@ -564,7 +563,7 @@ pub impl GlyphStore {
// used when a character index has no associated glyph---for example, a ligature continuation.
fn add_nonglyph_for_char_index(&mut self, i: uint, cluster_start: bool, ligature_start: bool) {
fail_unless!(i < self.entry_buffer.len());
assert!(i < self.entry_buffer.len());
let entry = ComplexGlyphEntry(cluster_start, ligature_start, 0);
debug!("adding spacer for chracter without associated glyph[idx=%u]", i);
@ -572,20 +571,20 @@ pub impl GlyphStore {
self.entry_buffer[i] = entry;
}
pure fn iter_glyphs_for_char_index(&self, i: uint, cb: &fn(uint, GlyphInfo/&self) -> bool) -> bool {
fail_unless!(i < self.entry_buffer.len());
fn iter_glyphs_for_char_index(&self, i: uint, cb: &fn(uint, &GlyphInfo<'self>) -> bool) -> bool {
assert!(i < self.entry_buffer.len());
let entry = &self.entry_buffer[i];
match entry.is_simple() {
true => {
let proxy = SimpleGlyphInfo(self, i);
let proxy = &SimpleGlyphInfo(self, i);
cb(i, proxy);
},
false => {
let glyphs = self.detail_store.get_detailed_glyphs_for_entry(i,
entry.glyph_count());
for uint::range(0, glyphs.len()) |j| {
let proxy = DetailGlyphInfo(self, i, j as u16);
let proxy = &DetailGlyphInfo(self, i, j as u16);
cb(i, proxy);
}
}
@ -593,7 +592,7 @@ pub impl GlyphStore {
return true;
}
pure fn iter_glyphs_for_char_range(&self, range: &const Range, cb: &fn(uint, GlyphInfo/&self) -> bool) {
fn iter_glyphs_for_char_range(&self, range: &Range, cb: &fn(uint, &GlyphInfo<'self>) -> bool) {
if range.begin() >= self.entry_buffer.len() {
error!("iter_glyphs_for_range: range.begin beyond length!");
return;
@ -608,64 +607,64 @@ pub impl GlyphStore {
}
}
pure fn iter_all_glyphs(&self, cb: &fn(uint, GlyphInfo/&self) -> bool) {
fn iter_all_glyphs(&self, cb: &fn(uint, &GlyphInfo<'self>) -> bool) {
for uint::range(0, self.entry_buffer.len()) |i| {
if !self.iter_glyphs_for_char_index(i, cb) { break; }
}
}
// getter methods
pure fn char_is_space(&self, i: uint) -> bool {
fail_unless!(i < self.entry_buffer.len());
fn char_is_space(&self, i: uint) -> bool {
assert!(i < self.entry_buffer.len());
self.entry_buffer[i].char_is_space()
}
pure fn char_is_tab(&self, i: uint) -> bool {
fail_unless!(i < self.entry_buffer.len());
fn char_is_tab(&self, i: uint) -> bool {
assert!(i < self.entry_buffer.len());
self.entry_buffer[i].char_is_tab()
}
pure fn char_is_newline(&self, i: uint) -> bool {
fail_unless!(i < self.entry_buffer.len());
fn char_is_newline(&self, i: uint) -> bool {
assert!(i < self.entry_buffer.len());
self.entry_buffer[i].char_is_newline()
}
pure fn is_ligature_start(&self, i: uint) -> bool {
fail_unless!(i < self.entry_buffer.len());
fn is_ligature_start(&self, i: uint) -> bool {
assert!(i < self.entry_buffer.len());
self.entry_buffer[i].is_ligature_start()
}
pure fn is_cluster_start(&self, i: uint) -> bool {
fail_unless!(i < self.entry_buffer.len());
fn is_cluster_start(&self, i: uint) -> bool {
assert!(i < self.entry_buffer.len());
self.entry_buffer[i].is_cluster_start()
}
pure fn can_break_before(&self, i: uint) -> BreakType {
fail_unless!(i < self.entry_buffer.len());
fn can_break_before(&self, i: uint) -> BreakType {
assert!(i < self.entry_buffer.len());
self.entry_buffer[i].can_break_before()
}
// setter methods
fn set_char_is_space(&mut self, i: uint) {
fail_unless!(i < self.entry_buffer.len());
assert!(i < self.entry_buffer.len());
let entry = self.entry_buffer[i];
self.entry_buffer[i] = entry.set_char_is_space();
}
fn set_char_is_tab(&mut self, i: uint) {
fail_unless!(i < self.entry_buffer.len());
assert!(i < self.entry_buffer.len());
let entry = self.entry_buffer[i];
self.entry_buffer[i] = entry.set_char_is_tab();
}
fn set_char_is_newline(&mut self, i: uint) {
fail_unless!(i < self.entry_buffer.len());
assert!(i < self.entry_buffer.len());
let entry = self.entry_buffer[i];
self.entry_buffer[i] = entry.set_char_is_newline();
}
fn set_can_break_before(&mut self, i: uint, t: BreakType) {
fail_unless!(i < self.entry_buffer.len());
assert!(i < self.entry_buffer.len());
let entry = self.entry_buffer[i];
self.entry_buffer[i] = entry.set_can_break_before(t);
}

View file

@ -10,22 +10,18 @@ use text::glyph::{GlyphStore, GlyphIndex, GlyphData};
use text::shaper::ShaperMethods;
use gfx_font::{FontHandleMethods, FontTableMethods};
use servo_util::range;
use util::range::Range;
use core::libc::types::common::c99::int32_t;
use core::libc::{c_uint, c_int, c_void, c_char};
use core::util::ignore;
//use dvec::DVec;
use std::arc;
use text::harfbuzz::shaper::harfbuzz::{HB_MEMORY_MODE_READONLY, HB_DIRECTION_LTR, hb_blob_t};
use text::harfbuzz::shaper::harfbuzz::{hb_face_t, hb_font_t};
use text::harfbuzz::shaper::harfbuzz::{hb_font_funcs_t, hb_buffer_t, hb_codepoint_t, hb_bool_t};
use text::harfbuzz::shaper::harfbuzz::{hb_glyph_position_t};
use text::harfbuzz::shaper::harfbuzz::{hb_glyph_info_t, hb_var_int_t, hb_position_t};
use text::harfbuzz::shaper::harfbuzz::bindgen::{hb_blob_create, hb_blob_destroy};
use text::harfbuzz::shaper::harfbuzz::bindgen::{hb_face_create, hb_face_destroy};
use text::harfbuzz::shaper::harfbuzz::{hb_glyph_info_t, hb_position_t};
use text::harfbuzz::shaper::harfbuzz::bindgen::hb_blob_create;
use text::harfbuzz::shaper::harfbuzz::bindgen::hb_face_destroy;
use text::harfbuzz::shaper::harfbuzz::bindgen::{hb_font_create, hb_font_destroy};
use text::harfbuzz::shaper::harfbuzz::bindgen::{hb_buffer_create};
use text::harfbuzz::shaper::harfbuzz::bindgen::{hb_buffer_destroy};
@ -40,14 +36,13 @@ use text::harfbuzz::shaper::harfbuzz::bindgen::{hb_font_funcs_destroy};
use text::harfbuzz::shaper::harfbuzz::bindgen::{hb_font_set_funcs};
use text::harfbuzz::shaper::harfbuzz::bindgen::{hb_font_funcs_set_glyph_h_advance_func};
use text::harfbuzz::shaper::harfbuzz::bindgen::{hb_font_funcs_set_glyph_func};
use text::harfbuzz::shaper::harfbuzz::bindgen::{hb_font_funcs_set_glyph_h_kerning_func};
use text::harfbuzz::shaper::harfbuzz::{HB_MEMORY_MODE_READONLY, HB_DIRECTION_LTR};
use text::harfbuzz::shaper::harfbuzz::{hb_blob_t, hb_face_t, hb_font_t, hb_font_funcs_t};
use text::harfbuzz::shaper::harfbuzz::{hb_buffer_t, hb_codepoint_t, hb_bool_t};
use text::harfbuzz::shaper::harfbuzz::{hb_glyph_position_t, hb_glyph_info_t, hb_var_int_t};
use text::harfbuzz::shaper::harfbuzz::{hb_glyph_position_t, hb_glyph_info_t};
use text::harfbuzz::shaper::harfbuzz::{hb_position_t, hb_tag_t};
use text::harfbuzz::shaper::harfbuzz::bindgen::{hb_blob_create, hb_blob_destroy,
use text::harfbuzz::shaper::harfbuzz::bindgen::{hb_blob_create,
hb_face_create_for_tables, hb_face_destroy,
hb_font_create, hb_font_destroy,
hb_buffer_create, hb_buffer_destroy,
@ -59,8 +54,7 @@ use text::harfbuzz::shaper::harfbuzz::bindgen::{hb_blob_create, hb_blob_destroy,
hb_font_funcs_create, hb_font_funcs_destroy,
hb_font_set_funcs,
hb_font_funcs_set_glyph_h_advance_func,
hb_font_funcs_set_glyph_func,
hb_font_funcs_set_glyph_h_kerning_func};
hb_font_funcs_set_glyph_func};
use text::util::{float_to_fixed, fixed_to_float, fixed_to_rounded_int};
@ -78,16 +72,16 @@ pub struct ShapedGlyphEntry {
}
pub impl ShapedGlyphData {
static pure fn new(buffer: *hb_buffer_t) -> ShapedGlyphData {
fn new(buffer: *hb_buffer_t) -> ShapedGlyphData {
unsafe {
let glyph_count = 0 as c_uint;
let glyph_infos = hb_buffer_get_glyph_infos(buffer, ptr::to_unsafe_ptr(&glyph_count));
let glyph_count = glyph_count as uint;
fail_unless!(glyph_infos.is_not_null());
assert!(glyph_infos.is_not_null());
let pos_count = 0 as c_uint;
let pos_infos = hb_buffer_get_glyph_positions(buffer, ptr::to_unsafe_ptr(&pos_count));
fail_unless!(pos_infos.is_not_null());
fail_unless!(glyph_count == pos_count as uint);
assert!(pos_infos.is_not_null());
assert!(glyph_count == pos_count as uint);
ShapedGlyphData {
count: glyph_count,
@ -98,8 +92,8 @@ pub impl ShapedGlyphData {
}
#[inline(always)]
priv pure fn byte_offset_of_glyph(&const self, i: uint) -> uint {
fail_unless!(i < self.count);
priv fn byte_offset_of_glyph(&self, i: uint) -> uint {
assert!(i < self.count);
let glyph_info_i = ptr::offset(self.glyph_infos, i);
unsafe {
@ -107,11 +101,11 @@ pub impl ShapedGlyphData {
}
}
pure fn len(&self) -> uint { self.count }
fn len(&self) -> uint { self.count }
// Returns shaped glyph data for one glyph, and updates the y-position of the pen.
fn get_entry_for_glyph(&self, i: uint, y_pos: &mut Au) -> ShapedGlyphEntry {
fail_unless!(i < self.count);
assert!(i < self.count);
let glyph_info_i = ptr::offset(self.glyph_infos, i);
let pos_info_i = ptr::offset(self.pos_infos, i);
@ -128,7 +122,7 @@ pub impl ShapedGlyphData {
*y_pos -= y_advance;
}
Some(Point2D(x_offset, y_pos - y_offset))
Some(Point2D(x_offset, *y_pos - y_offset))
};
unsafe {
@ -149,21 +143,22 @@ pub struct HarfbuzzShaper {
priv hb_funcs: *hb_font_funcs_t,
}
#[unsafe_destructor]
impl Drop for HarfbuzzShaper {
fn finalize(&self) {
fail_unless!(self.hb_face.is_not_null());
assert!(self.hb_face.is_not_null());
hb_face_destroy(self.hb_face);
fail_unless!(self.hb_font.is_not_null());
assert!(self.hb_font.is_not_null());
hb_font_destroy(self.hb_font);
fail_unless!(self.hb_funcs.is_not_null());
assert!(self.hb_funcs.is_not_null());
hb_font_funcs_destroy(self.hb_funcs);
}
}
pub impl HarfbuzzShaper {
static pub fn new(font: @mut Font) -> HarfbuzzShaper {
pub fn new(font: @mut Font) -> HarfbuzzShaper {
let hb_face: *hb_face_t = hb_face_create_for_tables(get_font_table_func, ptr::to_unsafe_ptr(font) as *c_void, ptr::null());
let hb_font: *hb_font_t = hb_font_create(hb_face);
// Set points-per-em. if zero, performs no hinting in that direction.
@ -192,15 +187,15 @@ pub impl HarfbuzzShaper {
}
}
static priv fn float_to_fixed(f: float) -> i32 {
priv fn float_to_fixed(f: float) -> i32 {
float_to_fixed(16, f)
}
static priv fn fixed_to_float(i: hb_position_t) -> float {
priv fn fixed_to_float(i: hb_position_t) -> float {
fixed_to_float(16, i)
}
static priv fn fixed_to_rounded_int(f: hb_position_t) -> int {
priv fn fixed_to_rounded_int(f: hb_position_t) -> int {
fixed_to_rounded_int(16, f)
}
}
@ -240,7 +235,7 @@ pub impl HarfbuzzShaper {
// so, we must be careful to increment this when saving glyph entries.
let mut char_idx = 0;
fail_unless!(glyph_count <= char_max);
assert!(glyph_count <= char_max);
debug!("Shaped text[char count=%u], got back %u glyph info records.", char_max, glyph_count);
if char_max != glyph_count {
@ -248,8 +243,8 @@ pub impl HarfbuzzShaper {
}
// make map of what chars have glyphs
const NO_GLYPH : i32 = -1;
const CONTINUATION_BYTE : i32 = -2;
static NO_GLYPH : i32 = -1;
static CONTINUATION_BYTE : i32 = -2;
let mut byteToGlyph : ~[i32];
// fast path: all chars are single-byte.
@ -271,7 +266,7 @@ pub impl HarfbuzzShaper {
// loc refers to a *byte* offset within the utf8 string.
let loc = glyph_data.byte_offset_of_glyph(i);
if loc < byte_max {
fail_unless!(byteToGlyph[loc] != CONTINUATION_BYTE);
assert!(byteToGlyph[loc] != CONTINUATION_BYTE);
byteToGlyph[loc] = i as i32;
}
else { debug!("ERROR: tried to set out of range byteToGlyph: idx=%u, glyph idx=%u", loc, i); }
@ -361,9 +356,9 @@ pub impl HarfbuzzShaper {
}
// character/glyph clump must contain characters.
fail_unless!(char_byte_span.length() > 0);
assert!(char_byte_span.length() > 0);
// character/glyph clump must contain glyphs.
fail_unless!(glyph_span.length() > 0);
assert!(glyph_span.length() > 0);
// now char_span is a ligature clump, formed by the glyphs in glyph_span.
// we need to find the chars that correspond to actual glyphs (char_extended_span),
@ -387,12 +382,15 @@ pub impl HarfbuzzShaper {
if covered_byte_span.begin() >= byte_max {
// oops, out of range. clip and forget this clump.
glyph_span.reset(glyph_span.end(), 0);
char_byte_span.reset(char_byte_span.end(), 0);
let end = glyph_span.end(); // FIXME: borrow checker workaround
glyph_span.reset(end, 0);
let end = char_byte_span.end(); // FIXME: borrow checker workaround
char_byte_span.reset(end, 0);
}
// clamp to end of text. (I don't think this will be necessary, but..)
covered_byte_span.extend_to(uint::min(covered_byte_span.end(), byte_max));
let end = covered_byte_span.end(); // FIXME: borrow checker workaround
covered_byte_span.extend_to(uint::min(end, byte_max));
// fast path: 1-to-1 mapping of single char and single glyph.
if glyph_span.length() == 1 {
@ -416,7 +414,6 @@ pub impl HarfbuzzShaper {
false, // not missing
true, // treat as cluster start
glyph_i > glyph_span.begin())); // all but first are ligature continuations
glyph_span.adjust_by(1,-1);
}
// now add the detailed glyph entry.
@ -435,8 +432,10 @@ pub impl HarfbuzzShaper {
}
// shift up our working spans past things we just handled.
glyph_span.reset(glyph_span.end(), 0);
char_byte_span.reset(char_byte_span.end(), 0);
let end = glyph_span.end(); // FIXME: borrow checker workaround
glyph_span.reset(end, 0);
let end = char_byte_span.end();; // FIXME: borrow checker workaround
char_byte_span.reset(end, 0);
char_idx += 1;
}
@ -454,7 +453,7 @@ extern fn glyph_func(_font: *hb_font_t,
glyph: *mut hb_codepoint_t,
_user_data: *c_void) -> hb_bool_t {
let font: *Font = font_data as *Font;
fail_unless!(font.is_not_null());
assert!(font.is_not_null());
unsafe {
return match (*font).glyph_index(unicode as char) {
Some(g) => { *glyph = g as hb_codepoint_t; true },
@ -468,7 +467,7 @@ extern fn glyph_h_advance_func(_font: *hb_font_t,
glyph: hb_codepoint_t,
_user_data: *c_void) -> hb_position_t {
let font: *Font = font_data as *Font;
fail_unless!(font.is_not_null());
assert!(font.is_not_null());
unsafe {
let advance = (*font).glyph_h_advance(glyph as GlyphIndex);
@ -480,7 +479,7 @@ extern fn glyph_h_advance_func(_font: *hb_font_t,
extern fn get_font_table_func(_face: *hb_face_t, tag: hb_tag_t, user_data: *c_void) -> *hb_blob_t {
unsafe {
let font: *Font = user_data as *Font;
fail_unless!(font.is_not_null());
assert!(font.is_not_null());
// TODO(Issue #197): reuse font table data, which will change the unsound trickery here.
match (*font).get_table_for_tag(tag as FontTableTag) {
@ -496,7 +495,7 @@ extern fn get_font_table_func(_face: *hb_face_t, tag: hb_tag_t, user_data: *c_vo
cast::transmute(skinny_font_table_ptr), // private context for below.
destroy_blob_func); // HarfBuzz calls this when blob not needed.
});
fail_unless!(blob.is_not_null());
assert!(blob.is_not_null());
return blob;
}
}

View file

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

View file

@ -1,15 +1,9 @@
use font_context::FontContext;
use geometry::Au;
use text::glyph::{BreakTypeNormal, GlyphStore};
use servo_gfx_font::{Font, FontDescriptor, RunMetrics, FontHandleMethods};
use servo_gfx_font::{Font, FontDescriptor, RunMetrics};
use servo_gfx_util::range::Range;
use core::libc::{c_void};
use geom::point::Point2D;
use geom::size::Size2D;
use std::arc;
use std::arc::ARC;
pub struct TextRun {
text: ~str,
font: @mut Font,
@ -40,7 +34,7 @@ impl SendableTextRun {
}
pub impl TextRun {
static fn new(font: @mut Font, text: ~str) -> TextRun {
fn new(font: @mut Font, text: ~str) -> TextRun {
let mut glyph_store = GlyphStore::new(str::char_len(text));
TextRun::compute_potential_breaks(text, &mut glyph_store);
font.shape_text(text, &mut glyph_store);
@ -53,7 +47,7 @@ pub impl TextRun {
return run;
}
static fn compute_potential_breaks(text: &str, glyphs: &mut GlyphStore) {
fn compute_potential_breaks(text: &str, glyphs: &mut GlyphStore) {
// TODO(Issue #230): do a better job. See Gecko's LineBreaker.
let mut byte_i = 0u;
@ -103,10 +97,10 @@ pub impl TextRun {
}
}
pure fn char_len(&self) -> uint { self.glyphs.entry_buffer.len() }
pure fn glyphs(&self) -> &self/GlyphStore { &self.glyphs }
fn char_len(&self) -> uint { self.glyphs.entry_buffer.len() }
fn glyphs(&self) -> &'self GlyphStore { &self.glyphs }
pure fn range_is_trimmable_whitespace(&self, range: &const Range) -> bool {
fn range_is_trimmable_whitespace(&self, range: &Range) -> bool {
for range.eachi |i| {
if !self.glyphs.char_is_space(i) &&
!self.glyphs.char_is_tab(i) &&
@ -115,11 +109,11 @@ pub impl TextRun {
return true;
}
fn metrics_for_range(&self, range: &const Range) -> RunMetrics {
fn metrics_for_range(&self, range: &Range) -> RunMetrics {
self.font.measure_text(self, range)
}
fn min_width_for_range(&self, range: &const Range) -> Au {
fn min_width_for_range(&self, range: &Range) -> Au {
let mut max_piece_width = Au(0);
debug!("iterating outer range %?", range);
for self.iter_indivisible_pieces_for_range(range) |piece_range| {
@ -130,7 +124,7 @@ pub impl TextRun {
return max_piece_width;
}
fn iter_natural_lines_for_range(&self, range: &const Range, f: &fn(&const Range) -> bool) {
fn iter_natural_lines_for_range(&self, range: &Range, f: &fn(&Range) -> bool) {
let mut clump = Range::new(range.begin(), 0);
let mut in_clump = false;
@ -143,7 +137,7 @@ pub impl TextRun {
(true, true) => {
in_clump = false;
// don't include the linebreak character itself in the clump.
if !f(&const clump) { break }
if !f(&clump) { break }
}
}
}
@ -151,11 +145,11 @@ pub impl TextRun {
// flush any remaining chars as a line
if in_clump {
clump.extend_to(range.end());
f(&const clump);
f(&clump);
}
}
fn iter_indivisible_pieces_for_range(&self, range: &const Range, f: &fn(&const Range) -> bool) {
fn iter_indivisible_pieces_for_range(&self, range: &Range, f: &fn(&Range) -> bool) {
let mut clump = Range::new(range.begin(), 0);
loop {
@ -167,10 +161,11 @@ pub impl TextRun {
}
// now clump.end() is break-before or range.end()
if !f(&const clump) || clump.end() == range.end() { break; }
if !f(&clump) || clump.end() == range.end() { break; }
// now clump includes one break-before character, or starts from range.end()
clump.reset(clump.end(), 1);
let end = clump.end(); // FIXME: borrow checker workaround
clump.reset(end, 1);
}
}
}

View file

@ -6,7 +6,7 @@ enum CompressionMode {
}
impl Eq for CompressionMode {
pure fn eq(&self, other: &CompressionMode) -> bool {
fn eq(&self, other: &CompressionMode) -> bool {
match (*self, *other) {
(CompressNone, CompressNone) => true,
(CompressWhitespace, CompressWhitespace) => true,
@ -15,7 +15,7 @@ impl Eq for CompressionMode {
_ => false
}
}
pure fn ne(&self, other: &CompressionMode) -> bool {
fn ne(&self, other: &CompressionMode) -> bool {
!(*self).eq(other)
}
}

View file

@ -1,10 +1,8 @@
use core::cmp::*;
pub trait Cache<K: Copy + Eq, V: Copy> {
static fn new(size: uint) -> Self;
fn new(size: uint) -> Self;
fn insert(&mut self, key: &K, value: V);
fn find(&self, key: &K) -> Option<V>;
fn find_or_create(&mut self, key: &K, blk: &pure fn(&K) -> V) -> V;
fn find_or_create(&mut self, key: &K, blk: &fn(&K) -> V) -> V;
fn evict_all(&mut self);
}
@ -13,7 +11,7 @@ pub struct MonoCache<K, V> {
}
impl<K: Copy + Eq, V: Copy> Cache<K,V> for MonoCache<K,V> {
static fn new(_size: uint) -> MonoCache<K,V> {
fn new(_size: uint) -> MonoCache<K,V> {
MonoCache { entry: None }
}
@ -28,7 +26,7 @@ impl<K: Copy + Eq, V: Copy> Cache<K,V> for MonoCache<K,V> {
}
}
fn find_or_create(&mut self, key: &K, blk: &pure fn(&K) -> V) -> V {
fn find_or_create(&mut self, key: &K, blk: &fn(&K) -> V) -> V {
return match self.find(key) {
None => {
let value = blk(key);
@ -51,9 +49,9 @@ fn test_monocache() {
let two = @"two";
cache.insert(&1, one);
fail_unless!(cache.find(&1).is_some());
fail_unless!(cache.find(&2).is_none());
assert!(cache.find(&1).is_some());
assert!(cache.find(&2).is_none());
cache.find_or_create(&2, |_v| { two });
fail_unless!(cache.find(&2).is_some());
fail_unless!(cache.find(&1).is_none());
assert!(cache.find(&2).is_some());
assert!(cache.find(&1).is_none());
}

View file

@ -14,28 +14,28 @@ pub struct Range {
}
pub impl Range {
static pub pure fn new(off: uint, len: uint) -> Range {
pub fn new(off: uint, len: uint) -> Range {
Range { off: off, len: len }
}
static pub pure fn empty() -> Range {
pub fn empty() -> Range {
Range::new(0, 0)
}
}
pub impl Range {
pure fn begin(&const self) -> uint { self.off }
pure fn length(&const self) -> uint { self.len }
pure fn end(&const self) -> uint { self.off + self.len }
pure fn eachi(&const self, cb: &fn(uint) -> bool) {
fn begin(&self) -> uint { self.off }
fn length(&self) -> uint { self.len }
fn end(&self) -> uint { self.off + self.len }
fn eachi(&self, cb: &fn(uint) -> bool) {
do uint::range(self.off, self.off + self.len) |i| { cb(i) }
}
pure fn contains(&const self, i: uint) -> bool {
fn contains(&self, i: uint) -> bool {
i >= self.begin() && i < self.end()
}
pure fn is_valid_for_string(&const self, s: &str) -> bool {
fn is_valid_for_string(&self, s: &str) -> bool {
self.begin() < s.len() && self.end() <= s.len() && self.length() <= s.len()
}
@ -64,7 +64,7 @@ pub impl Range {
/// Computes the relationship between two ranges (`self` and `other`),
/// from the point of view of `self`. So, 'EntirelyBefore' means
/// that the `self` range is entirely before `other` range.
pure fn relation_to_range(&const self, other: &const Range) -> RangeRelation {
fn relation_to_range(&self, other: &Range) -> RangeRelation {
if other.begin() > self.end() {
return EntirelyBefore;
}
@ -92,7 +92,7 @@ pub impl Range {
self, other));
}
fn repair_after_coalesced_range(&mut self, other: &const Range) {
fn repair_after_coalesced_range(&mut self, other: &Range) {
let relation = self.relation_to_range(other);
debug!("repair_after_coalesced_range: possibly repairing range %?", self);
debug!("repair_after_coalesced_range: relation of original range and coalesced range(%?): %?",

View file

@ -1,7 +1,6 @@
use core::path::Path;
use std::net::url;
use std::net::url::Url;
use std::oldmap::HashMap;
use core::hashmap::HashMap;
/**
Create a URL object from a string. Does various helpful browsery things like
@ -26,7 +25,11 @@ pub fn make_url(str_url: ~str, current_url: Option<Url>) -> Url {
if current_url.path.is_empty() || current_url.path.ends_with("/") {
current_url.scheme + "://" + current_url.host + "/" + str_url
} else {
let path = str::split_char(current_url.path, '/');
let mut path = ~[];
for str::each_split_char(current_url.path, '/') |p| {
path.push(p.to_str());
}
let path = path; // FIXME: borrow checker workaround
let path = path.init();
let path = str::connect(path.map(|x| copy *x) + ~[str_url], "/");
@ -98,10 +101,8 @@ mod make_url_tests {
}
pub type UrlMap<T> = HashMap<Url, T>;
pub type UrlMap<T> = @mut HashMap<Url, T>;
pub fn url_map<T: Copy>() -> UrlMap<T> {
use core::to_str::ToStr;
HashMap::<Url, T>()
@mut HashMap::new()
}

View file

@ -1,19 +1,19 @@
use core::cmp::{Ord, Eq};
pub trait BinarySearchMethods<T: Ord + Eq> {
pure fn binary_search(&self, key: &T) -> Option<&self/T>;
pure fn binary_search_index(&self, key: &T) -> Option<uint>;
fn binary_search(&self, key: &T) -> Option<&'self T>;
fn binary_search_index(&self, key: &T) -> Option<uint>;
}
impl<'self, T: Ord + Eq> BinarySearchMethods<T> for &'self [T] {
pure fn binary_search(&self, key: &T) -> Option<&self/T> {
fn binary_search(&self, key: &T) -> Option<&'self T> {
match self.binary_search_index(key) {
None => None,
Some(i) => Some(&self[i])
}
}
pure fn binary_search_index(&self, key: &T) -> Option<uint> {
fn binary_search_index(&self, key: &T) -> Option<uint> {
if self.len() == 0 {
return None;
}
@ -41,7 +41,7 @@ impl<'self, T: Ord + Eq> BinarySearchMethods<T> for &'self [T] {
fn test_find_all_elems<T: Eq + Ord>(arr: &[T]) {
let mut i = 0;
while i < arr.len() {
fail_unless!(test_match(&arr[i], arr.binary_search(&arr[i])));
assert!(test_match(&arr[i], arr.binary_search(&arr[i])));
i += 1;
}
}
@ -51,7 +51,7 @@ fn test_miss_all_elems<T: Eq + Ord>(arr: &[T], misses: &[T]) {
while i < misses.len() {
let res = arr.binary_search(&misses[i]);
debug!("%? == %? ?", misses[i], res);
fail_unless!(!test_match(&misses[i], arr.binary_search(&misses[i])));
assert!(!test_match(&misses[i], arr.binary_search(&misses[i])));
i += 1;
}
}

View file

@ -3,8 +3,6 @@ The content task is the main task that runs JavaScript and spawns layout
tasks.
*/
use dom::bindings::utils::rust_box;
use dom::bindings::utils::CacheableWrapper;
use dom::bindings::utils::GlobalStaticData;
use dom::document::Document;
use dom::node::define_bindings;
@ -13,29 +11,25 @@ use dom::window::Window;
use layout::layout_task;
use layout::layout_task::{AddStylesheet, BuildData, BuildMsg, Damage, LayoutTask};
use layout::layout_task::{MatchSelectorsDamage, NoDamage, ReflowDamage};
use util::task::spawn_listener;
use core::cell::Cell;
use core::comm::{Port, Chan, SharedChan};
use core::comm::{Port, SharedChan};
use core::pipes::select2i;
use core::either;
use core::task::{SingleThreaded, spawn, task};
use core::task::{SingleThreaded, task};
use core::io::{println, read_whole_file};
use core::ptr::null;
use core::util::replace;
use geom::size::Size2D;
use gfx::resource::image_cache_task::ImageCacheTask;
use gfx::resource::resource_task::ResourceTask;
use gfx::util::url::make_url;
use js::JSVAL_NULL;
use js::global::{global_class, debug_fns};
use js::glue::bindgen::RUST_JSVAL_TO_OBJECT;
use js::jsapi::{JSContext, JSVal};
use js::jsapi::JSContext;
use js::jsapi::bindgen::{JS_CallFunctionValue, JS_GetContextPrivate};
use js::rust::{Compartment, Cx};
use jsrt = js::rust::rt;
use newcss::stylesheet::Stylesheet;
use std::arc::{ARC, clone};
use std::net::url::Url;
use url_to_str = std::net::url::to_str;
use dom;
@ -223,7 +217,7 @@ pub impl Content {
self.window = Some(window);
self.doc_url = Some(url);
let compartment = option::expect(self.compartment, ~"TODO error checking");
let compartment = self.compartment.expect(~"TODO error checking");
compartment.define_functions(debug_fns);
define_bindings(compartment, document, window);
@ -235,7 +229,7 @@ pub impl Content {
}
Timer(timerData) => {
let compartment = option::expect(self.compartment, ~"TODO error checking");
let compartment = self.compartment.expect(~"TODO error checking");
let thisValue = if timerData.args.len() > 0 {
RUST_JSVAL_TO_OBJECT(timerData.args[0])
} else {
@ -258,7 +252,7 @@ pub impl Content {
println(fmt!("Error opening %s: %s", url_to_str(&url), msg));
}
Ok(bytes) => {
let compartment = option::expect(self.compartment, ~"TODO error checking");
let compartment = self.compartment.expect(~"TODO error checking");
compartment.define_functions(debug_fns);
self.cx.evaluate_script(compartment.global_obj, bytes, copy url.path, 1u);
}
@ -349,7 +343,7 @@ pub impl Content {
// Nothing to do.
}
Some(document) => {
fail_unless!(self.doc_url.is_some());
assert!(self.doc_url.is_some());
self.relayout(document, &(copy self.doc_url).get());
}
}
@ -364,7 +358,7 @@ pub impl Content {
// Nothing to do.
}
Some(document) => {
fail_unless!(self.doc_url.is_some());
assert!(self.doc_url.is_some());
self.relayout(document, &(copy self.doc_url).get());
}
}

View file

@ -3,12 +3,9 @@
use css::node_util::NodeUtil;
use css::select_handler::NodeSelectHandler;
use dom::node::AbstractNode;
use layout::context::LayoutContext;
use newcss::complete::CompleteSelectResults;
use newcss::select::{SelectCtx, SelectResults};
use std::arc::{ARC, get, clone};
pub trait MatchMethods {
fn restyle_subtree(&self, select_ctx: &SelectCtx);
}

View file

@ -6,12 +6,12 @@ use newcss::complete::CompleteStyle;
/// Node mixin providing `style` method that returns a `NodeStyle`
pub trait StyledNode {
fn style(&self) -> CompleteStyle/&self;
fn style(&self) -> CompleteStyle<'self>;
}
impl StyledNode for AbstractNode {
fn style(&self) -> CompleteStyle/&self {
fail_unless!(self.is_element()); // Only elements can have styles
fn style(&self) -> CompleteStyle<'self> {
assert!(self.is_element()); // Only elements can have styles
let results = self.get_css_select_results();
results.computed_style()
}

View file

@ -3,8 +3,8 @@ use newcss::complete::CompleteSelectResults;
use core::cast::transmute;
pub trait NodeUtil {
fn get_css_select_results(self) -> &self/CompleteSelectResults;
pub trait NodeUtil<'self> {
fn get_css_select_results(self) -> &'self CompleteSelectResults;
fn set_css_select_results(self, decl: CompleteSelectResults);
}
@ -16,7 +16,7 @@ impl<'self> NodeUtil<'self> for AbstractNode {
* FIXME: This isn't completely memory safe since the style is
* stored in a box that can be overwritten
*/
fn get_css_select_results(self) -> &self/CompleteSelectResults {
fn get_css_select_results(self) -> &'self CompleteSelectResults {
if !self.has_layout_data() {
fail!(~"style() called on a node without aux data!");
}

View file

@ -1,16 +1,16 @@
//! CSS library requires that DOM nodes be convertable to *c_void through this trait
extern mod netsurfcss;
use dom::node::AbstractNode;
use core::cast;
// FIXME: Rust #3908. rust-css can't reexport VoidPtrLike
extern mod netsurfcss;
use css::node_void_ptr::netsurfcss::util::VoidPtrLike;
impl VoidPtrLike for AbstractNode {
static fn from_void_ptr(node: *libc::c_void) -> AbstractNode {
fail_unless!(node.is_not_null());
fn from_void_ptr(node: *libc::c_void) -> AbstractNode {
assert!(node.is_not_null());
unsafe {
cast::transmute(node)
}

View file

@ -4,12 +4,12 @@ use dom::bindings::codegen::ClientRectBinding;
use js::jsapi::{JSObject, JSContext};
pub trait ClientRect {
fn Top() -> f32;
fn Bottom() -> f32;
fn Left() -> f32;
fn Right() -> f32;
fn Width() -> f32;
fn Height() -> f32;
fn Top(&self) -> f32;
fn Bottom(&self) -> f32;
fn Left(&self) -> f32;
fn Right(&self) -> f32;
fn Width(&self) -> f32;
fn Height(&self) -> f32;
}
pub struct ClientRectImpl {
@ -21,27 +21,27 @@ pub struct ClientRectImpl {
}
impl ClientRect for ClientRectImpl {
fn Top() -> f32 {
fn Top(&self) -> f32 {
self.top
}
fn Bottom() -> f32 {
fn Bottom(&self) -> f32 {
self.bottom
}
fn Left() -> f32 {
fn Left(&self) -> f32 {
self.left
}
fn Right() -> f32 {
fn Right(&self) -> f32 {
self.right
}
fn Width() -> f32 {
fn Width(&self) -> f32 {
f32::abs(self.right - self.left)
}
fn Height() -> f32 {
fn Height(&self) -> f32 {
f32::abs(self.bottom - self.top)
}
}
@ -63,7 +63,7 @@ impl CacheableWrapper for ClientRectImpl {
ClientRectBinding::Wrap(cx, scope, self, &mut unused)
}
fn wrap_object_shared(@self, cx: *JSContext, scope: *JSObject) -> *JSObject {
fn wrap_object_shared(@self, _cx: *JSContext, _scope: *JSObject) -> *JSObject {
fail!(~"nyi")
}
}

View file

@ -2,8 +2,6 @@ use content::content_task::task_from_context;
use dom::bindings::clientrect::{ClientRect, ClientRectImpl};
use dom::bindings::codegen::ClientRectListBinding;
use dom::bindings::utils::{WrapperCache, CacheableWrapper, BindingObject, OpaqueBindingReference};
use dom::window::Window;
use dom::bindings::window::Window;
use js::jsapi::{JSObject, JSContext};
pub trait ClientRectList {
@ -37,8 +35,8 @@ impl ClientRectList for ClientRectListImpl {
}
}
impl ClientRectListImpl {
static fn new() -> ClientRectListImpl {
pub impl ClientRectListImpl {
fn new() -> ClientRectListImpl {
ClientRectListImpl {
wrapper: WrapperCache::new(),
rects: ~[(5.6, 80.2, 3.7, 4.8), (800.1, 8001.1, -50.000001, -45.01)]
@ -56,7 +54,7 @@ impl CacheableWrapper for ClientRectListImpl {
ClientRectListBinding::Wrap(cx, scope, self, &mut unused)
}
fn wrap_object_shared(@self, cx: *JSContext, scope: *JSObject) -> *JSObject {
fn wrap_object_shared(@self, _cx: *JSContext, _scope: *JSObject) -> *JSObject {
fail!(~"nyi")
}
}

View file

@ -1856,7 +1856,7 @@ class PropertyDefiner:
specs.append(specTerminator)
prefableSpecs.append(" { false, NULL }");
arrays = (("const %s: [%s * %i] = [\n" +
arrays = (("static %s: [%s, ..%i] = [\n" +
',\n'.join(specs) + "\n" +
"];\n\n") % (name, specType, len(specs)))
#+
@ -1864,7 +1864,7 @@ class PropertyDefiner:
#',\n'.join(prefableSpecs) + "\n" +
#"];\n\n")
if doIdArrays:
arrays += ("const %s_ids: [jsid * %i] = [" % (name, len(specs))) + ", ".join(["JSID_VOID"] * len(specs)) + "];\n\n"
arrays += ("static %s_ids: [jsid, ..%i] = [" % (name, len(specs))) + ", ".join(["JSID_VOID"] * len(specs)) + "];\n\n"
return arrays
# The length of a method is the maximum of the lengths of the
@ -1945,7 +1945,7 @@ class MethodDefiner(PropertyDefiner):
return (m["name"], accessor, jitinfo, m["length"], m["flags"])
def stringDecl(m):
return "const %s_name: [u8 * %i] = %s;\n" % (m["name"], len(m["name"]) + 1,
return "static %s_name: [u8, ..%i] = %s;\n" % (m["name"], len(m["name"]) + 1,
str_to_const_array(m["name"]))
decls = ''.join([stringDecl(m) for m in array])
@ -1992,7 +1992,7 @@ class AttrDefiner(PropertyDefiner):
def stringDecl(attr):
name = attr.identifier.name
return "const %s_name: [u8 * %i] = %s;\n" % (name, len(name) + 1,
return "static %s_name: [u8, ..%i] = %s;\n" % (name, len(name) + 1,
str_to_const_array(name))
decls = ''.join([stringDecl(m) for m in array])
@ -2024,7 +2024,7 @@ class ConstDefiner(PropertyDefiner):
def stringDecl(const):
name = const.identifier.name
return "const %s_name: [u8 * %i] = %s;\n" % (name, len(name) + 1,
return "static %s_name: [u8, ..%i] = %s;\n" % (name, len(name) + 1,
str_to_const_array(name))
decls = ''.join([stringDecl(m) for m in array])
@ -2060,7 +2060,7 @@ class CGNativePropertyHooks(CGThing):
parentHooks = ("&" + toBindingNamespace(parent.identifier.name) + "::NativeHooks"
if parent else '0 as *NativePropertyHooks')
return """
const NativeHooks: NativePropertyHooks = NativePropertyHooks { resolve_own_property: /*%s*/ 0 as *u8, resolve_property: ResolveProperty, enumerate_own_properties: /*%s*/ 0 as *u8, enumerate_properties: /*EnumerateProperties*/ 0 as *u8, proto_hooks: %s };
static NativeHooks: NativePropertyHooks = NativePropertyHooks { resolve_own_property: /*%s*/ 0 as *u8, resolve_property: ResolveProperty, enumerate_own_properties: /*%s*/ 0 as *u8, enumerate_properties: /*EnumerateProperties*/ 0 as *u8, proto_hooks: %s };
""" % (resolveOwnProperty, enumerateOwnProperties, parentHooks)
# We'll want to insert the indent at the beginnings of lines, but we
@ -2142,9 +2142,9 @@ class CGImports(CGWrapper):
# TODO imports to cover descriptors, etc.
def _useString(imports):
return ''.join(['use %s;\n' % i for i in imports]) + '\n'
return '#[allow(unused_imports)];' + ''.join(['use %s;\n' % i for i in imports]) + '\n'
CGWrapper.__init__(self, child,
definePre=_useString(sorted(defineImports)))
declarePre=_useString(sorted(declareImports)))
class CGIfWrapper(CGWrapper):
def __init__(self, child, condition):
@ -2197,8 +2197,8 @@ class CGDOMJSClass(CGThing):
def define(self):
traceHook = TRACE_HOOK_NAME if self.descriptor.customTrace else '0 as *u8'
return """
const Class_name: [u8 * %i] = %s;
const Class: DOMJSClass = DOMJSClass {
static Class_name: [u8, ..%i] = %s;
static Class: DOMJSClass = DOMJSClass {
base: JSClass { name: &Class_name as *u8 as *libc::c_char,
flags: JSCLASS_IS_DOMJSCLASS | ((1 & JSCLASS_RESERVED_SLOTS_MASK) << JSCLASS_RESERVED_SLOTS_SHIFT), //JSCLASS_HAS_RESERVED_SLOTS(1),
addProperty: %s, /* addProperty */
@ -2243,8 +2243,9 @@ class CGPrototypeJSClass(CGThing):
# We're purely for internal consumption
return ""
def define(self):
return """const PrototypeClassName__: [u8 * %s] = %s;
const PrototypeClass: JSClass = JSClass {
return """
static PrototypeClassName__: [u8, ..%s] = %s;
static PrototypeClass: JSClass = JSClass {
name: &PrototypeClassName__ as *u8 as *libc::c_char,
flags: (1 & JSCLASS_RESERVED_SLOTS_MASK) << JSCLASS_RESERVED_SLOTS_SHIFT, //JSCLASS_HAS_RESERVED_SLOTS(1)
addProperty: crust::JS_PropertyStub, /* addProperty */
@ -2285,7 +2286,7 @@ class CGInterfaceObjectJSClass(CGThing):
ctorname = "0 as *u8" if not self.descriptor.interface.ctor() else CONSTRUCT_HOOK_NAME
hasinstance = HASINSTANCE_HOOK_NAME
return """
const InterfaceObjectClass: JSClass = {
static InterfaceObjectClass: JSClass = {
%s, 0,
crust::JS_PropertyStub, /* addProperty */
crust::JS_PropertyStub, /* delProperty */
@ -3149,7 +3150,7 @@ class CGSpecializedMethod(CGAbstractExternMethod):
def __init__(self, descriptor, method):
self.method = method
name = method.identifier.name
args = [Argument('*JSContext', 'cx'), Argument('JSHandleObject', '++obj'),
args = [Argument('*JSContext', 'cx'), Argument('JSHandleObject', 'obj'),
Argument('*%s' % descriptor.nativeType, 'self'),
Argument('libc::c_uint', 'argc'), Argument('*mut JSVal', 'vp')]
CGAbstractExternMethod.__init__(self, descriptor, name, 'JSBool', args)
@ -3194,7 +3195,7 @@ class CGSpecializedGetter(CGAbstractExternMethod):
self.attr = attr
name = 'get_' + attr.identifier.name
args = [ Argument('*JSContext', 'cx'),
Argument('JSHandleObject', '++obj'),
Argument('JSHandleObject', 'obj'),
Argument('*%s' % descriptor.nativeType, 'self'),
Argument('*mut JSVal', 'vp') ]
CGAbstractExternMethod.__init__(self, descriptor, name, "JSBool", args)
@ -3245,7 +3246,7 @@ class CGMemberJITInfo(CGThing):
depth = self.descriptor.interface.inheritanceDepth()
failstr = "true" if infallible else "false"
return ("\n"
"const %s: JSJitInfo = JSJitInfo {\n"
"static %s: JSJitInfo = JSJitInfo {\n"
" op: %s,\n"
" protoID: %s,\n"
" depth: %s,\n"
@ -3690,7 +3691,7 @@ class CGDOMJSProxyHandlerDOMClass(CGThing):
return ""
def define(self):
return """
const Class: DOMClass = """ + DOMClass(self.descriptor) + """;
static Class: DOMClass = """ + DOMClass(self.descriptor) + """;
"""
@ -3847,7 +3848,6 @@ class CGBindingRoot(CGThing):
# Add imports
curr = CGImports(descriptors,
dictionaries,
[],
['js::*',
'js::jsapi::*',
'js::jsapi::bindgen::*',
@ -3863,6 +3863,7 @@ class CGBindingRoot(CGThing):
'dom::bindings::proxyhandler::*',
'content::content_task::task_from_context'
],
[],
curr)
# Add the auto-generated comment.

View file

@ -3,7 +3,7 @@ use js::glue::bindgen::{RUST_INT_TO_JSVAL, RUST_JSVAL_TO_INT};
pub trait JSValConvertible<T> {
fn to_jsval(&self) -> JSVal;
static fn from_jsval(val: JSVal) -> Option<T>;
fn from_jsval(val: JSVal) -> Option<T>;
}
impl JSValConvertible<u32> for u32 {
@ -11,7 +11,7 @@ impl JSValConvertible<u32> for u32 {
RUST_INT_TO_JSVAL(*self as i32)
}
static fn from_jsval(val: JSVal) -> Option<u32> {
fn from_jsval(val: JSVal) -> Option<u32> {
Some(RUST_JSVAL_TO_INT(val) as u32)
}
}

View file

@ -1,27 +1,23 @@
use js::rust::{Compartment, jsobj};
use js::{JS_ARGV, JSCLASS_HAS_RESERVED_SLOTS, JSPROP_ENUMERATE, JSPROP_SHARED,
use js::{JS_ARGV, JSPROP_ENUMERATE, JSPROP_SHARED,
JSVAL_NULL, JS_THIS_OBJECT, JS_SET_RVAL, JSPROP_NATIVE_ACCESSORS};
use js::jsapi::{JSContext, JSVal, JSObject, JSBool, jsid, JSClass, JSFreeOp,
use js::jsapi::{JSContext, JSVal, JSObject, JSBool, JSFreeOp,
JSPropertySpec, JSPropertyOpWrapper, JSStrictPropertyOpWrapper,
JSNativeWrapper, JSFunctionSpec};
use js::jsapi::bindgen::{JS_ValueToString, JS_GetStringCharsZAndLength, JS_ReportError,
JS_GetReservedSlot, JS_SetReservedSlot, JS_NewStringCopyN,
JS_DefineFunctions, JS_DefineProperty, JS_DefineProperties};
use js::jsapi::bindgen::{JS_GetReservedSlot, JS_SetReservedSlot,
JS_DefineFunctions, JS_DefineProperties};
use js::glue::bindgen::*;
use js::glue::{PROPERTY_STUB, STRICT_PROPERTY_STUB};
use js::crust::{JS_PropertyStub, JS_StrictPropertyStub, JS_EnumerateStub, JS_ConvertStub, JS_ResolveStub};
use core::ptr::null;
use core::libc::c_uint;
use dom::bindings::utils::{DOMString, domstring_to_jsval, rust_box, squirrel_away, str};
use dom::bindings::utils::{DOMString, rust_box, squirrel_away, str};
use dom::bindings::utils::{jsval_to_str, WrapNewBindingObject, CacheableWrapper};
use dom::bindings::utils::WrapperCache;
use dom::bindings::node::create;
use dom::document::Document;
use dom::bindings::htmlcollection::HTMLCollection;
use dom::bindings::node;
use dom::bindings::utils;
use dom::node::Node;
extern fn getDocumentElement(cx: *JSContext, _argc: c_uint, vp: *mut JSVal) -> JSBool {
unsafe {
@ -36,7 +32,7 @@ extern fn getDocumentElement(cx: *JSContext, _argc: c_uint, vp: *mut JSVal) -> J
}
}
extern fn getElementsByTagName(cx: *JSContext, argc: c_uint, vp: *JSVal) -> JSBool {
extern fn getElementsByTagName(cx: *JSContext, _argc: c_uint, vp: *JSVal) -> JSBool {
unsafe {
let obj = JS_THIS_OBJECT(cx, vp);
@ -56,7 +52,7 @@ extern fn getElementsByTagName(cx: *JSContext, argc: c_uint, vp: *JSVal) -> JSBo
JS_SET_RVAL(cx, vp, JSVAL_NULL);
} else {
let cache = doc.get_wrappercache();
fail_unless!(WrapNewBindingObject(cx, cache.get_wrapper(),
assert!(WrapNewBindingObject(cx, cache.get_wrapper(),
rval.get(),
cast::transmute(vp)));
}
@ -96,7 +92,7 @@ pub fn init(compartment: @mut Compartment, doc: @mut Document) {
setter: JSStrictPropertyOpWrapper {op: null(), info: null()}}];
vec::push(&mut compartment.global_props, attrs);
vec::as_imm_buf(*attrs, |specs, _len| {
fail_unless!(JS_DefineProperties(compartment.cx.ptr, obj.ptr, specs) == 1);
assert!(JS_DefineProperties(compartment.cx.ptr, obj.ptr, specs) == 1);
});
let methods = @~[JSFunctionSpec {name: compartment.add_name(~"getElementsByTagName"),
@ -136,11 +132,11 @@ impl CacheableWrapper for Document {
unsafe { cast::transmute(&self.wrapper) }
}
fn wrap_object_unique(~self, cx: *JSContext, scope: *JSObject) -> *JSObject {
fn wrap_object_unique(~self, _cx: *JSContext, _scope: *JSObject) -> *JSObject {
fail!(~"need to implement wrapping");
}
fn wrap_object_shared(@self, cx: *JSContext, scope: *JSObject) -> *JSObject {
fn wrap_object_shared(@self, _cx: *JSContext, _scope: *JSObject) -> *JSObject {
fail!(~"need to implement wrapping");
}
}

View file

@ -1,23 +1,20 @@
use content::content_task::{Content, task_from_context};
use dom::bindings::utils::{rust_box, squirrel_away_unique, get_compartment};
use content::content_task::task_from_context;
use dom::bindings::utils::{domstring_to_jsval, WrapNewBindingObject};
use dom::bindings::utils::{str, CacheableWrapper, DOM_OBJECT_SLOT};
use dom::bindings::clientrectlist::ClientRectListImpl;
use dom::element::*;
use dom::node::{AbstractNode, Node, Element, ElementNodeTypeId};
use dom::node::{AbstractNode, Element, ElementNodeTypeId};
use layout::layout_task;
use super::utils;
use core::libc::c_uint;
use core::ptr::null;
use js::crust::{JS_PropertyStub, JS_StrictPropertyStub, JS_EnumerateStub, JS_ConvertStub};
use js::glue::bindgen::*;
use js::jsapi::bindgen::*;
use js::jsapi::{JSContext, JSVal, JSObject, JSBool, jsid, JSClass, JSFreeOp, JSPropertySpec};
use js::jsapi::{JSContext, JSVal, JSObject, JSBool, JSFreeOp, JSPropertySpec};
use js::jsapi::{JSPropertyOpWrapper, JSStrictPropertyOpWrapper, JSFunctionSpec};
use js::jsapi::JSNativeWrapper;
use js::rust::{Compartment, jsobj};
use js::{JS_ARGV, JSCLASS_HAS_RESERVED_SLOTS, JSPROP_ENUMERATE, JSPROP_SHARED, JSVAL_NULL};
use js::{JS_ARGV, JSPROP_ENUMERATE, JSPROP_SHARED, JSVAL_NULL};
use js::{JS_THIS_OBJECT, JS_SET_RVAL, JSPROP_NATIVE_ACCESSORS};
extern fn finalize(_fop: *JSFreeOp, obj: *JSObject) {
@ -25,7 +22,7 @@ extern fn finalize(_fop: *JSFreeOp, obj: *JSObject) {
unsafe {
let val = JS_GetReservedSlot(obj, DOM_OBJECT_SLOT as u32);
let node: AbstractNode = cast::reinterpret_cast(&RUST_JSVAL_TO_PRIVATE(val));
let elem: ~Element = cast::transmute(node.raw_object());
let _elem: ~Element = cast::transmute(node.raw_object());
}
}
@ -89,7 +86,7 @@ pub fn init(compartment: @mut Compartment) {
});
}
extern fn getClientRects(cx: *JSContext, argc: c_uint, vp: *JSVal) -> JSBool {
extern fn getClientRects(cx: *JSContext, _argc: c_uint, vp: *JSVal) -> JSBool {
unsafe {
let obj = JS_THIS_OBJECT(cx, vp);
let mut box = utils::unwrap::<*mut AbstractNode>(obj);
@ -101,7 +98,7 @@ extern fn getClientRects(cx: *JSContext, argc: c_uint, vp: *JSVal) -> JSBool {
JS_SET_RVAL(cx, vp, JSVAL_NULL);
} else {
let cache = node.get_wrappercache();
fail_unless!(WrapNewBindingObject(cx, cache.get_wrapper(),
assert!(WrapNewBindingObject(cx, cache.get_wrapper(),
rval.get(),
cast::transmute(vp)));
}

View file

@ -1,5 +1,4 @@
use content::content_task::task_from_context;
use dom::element::Element;
use dom::node::AbstractNode;
use dom::bindings::codegen::HTMLCollectionBinding;
use dom::bindings::utils::{DOMString, ErrorResult, OpaqueBindingReference};
@ -12,7 +11,7 @@ pub struct HTMLCollection {
}
pub impl HTMLCollection {
static fn new(elements: ~[AbstractNode]) -> HTMLCollection {
fn new(elements: ~[AbstractNode]) -> HTMLCollection {
HTMLCollection {
elements: elements,
wrapper: WrapperCache::new()
@ -31,7 +30,7 @@ pub impl HTMLCollection {
}
}
fn NamedItem(&self, cx: *JSContext, name: DOMString, rv: &mut ErrorResult) -> *JSObject {
fn NamedItem(&self, _cx: *JSContext, _name: DOMString, rv: &mut ErrorResult) -> *JSObject {
*rv = Ok(());
ptr::null()
}
@ -59,7 +58,7 @@ impl CacheableWrapper for HTMLCollection {
HTMLCollectionBinding::Wrap(cx, scope, self, &mut unused)
}
fn wrap_object_shared(@self, cx: *JSContext, scope: *JSObject) -> *JSObject {
fn wrap_object_shared(@self, _cx: *JSContext, _scope: *JSObject) -> *JSObject {
fail!(~"nyi")
}
}

View file

@ -1,25 +1,20 @@
use dom::bindings::utils::{rust_box, squirrel_away_unique, get_compartment};
use dom::bindings::utils::{str, domstring_to_jsval, CacheableWrapper, WrapperCache};
use dom::bindings::utils::{CacheableWrapper, WrapperCache};
use dom::bindings::utils::{DOM_OBJECT_SLOT};
use dom::node::{AbstractNode, Node, ElementNodeTypeId, TextNodeTypeId, CommentNodeTypeId};
use dom::node::{DoctypeNodeTypeId};
use super::element;
use super::utils;
use core::cast::transmute;
use core::libc::c_uint;
use core::ptr::null;
use js::glue::bindgen::*;
use js::jsapi::bindgen::*;
use js::jsapi::bindgen::{JS_DefineFunctions, JS_DefineProperty, JS_GetContextPrivate};
use js::jsapi::bindgen::{JS_GetReservedSlot, JS_SetReservedSlot, JS_NewStringCopyN};
use js::jsapi::bindgen::{JS_ValueToString, JS_GetStringCharsZAndLength, JS_ReportError};
use js::jsapi::{JSContext, JSVal, JSObject, JSBool, jsid, JSClass, JSFreeOp, JSPropertySpec};
use js::jsapi::{JSContext, JSVal, JSObject, JSBool, JSPropertySpec};
use js::jsapi::{JSPropertyOpWrapper, JSStrictPropertyOpWrapper};
use js::jsval::{INT_TO_JSVAL, JSVAL_TO_PRIVATE};
use js::rust::{Compartment, jsobj};
use js::{JS_ARGV, JSCLASS_HAS_RESERVED_SLOTS, JSPROP_ENUMERATE, JSPROP_SHARED, JSVAL_NULL};
use js::{JS_THIS_OBJECT, JS_SET_RVAL, JSPROP_NATIVE_ACCESSORS};
use js::{JSPROP_ENUMERATE, JSPROP_SHARED, JSVAL_NULL};
use js::{JS_THIS_OBJECT, JSPROP_NATIVE_ACCESSORS};
use js;
pub fn init(compartment: @mut Compartment) {
@ -172,11 +167,11 @@ impl CacheableWrapper for AbstractNode {
}
}
fn wrap_object_unique(~self, cx: *JSContext, scope: *JSObject) -> *JSObject {
fn wrap_object_unique(~self, _cx: *JSContext, _scope: *JSObject) -> *JSObject {
fail!(~"need to implement wrapping");
}
fn wrap_object_shared(@self, cx: *JSContext, scope: *JSObject) -> *JSObject {
fn wrap_object_shared(@self, _cx: *JSContext, _scope: *JSObject) -> *JSObject {
fail!(~"need to implement wrapping");
}
}

View file

@ -1,6 +1,5 @@
use js::jsapi::{JSContext, jsid, JSPropertyDescriptor, JSObject, JSString, jschar};
use js::jsapi::bindgen::{JS_GetPropertyDescriptorById, JS_GetPrototype};
use js::jsapi::bindgen::{JS_NewUCString, JS_malloc, JS_free};
use js::jsapi::bindgen::{JS_GetPropertyDescriptorById, JS_NewUCString, JS_malloc, JS_free};
use js::glue::bindgen::{RUST_JSVAL_IS_VOID, RUST_JSVAL_TO_OBJECT, GetProxyExtra};
use js::glue::bindgen::{GetObjectProto};
@ -31,7 +30,7 @@ pub extern fn getPropertyDescriptor(cx: *JSContext, proxy: *JSObject, id: jsid,
}
fn _getOwnPropertyDescriptor(cx: *JSContext, proxy: *JSObject, id: jsid,
set: c_bool, desc: *mut JSPropertyDescriptor) -> c_bool {
_set: c_bool, desc: *mut JSPropertyDescriptor) -> c_bool {
unsafe {
let v = GetProxyExtra(proxy, 0 /*JSPROXYSLOT_EXPANDO*/);
if RUST_JSVAL_IS_VOID(v) == 0 {
@ -77,6 +76,6 @@ pub fn _obj_toString(cx: *JSContext, className: *libc::c_char) -> *JSString {
}
}
pub fn GetExpandoObject(proxy: *JSObject) -> *JSObject {
pub fn GetExpandoObject(_proxy: *JSObject) -> *JSObject {
ptr::null()
}

View file

@ -1,18 +1,18 @@
use js;
use js::rust::Compartment;
use js::{JS_ARGV, JSCLASS_HAS_RESERVED_SLOTS, JSPROP_ENUMERATE, JSPROP_SHARED, JSVAL_NULL,
JS_THIS_OBJECT, JS_SET_RVAL, JSFUN_CONSTRUCTOR, JS_CALLEE, JSPROP_READONLY,
use js::{JSCLASS_HAS_RESERVED_SLOTS, JSPROP_ENUMERATE, JSVAL_NULL,
JS_THIS_OBJECT, JSFUN_CONSTRUCTOR, JS_CALLEE, JSPROP_READONLY,
JSPROP_PERMANENT, JSID_VOID, JSPROP_NATIVE_ACCESSORS, JSPROP_GETTER, JSPROP_SETTER};
use js::jsapi::{JSContext, JSVal, JSObject, JSBool, jsid, JSClass, JSFreeOp, JSNative,
JSFunctionSpec, JSPropertySpec, JSVal, JSString, JSPropertyDescriptor};
use js::jsapi::bindgen::{JS_ValueToString, JS_GetStringCharsZAndLength, JS_ReportError,
use js::jsapi::{JSContext, JSVal, JSObject, JSBool, jsid, JSClass, JSNative,
JSFunctionSpec, JSPropertySpec, JSVal, JSPropertyDescriptor};
use js::jsapi::bindgen::{JS_ValueToString,
JS_GetReservedSlot, JS_SetReservedSlot, JS_NewStringCopyN,
JS_DefineFunctions, JS_DefineProperty, JS_GetContextPrivate,
JS_DefineFunctions, JS_DefineProperty,
JS_GetClass, JS_GetPrototype, JS_LinkConstructorAndPrototype,
JS_AlreadyHasOwnProperty, JS_NewObject, JS_NewFunction,
JS_GetFunctionPrototype, JS_InternString, JS_GetFunctionObject,
JS_GetInternedStringCharsAndLength, JS_DefineProperties,
JS_WrapValue, JS_GetObjectPrototype, JS_ForwardGetPropertyTo,
JS_DefineProperties,
JS_WrapValue, JS_ForwardGetPropertyTo,
JS_HasPropertyById, JS_GetPrototype, JS_GetGlobalForObject,
JS_EncodeString, JS_free};
use js::jsfriendapi::bindgen::JS_NewObjectWithUniqueType;
@ -22,33 +22,33 @@ use js::glue::{PROPERTY_STUB, STRICT_PROPERTY_STUB, ENUMERATE_STUB, CONVERT_STUB
use js::glue::bindgen::*;
use core::ptr::null;
use core::cast;
use content::content_task::{Content, task_from_context};
use content::content_task::task_from_context;
use core::hashmap::linear;
use core::hashmap::HashMap;
use dom::bindings::node;
use dom::node::AbstractNode;
const TOSTRING_CLASS_RESERVED_SLOT: u64 = 0;
const TOSTRING_NAME_RESERVED_SLOT: u64 = 1;
static TOSTRING_CLASS_RESERVED_SLOT: u64 = 0;
static TOSTRING_NAME_RESERVED_SLOT: u64 = 1;
struct GlobalStaticData {
proxy_handlers: linear::LinearMap<uint, *libc::c_void>,
attribute_ids: linear::LinearMap<uint, ~[jsid]>,
method_ids: linear::LinearMap<uint, ~[jsid]>,
constant_ids: linear::LinearMap<uint, ~[jsid]>
proxy_handlers: HashMap<uint, *libc::c_void>,
attribute_ids: HashMap<uint, ~[jsid]>,
method_ids: HashMap<uint, ~[jsid]>,
constant_ids: HashMap<uint, ~[jsid]>
}
pub fn GlobalStaticData() -> GlobalStaticData {
GlobalStaticData {
proxy_handlers: linear::LinearMap::new(),
attribute_ids: linear::LinearMap::new(),
method_ids: linear::LinearMap::new(),
constant_ids: linear::LinearMap::new()
proxy_handlers: HashMap::new(),
attribute_ids: HashMap::new(),
method_ids: HashMap::new(),
constant_ids: HashMap::new()
}
}
extern fn InterfaceObjectToString(cx: *JSContext, argc: uint, vp: *mut JSVal) -> JSBool {
extern fn InterfaceObjectToString(cx: *JSContext, _argc: uint, vp: *mut JSVal) -> JSBool {
unsafe {
let callee = RUST_JSVAL_TO_OBJECT(*JS_CALLEE(cx, cast::transmute(&vp)));
let obj = JS_THIS_OBJECT(cx, cast::transmute(&vp));
@ -160,10 +160,9 @@ pub unsafe fn domstring_to_jsval(cx: *JSContext, string: &DOMString) -> JSVal {
pub fn get_compartment(cx: *JSContext) -> @mut Compartment {
unsafe {
let content = task_from_context(cx);
let compartment = option::expect((*content).compartment,
~"Should always have compartment when \
executing JS code");
fail_unless!(cx == compartment.cx.ptr);
let compartment = (*content).compartment.expect(~"Should always have compartment when \
executing JS code");
assert!(cx == compartment.cx.ptr);
compartment
}
}
@ -270,23 +269,23 @@ pub fn define_empty_prototype(name: ~str, proto: Option<~str>, compartment: @mut
// We use slot 0 for holding the raw object. This is safe for both
// globals and non-globals.
pub const DOM_OBJECT_SLOT: uint = 0;
const DOM_PROXY_OBJECT_SLOT: uint = js::JSSLOT_PROXY_PRIVATE as uint;
pub static DOM_OBJECT_SLOT: uint = 0;
static DOM_PROXY_OBJECT_SLOT: uint = js::JSSLOT_PROXY_PRIVATE as uint;
// NOTE: This is baked into the Ion JIT as 0 in codegen for LGetDOMProperty and
// LSetDOMProperty. Those constants need to be changed accordingly if this value
// changes.
const DOM_PROTO_INSTANCE_CLASS_SLOT: u32 = 0;
static DOM_PROTO_INSTANCE_CLASS_SLOT: u32 = 0;
// All DOM globals must have a slot at DOM_PROTOTYPE_SLOT. We have to
// start at 1 past JSCLASS_GLOBAL_SLOT_COUNT because XPConnect uses
// that one.
pub const DOM_PROTOTYPE_SLOT: u32 = js::JSCLASS_GLOBAL_SLOT_COUNT + 1;
pub static DOM_PROTOTYPE_SLOT: u32 = js::JSCLASS_GLOBAL_SLOT_COUNT + 1;
// NOTE: This is baked into the Ion JIT as 0 in codegen for LGetDOMProperty and
// LSetDOMProperty. Those constants need to be changed accordingly if this value
// changes.
const JSCLASS_DOM_GLOBAL: u32 = js::JSCLASS_USERBIT1;
static JSCLASS_DOM_GLOBAL: u32 = js::JSCLASS_USERBIT1;
pub struct NativeProperties {
staticMethods: *JSFunctionSpec,
@ -330,7 +329,7 @@ pub struct ConstantSpec {
pub struct DOMClass {
// A list of interfaces that this object implements, in order of decreasing
// derivedness.
interface_chain: [prototypes::id::Prototype * 2 /*max prototype chain length*/],
interface_chain: [prototypes::id::Prototype, ..2 /*max prototype chain length*/],
unused: bool, // DOMObjectIsISupports (always false)
native_hooks: *NativePropertyHooks
@ -418,7 +417,7 @@ fn CreateInterfaceObject(cx: *JSContext, global: *JSObject, receiver: *JSObject,
JS_NewObject(cx, constructorClass, functionProto, global)
}
} else {
fail_unless!(constructorNative.is_not_null());
assert!(constructorNative.is_not_null());
let fun = JS_NewFunction(cx, constructorNative, ctorNargs,
JSFUN_CONSTRUCTOR, global, name);
if fun.is_null() {
@ -535,13 +534,13 @@ fn CreateInterfacePrototypeObject(cx: *JSContext, global: *JSObject,
return ourProto;
}
pub extern fn ThrowingConstructor(cx: *JSContext, argc: uint, vp: *JSVal) -> JSBool {
pub extern fn ThrowingConstructor(_cx: *JSContext, _argc: uint, _vp: *JSVal) -> JSBool {
//XXX should trigger exception here
return 0;
}
pub fn initialize_global(global: *JSObject) {
let protoArray = @mut [0 as *JSObject, ..3]; //XXXjdm prototypes::_ID_COUNT
let protoArray = @mut ~[0 as *JSObject, ..3]; //XXXjdm prototypes::_ID_COUNT
unsafe {
//XXXjdm we should be storing the box pointer instead of the inner
let box = squirrel_away(protoArray);
@ -571,7 +570,7 @@ pub impl WrapperCache {
unsafe { self.wrapper = wrapper; }
}
static fn new() -> WrapperCache {
fn new() -> WrapperCache {
WrapperCache {
wrapper: ptr::null()
}
@ -642,7 +641,7 @@ pub impl<T: BindingObject + CacheableWrapper> BindingReference<T> {
}
}
fn get_wrappercache(&mut self) -> &self/mut WrapperCache {
fn get_wrappercache(&mut self) -> &mut WrapperCache {
match **self {
Left(ref mut obj) => obj.get_wrappercache(),
Right(ref mut obj) => obj.get_wrappercache()
@ -684,7 +683,7 @@ pub fn GetPropertyOnPrototype(cx: *JSContext, proxy: *JSObject, id: jsid, found:
}
}
pub fn GetArrayIndexFromId(cx: *JSContext, id: jsid) -> Option<u32> {
pub fn GetArrayIndexFromId(_cx: *JSContext, id: jsid) -> Option<u32> {
if RUST_JSID_IS_INT(id) != 0 {
return Some(RUST_JSID_TO_INT(id) as u32);
}
@ -709,9 +708,9 @@ pub fn XrayResolveProperty(cx: *JSContext,
wrapper: *JSObject,
id: jsid,
desc: *mut JSPropertyDescriptor,
methods: Option<~[(JSFunctionSpec, jsid)]>,
_methods: Option<~[(JSFunctionSpec, jsid)]>,
attributes: Option<~[(JSPropertySpec, jsid)]>,
constants: Option<~[(ConstantSpec, jsid)]>) -> bool
_constants: Option<~[(ConstantSpec, jsid)]>) -> bool
{
unsafe {
match attributes {
@ -785,7 +784,7 @@ pub trait DerivedWrapper {
}
impl DerivedWrapper for AbstractNode {
fn wrap(&mut self, cx: *JSContext, scope: *JSObject, vp: *mut JSVal) -> i32 {
fn wrap(&mut self, cx: *JSContext, _scope: *JSObject, vp: *mut JSVal) -> i32 {
let cache = self.get_wrappercache();
let wrapper = cache.get_wrapper();
if wrapper.is_not_null() {

View file

@ -1,34 +1,30 @@
// DOM bindings for the Window object.
use dom::bindings::node::create;
use dom::bindings::utils::{rust_box, squirrel_away, jsval_to_str, CacheableWrapper};
use dom::bindings::utils::{rust_box, squirrel_away, CacheableWrapper};
use dom::bindings::utils::{WrapperCache};
use dom::node::Node;
use dom::window::{Window, TimerMessage_Fire};
use dom::window::Window;
use super::utils;
use core::libc::c_uint;
use core::ptr::null;
use core::ptr;
use js::crust::{JS_PropertyStub, JS_StrictPropertyStub, JS_EnumerateStub, JS_ConvertStub};
use js::crust::{JS_ResolveStub};
use js::crust::{JS_PropertyStub, JS_StrictPropertyStub};
use js::global::jsval_to_rust_str;
use js::glue::bindgen::*;
use js::glue::bindgen::RUST_JSVAL_TO_INT;
use js::jsapi::bindgen::{JS_DefineFunctions, JS_DefineProperty, JS_DefineProperties};
use js::jsapi::bindgen::{JS_EncodeString, JS_free};
use js::jsapi::bindgen::{JS_GetReservedSlot, JS_SetReservedSlot, JS_NewStringCopyN};
use js::jsapi::bindgen::{JS_ValueToString, JS_GetStringCharsZAndLength, JS_ReportError};
use js::jsapi::{JSContext, JSVal, JSObject, JSBool, jsid, JSClass, JSFreeOp, JSFunctionSpec};
use js::jsapi::bindgen::{JS_DefineFunctions};
use js::jsapi::bindgen::{JS_GetReservedSlot, JS_SetReservedSlot};
use js::jsapi::bindgen::{JS_ValueToString};
use js::jsapi::{JSContext, JSVal, JSObject, JSBool, JSFreeOp, JSFunctionSpec};
use js::jsapi::{JSNativeWrapper};
use js::rust::Compartment;
use js::{JS_ARGV, JSCLASS_HAS_RESERVED_SLOTS, JSPROP_ENUMERATE, JSPROP_SHARED, JSVAL_NULL};
use js::{JS_ARGV, JSPROP_ENUMERATE, JSVAL_NULL};
use js::{JS_THIS_OBJECT, JS_SET_RVAL};
extern fn alert(cx: *JSContext, argc: c_uint, vp: *JSVal) -> JSBool {
unsafe {
let argv = JS_ARGV(cx, vp);
fail_unless!(argc == 1);
assert!(argc == 1);
// Abstract this pattern and use it in debug, too?
let jsstr = JS_ValueToString(cx, *ptr::offset(argv, 0));
@ -42,7 +38,7 @@ extern fn alert(cx: *JSContext, argc: c_uint, vp: *JSVal) -> JSBool {
extern fn setTimeout(cx: *JSContext, argc: c_uint, vp: *JSVal) -> JSBool {
unsafe {
let argv = JS_ARGV(cx, vp);
fail_unless!(argc >= 2);
assert!(argc >= 2);
//TODO: don't crash when passed a non-integer value for the timeout
@ -137,11 +133,11 @@ impl CacheableWrapper for Window {
unsafe { cast::transmute(&self.wrapper) }
}
fn wrap_object_unique(~self, cx: *JSContext, scope: *JSObject) -> *JSObject {
fn wrap_object_unique(~self, _cx: *JSContext, _scope: *JSObject) -> *JSObject {
fail!(~"should this be called?");
}
fn wrap_object_shared(@self, cx: *JSContext, scope: *JSObject) -> *JSObject {
fn wrap_object_shared(@self, _cx: *JSContext, _scope: *JSObject) -> *JSObject {
fail!(~"should this be called?");
}
}

View file

@ -1,9 +1,7 @@
use dom::bindings::htmlcollection::HTMLCollection;
use dom::bindings::utils::{DOMString, WrapperCache, str};
use dom::node::AbstractNode;
use newcss::stylesheet::Stylesheet;
use std::arc::ARC;
pub struct Document {
root: AbstractNode,

View file

@ -15,7 +15,7 @@ pub struct Element {
attrs: ~[Attr],
}
#[deriving_eq]
#[deriving(Eq)]
pub enum ElementTypeId {
HTMLAnchorElementTypeId,
HTMLAsideElementTypeId,
@ -109,7 +109,7 @@ pub struct HTMLImageElement {
//
pub impl Element {
static pub fn new(type_id: ElementTypeId, tag_name: ~str) -> Element {
pub fn new(type_id: ElementTypeId, tag_name: ~str) -> Element {
Element {
parent: Node::new(ElementNodeTypeId(type_id)),
tag_name: tag_name,
@ -117,7 +117,7 @@ pub impl Element {
}
}
fn get_attr(&self, name: &str) -> Option<&self/str> {
fn get_attr(&self, name: &str) -> Option<&'self str> {
// FIXME: Need an each() that links lifetimes in Rust.
for uint::range(0, self.attrs.len()) |i| {
if eq_slice(self.attrs[i].name, name) {
@ -151,7 +151,7 @@ pub struct Attr {
}
impl Attr {
static pub fn new(name: ~str, value: ~str) -> Attr {
pub fn new(name: ~str, value: ~str) -> Attr {
Attr {
name: name,
value: value

View file

@ -12,16 +12,9 @@ use dom::window::Window;
use layout::debug::DebugMethods;
use layout::flow::FlowContext;
use newcss::complete::CompleteSelectResults;
use js::rust::Compartment;
use core::cast::transmute;
use core::ptr::null;
use geom::size::Size2D;
use js::crust::*;
use js::glue::bindgen::RUST_OBJECT_TO_JSVAL;
use js::jsapi::{JSClass, JSObject, JSPropertySpec, JSContext, jsid, JSVal, JSBool};
use js::jsapi::bindgen::JS_SetReservedSlot;
use js::rust::Compartment;
use std::arc::ARC;
//
// The basic Node structure
@ -36,8 +29,8 @@ pub struct AbstractNode {
}
impl Eq for AbstractNode {
pure fn eq(&self, other: &AbstractNode) -> bool { self.obj == other.obj }
pure fn ne(&self, other: &AbstractNode) -> bool { self.obj != other.obj }
fn eq(&self, other: &AbstractNode) -> bool { self.obj == other.obj }
fn ne(&self, other: &AbstractNode) -> bool { self.obj != other.obj }
}
pub struct Node {
@ -54,7 +47,7 @@ pub struct Node {
priv layout_data: Option<@mut LayoutData>
}
#[deriving_eq]
#[deriving(Eq)]
pub enum NodeTypeId {
DoctypeNodeTypeId,
CommentNodeTypeId,
@ -72,7 +65,7 @@ pub struct LayoutData {
}
impl LayoutData {
static pub fn new() -> LayoutData {
pub fn new() -> LayoutData {
LayoutData {
style: None,
flow: None,
@ -93,11 +86,11 @@ pub struct Doctype {
}
impl Doctype {
static pub fn new(name: ~str,
public_id: Option<~str>,
system_id: Option<~str>,
force_quirks: bool)
-> Doctype {
pub fn new(name: ~str,
public_id: Option<~str>,
system_id: Option<~str>,
force_quirks: bool)
-> Doctype {
Doctype {
parent: Node::new(DoctypeNodeTypeId),
name: name,
@ -114,7 +107,7 @@ pub struct Comment {
}
impl Comment {
static pub fn new(text: ~str) -> Comment {
pub fn new(text: ~str) -> Comment {
Comment {
parent: Node::new(CommentNodeTypeId),
text: text
@ -128,7 +121,7 @@ pub struct Text {
}
impl Text {
static pub fn new(text: ~str) -> Text {
pub fn new(text: ~str) -> Text {
Text {
parent: Node::new(TextNodeTypeId),
text: text
@ -171,13 +164,13 @@ pub impl AbstractNode {
// Invariant: `child` is disconnected from the document.
fn append_child(self, child: AbstractNode) {
fail_unless!(self != child);
assert!(self != child);
do self.with_mut_node |parent_n| {
do child.with_mut_node |child_n| {
fail_unless!(child_n.parent_node.is_none());
fail_unless!(child_n.prev_sibling.is_none());
fail_unless!(child_n.next_sibling.is_none());
assert!(child_n.parent_node.is_none());
assert!(child_n.prev_sibling.is_none());
assert!(child_n.next_sibling.is_none());
child_n.parent_node = Some(self);
@ -185,7 +178,7 @@ pub impl AbstractNode {
None => parent_n.first_child = Some(child),
Some(last_child) => {
do last_child.with_mut_node |last_child_n| {
fail_unless!(last_child_n.next_sibling.is_none());
assert!(last_child_n.next_sibling.is_none());
last_child_n.next_sibling = Some(child);
}
}
@ -323,12 +316,12 @@ pub impl AbstractNode {
impl DebugMethods for AbstractNode {
// Dumps the subtree rooted at this node, for debugging.
pure fn dump(&self) {
fn dump(&self) {
self.dump_indent(0);
}
// Dumps the node tree, for debugging, with indentation.
pure fn dump_indent(&self, indent: uint) {
fn dump_indent(&self, indent: uint) {
let mut s = ~"";
for uint::range(0u, indent) |_i| {
s += ~" ";
@ -345,7 +338,7 @@ impl DebugMethods for AbstractNode {
}
}
pure fn debug_str(&self) -> ~str {
fn debug_str(&self) -> ~str {
// Unsafe due to the call to type_id().
unsafe {
fmt!("%?", self.type_id())
@ -354,14 +347,14 @@ impl DebugMethods for AbstractNode {
}
impl Node {
static pub unsafe fn as_abstract_node<N>(node: ~N) -> AbstractNode {
pub unsafe fn as_abstract_node<N>(node: ~N) -> AbstractNode {
// This surrenders memory management of the node!
AbstractNode {
obj: transmute(node),
}
}
static pub fn new(type_id: NodeTypeId) -> Node {
pub fn new(type_id: NodeTypeId) -> Node {
Node {
wrapper: WrapperCache::new(),
type_id: type_id,
@ -384,13 +377,13 @@ pub fn define_bindings(compartment: @mut Compartment, doc: @mut Document, win: @
bindings::element::init(compartment);
bindings::utils::initialize_global(compartment.global_obj.ptr);
let mut unused = false;
fail_unless!(codegen::ClientRectBinding::DefineDOMInterface(compartment.cx.ptr,
compartment.global_obj.ptr,
&mut unused));
fail_unless!(codegen::ClientRectListBinding::DefineDOMInterface(compartment.cx.ptr,
compartment.global_obj.ptr,
&mut unused));
fail_unless!(codegen::HTMLCollectionBinding::DefineDOMInterface(compartment.cx.ptr,
compartment.global_obj.ptr,
&mut unused));
assert!(codegen::ClientRectBinding::DefineDOMInterface(compartment.cx.ptr,
compartment.global_obj.ptr,
&mut unused));
assert!(codegen::ClientRectListBinding::DefineDOMInterface(compartment.cx.ptr,
compartment.global_obj.ptr,
&mut unused));
assert!(codegen::HTMLCollectionBinding::DefineDOMInterface(compartment.cx.ptr,
compartment.global_obj.ptr,
&mut unused));
}

View file

@ -1,6 +1,6 @@
use content::content_task::{ControlMsg, Timer, ExitMsg};
use dom::bindings::utils::WrapperCache;
use js::jsapi::{JSVal, JSObject};
use js::jsapi::JSVal;
use util::task::spawn_listener;
use core::comm::{Port, Chan};

View file

@ -1,4 +1,4 @@
use content::content_task::{ContentTask, ExecuteMsg, ParseMsg, ExitMsg};
use content::content_task::{ContentTask, ExecuteMsg, ParseMsg};
use content::content_task;
use dom::event::Event;
use layout::layout_task;

View file

@ -5,13 +5,11 @@ Some little helpers for hooking up the HTML parser with the CSS parser
use resource::resource_task::{ResourceTask, ProgressMsg, Load, Payload, Done};
use core::cell::Cell;
use core::comm::{Port, Chan};
use core::pipes;
use core::comm::Port;
use core::str;
use newcss::stylesheet::Stylesheet;
use newcss::util::DataStream;
use std::net::url::Url;
use std::net::url;
/// Where a style sheet comes from.
pub enum StylesheetProvenance {

View file

@ -1,19 +1,16 @@
use content::content_task::ContentTask;
use dom::element::*;
use dom::event::{Event, ReflowEvent};
use dom::node::{AbstractNode, Comment, Doctype, Element, ElementNodeTypeId, Node, Text};
use html::cssparse::{InlineProvenance, StylesheetProvenance, UrlProvenance, spawn_css_parser};
use newcss::stylesheet::Stylesheet;
use resource::image_cache_task::ImageCacheTask;
use resource::image_cache_task;
use resource::resource_task::{Done, Load, Payload, ResourceTask};
use util::task::{spawn_listener, spawn_conversation};
use util::task::spawn_conversation;
use core::cell::Cell;
use core::comm::{Chan, Port, SharedChan};
use core::str::eq_slice;
use gfx::util::url::make_url;
use hubbub::hubbub::Attribute;
use hubbub::hubbub;
use std::net::url::Url;
use std::net::url;
@ -21,11 +18,11 @@ use std::net::url;
macro_rules! handle_element(
($tag:expr, $string:expr, $ctor:ident, $type_id:expr) => (
if eq_slice($tag, $string) {
let element = ~$ctor {
let _element = ~$ctor {
parent: Element::new($type_id, ($tag).to_str())
};
unsafe {
return Node::as_abstract_node(element);
return Node::as_abstract_node(_element);
}
}
)
@ -34,12 +31,12 @@ macro_rules! handle_element(
macro_rules! handle_heading_element(
($tag:expr, $string:expr, $ctor:ident, $type_id:expr, $level:expr) => (
if eq_slice($tag, $string) {
let element = ~HTMLHeadingElement {
let _element = ~HTMLHeadingElement {
parent: Element::new($type_id, ($tag).to_str()),
level: $level
};
unsafe {
return Node::as_abstract_node(element);
return Node::as_abstract_node(_element);
}
}
)
@ -65,14 +62,14 @@ struct HtmlParserResult {
trait NodeWrapping {
unsafe fn to_hubbub_node(self) -> hubbub::NodeDataPtr;
static unsafe fn from_hubbub_node(n: hubbub::NodeDataPtr) -> Self;
unsafe fn from_hubbub_node(n: hubbub::NodeDataPtr) -> Self;
}
impl NodeWrapping for AbstractNode {
unsafe fn to_hubbub_node(self) -> hubbub::NodeDataPtr {
cast::transmute(self)
}
static unsafe fn from_hubbub_node(n: hubbub::NodeDataPtr) -> AbstractNode {
unsafe fn from_hubbub_node(n: hubbub::NodeDataPtr) -> AbstractNode {
cast::transmute(n)
}
}
@ -221,7 +218,6 @@ pub fn parse_html(url: Url,
};
let css_chan = SharedChan(css_chan);
let resource_task2 = resource_task.clone();
// Spawn a JS parser to receive JavaScript.
let resource_task2 = resource_task.clone();
let (js_port, js_chan): (Port<JSResult>, Chan<JSMessage>) =
@ -231,7 +227,7 @@ pub fn parse_html(url: Url,
};
let js_chan = SharedChan(js_chan);
let url = @url;
let url2 = url.clone(), url3 = url.clone();
unsafe {
// Build the root node.
@ -247,7 +243,7 @@ pub fn parse_html(url: Url,
// consists of processing inline stylesheets, but in the future it might perform
// prefetching, etc.
let css_chan2 = css_chan.clone();
let append_hook: @fn(AbstractNode, AbstractNode) = |parent_node, child_node| {
let append_hook: ~fn(AbstractNode, AbstractNode) = |parent_node, child_node| {
if parent_node.is_style_element() && child_node.is_text() {
debug!("found inline CSS stylesheet");
let url = url::from_str("http://example.com/"); // FIXME
@ -261,7 +257,7 @@ pub fn parse_html(url: Url,
};
let (css_chan2, js_chan2) = (css_chan.clone(), js_chan.clone());
parser.set_tree_handler(@hubbub::TreeHandler {
parser.set_tree_handler(~hubbub::TreeHandler {
create_comment: |data: ~str| {
debug!("create comment");
unsafe {
@ -310,7 +306,7 @@ pub fn parse_html(url: Url,
(Some(rel), Some(href)) => {
if rel == ~"stylesheet" {
debug!("found CSS stylesheet: %s", href);
let url = make_url(href.to_str(), Some(copy *url));
let url = make_url(href.to_str(), Some(url2.clone()));
css_chan2.send(CSSTaskNewFile(UrlProvenance(url)));
}
}
@ -324,7 +320,7 @@ pub fn parse_html(url: Url,
match src_opt {
None => {}
Some(src) => {
let img_url = make_url(src, Some(copy *url));
let img_url = make_url(src, Some(url2.clone()));
image_element.image = Some(copy img_url);
// inform the image cache to load this, but don't store a handle.
// TODO (Issue #84): don't prefetch if we are within a <noscript>
@ -368,7 +364,7 @@ pub fn parse_html(url: Url,
debug!("remove child");
0u
},
clone_node: |node, deep| {
clone_node: |_node, deep| {
debug!("clone node");
unsafe {
if deep { error!("-- deep clone unimplemented"); }
@ -403,7 +399,7 @@ pub fn parse_html(url: Url,
// A little function for holding this lint attr
#[allow(non_implicitly_copyable_typarams)]
fn complete_script(script: hubbub::NodeDataPtr,
url: &Url,
url: Url,
js_chan: SharedChan<JSMessage>) {
unsafe {
let script: AbstractNode = NodeWrapping::from_hubbub_node(script);
@ -411,7 +407,7 @@ pub fn parse_html(url: Url,
match script.get_attr(~"src") {
Some(src) => {
debug!("found script: %s", src);
let new_url = make_url(src.to_str(), Some(copy *url));
let new_url = make_url(src.to_str(), Some(url.clone()));
js_chan.send(JSTaskNewFile(new_url));
}
None => {}
@ -419,14 +415,14 @@ pub fn parse_html(url: Url,
}
}
}
complete_script(script, url, js_chan2.clone());
complete_script(script, url3.clone(), js_chan2.clone());
debug!("complete script");
}
});
debug!("set tree handler");
let (input_port, input_chan) = comm::stream();
resource_task.send(Load(copy *url, input_chan));
resource_task.send(Load(url.clone(), input_chan));
debug!("loaded page");
loop {
match input_port.recv() {

View file

@ -1,18 +1,16 @@
// Block layout.
use core::cell::Cell;
use layout::box::{RenderBox};
use layout::context::LayoutContext;
use layout::display_list_builder::{DisplayListBuilder, FlowDisplayListBuilderMethods};
use layout::flow::{FlowContext, FlowTree, InlineBlockFlow, BlockFlow, RootFlow};
use layout::inline::InlineLayout;
use newcss::values::*;
use util::tree;
use au = gfx::geometry;
use core::mutable::Mut;
use geom::point::Point2D;
use geom::rect::Rect;
use geom::size::Size2D;
use gfx::display_list::DisplayList;
use gfx::geometry::Au;
@ -27,8 +25,8 @@ pub fn BlockFlowData() -> BlockFlowData {
}
pub trait BlockLayout {
pure fn starts_block_flow() -> bool;
pure fn with_block_box(@mut self, &fn(box: &@mut RenderBox) -> ()) -> ();
fn starts_block_flow(&self) -> bool;
fn with_block_box(@mut self, &fn(box: &@mut RenderBox) -> ()) -> ();
fn bubble_widths_block(@mut self, ctx: &LayoutContext);
fn assign_widths_block(@mut self, ctx: &LayoutContext);
@ -37,12 +35,12 @@ pub trait BlockLayout {
a: &DisplayListBuilder,
b: &Rect<Au>,
c: &Point2D<Au>,
d: &Mut<DisplayList>);
d: &Cell<DisplayList>);
}
impl BlockLayout for FlowContext {
pure fn starts_block_flow() -> bool {
match self {
fn starts_block_flow(&self) -> bool {
match *self {
RootFlow(*) | BlockFlow(*) | InlineBlockFlow(*) => true,
_ => false
}
@ -50,7 +48,7 @@ impl BlockLayout for FlowContext {
/* Get the current flow's corresponding block box, if it exists, and do something with it.
This works on both BlockFlow and RootFlow, since they are mostly the same. */
pure fn with_block_box(@mut self, cb: &fn(box: &@mut RenderBox) -> ()) -> () {
fn with_block_box(@mut self, cb: &fn(box: &@mut RenderBox) -> ()) -> () {
match *self {
BlockFlow(*) => {
let box = self.block().box;
@ -74,14 +72,14 @@ impl BlockLayout for FlowContext {
/* TODO: absolute contexts */
/* TODO: inline-blocks */
fn bubble_widths_block(@mut self, ctx: &LayoutContext) {
fail_unless!(self.starts_block_flow());
assert!(self.starts_block_flow());
let mut min_width = Au(0);
let mut pref_width = Au(0);
/* find max width from child block contexts */
for FlowTree.each_child(self) |child_ctx| {
fail_unless!(child_ctx.starts_block_flow() || child_ctx.starts_inline_flow());
assert!(child_ctx.starts_block_flow() || child_ctx.starts_inline_flow());
min_width = au::max(min_width, child_ctx.d().min_width);
pref_width = au::max(pref_width, child_ctx.d().pref_width);
@ -106,7 +104,7 @@ impl BlockLayout for FlowContext {
all child (block) contexts. */
fn assign_widths_block(@mut self, _ctx: &LayoutContext) {
fail_unless!(self.starts_block_flow());
assert!(self.starts_block_flow());
let mut remaining_width = self.d().position.size.width;
let mut _right_used = Au(0);
@ -121,14 +119,14 @@ impl BlockLayout for FlowContext {
}
for FlowTree.each_child(self) |child_ctx| {
fail_unless!(child_ctx.starts_block_flow() || child_ctx.starts_inline_flow());
assert!(child_ctx.starts_block_flow() || child_ctx.starts_inline_flow());
child_ctx.d().position.origin.x = left_used;
child_ctx.d().position.size.width = remaining_width;
}
}
fn assign_height_block(@mut self, _ctx: &LayoutContext) {
fail_unless!(self.starts_block_flow());
assert!(self.starts_block_flow());
let mut cur_y = Au(0);
@ -150,9 +148,9 @@ impl BlockLayout for FlowContext {
}
fn build_display_list_block(@mut self, builder: &DisplayListBuilder, dirty: &Rect<Au>,
offset: &Point2D<Au>, list: &Mut<DisplayList>) {
offset: &Point2D<Au>, list: &Cell<DisplayList>) {
fail_unless!(self.starts_block_flow());
assert!(self.starts_block_flow());
// add box that starts block context
do self.with_block_box |box| {

View file

@ -8,33 +8,24 @@ use layout::display_list_builder::DisplayListBuilder;
use layout::flow::FlowContext;
use layout::text::TextBoxData;
use layout;
use newcss::color::{Color, rgba, rgb};
use newcss::color::{Color, rgb};
use newcss::complete::CompleteStyle;
use newcss::units::{BoxSizing, Cursive, Em, Fantasy, Length, Monospace, Pt, Px, SansSerif, Serif};
use newcss::values::{CSSBackgroundColorColor, CSSBackgroundColorTransparent, CSSBorderColor};
use newcss::values::{CSSBorderWidthLength, CSSBorderWidthMedium, CSSDisplay};
use newcss::values::{CSSFontFamilyFamilyName, CSSFontFamilyGenericFamily, CSSPositionAbsolute};
use newcss::units::{Cursive, Em, Fantasy, Length, Monospace, Pt, Px, SansSerif, Serif};
use newcss::values::{CSSBorderWidthLength, CSSBorderWidthMedium};
use newcss::values::{CSSFontFamilyFamilyName, CSSFontFamilyGenericFamily};
use newcss::values::{CSSFontSizeLength, CSSFontStyleItalic, CSSFontStyleNormal};
use newcss::values::{CSSFontStyleOblique, CSSTextAlign, Specified};
use util::tree::ReadMethods;
use newcss::values::{CSSFontStyleOblique, CSSTextAlign};
use core::managed;
use core::mutable::Mut;
use core::rand;
use core::task::spawn;
use core::to_str::ToStr;
use core::cell::Cell;
use geom::{Point2D, Rect, Size2D};
use gfx::display_list::{DisplayItem, DisplayList};
use gfx::font::{FontStyle, FontWeight300};
use gfx::geometry::Au;
use gfx::image::base::Image;
use gfx::image::holder::ImageHolder;
use gfx::text::text_run::TextRun;
use gfx::util::range::*;
use gfx;
use std::arc::ARC;
use std::arc;
use std::net::url::Url;
/**
Render boxes (`struct RenderBox`) are the leafs of the layout
@ -118,8 +109,8 @@ pub fn RenderBoxData(node: AbstractNode, ctx: @mut FlowContext, id: int) -> Rend
}
}
impl RenderBox {
pure fn d(&mut self) -> &self/mut RenderBoxData {
impl RenderBox {
fn d(&mut self) -> &'self mut RenderBoxData {
unsafe {
//Rust #5074 - we can't take mutable references to the
// data that needs to be returned right now.
@ -132,35 +123,35 @@ impl RenderBox {
}
}
pure fn is_replaced(self) -> bool {
fn is_replaced(self) -> bool {
match self {
ImageBox(*) => true, // TODO: form elements, etc
_ => false
}
}
pure fn can_split() -> bool {
match self {
fn can_split(&self) -> bool {
match *self {
TextBox(*) => true,
_ => false
}
}
pure fn is_whitespace_only() -> bool {
match &self {
&UnscannedTextBox(_, ref raw_text) => raw_text.is_whitespace(),
fn is_whitespace_only(&self) -> bool {
match *self {
UnscannedTextBox(_, ref raw_text) => raw_text.is_whitespace(),
_ => false
}
}
fn can_merge_with_box(@mut self, other: @mut RenderBox) -> bool {
fail_unless!(!managed::mut_ptr_eq(self, other));
assert!(!managed::mut_ptr_eq(self, other));
match (self, other) {
(@UnscannedTextBox(*), @UnscannedTextBox(*)) => {
self.font_style() == other.font_style()
},
(@TextBox(_, ref d1), @TextBox(_, ref d2)) => managed::ptr_eq(d1.run, d2.run),
(@TextBox(_, d1), @TextBox(_, d2)) => managed::ptr_eq(d1.run, d2.run),
(_, _) => false
}
}
@ -178,7 +169,7 @@ impl RenderBox {
let mut right_range : Option<Range> = None;
debug!("split_to_width: splitting text box (strlen=%u, range=%?, avail_width=%?)",
data.run.text.len(), data.range, max_width);
do data.run.iter_indivisible_pieces_for_range(&const data.range) |piece_range| {
do data.run.iter_indivisible_pieces_for_range(&data.range) |piece_range| {
debug!("split_to_width: considering piece (range=%?, remain_width=%?)",
piece_range, remaining_width);
let metrics = data.run.metrics_for_range(piece_range);
@ -221,10 +212,10 @@ impl RenderBox {
}
let left_box = if left_range.length() > 0 {
Some(layout::text::adapt_textbox_with_range(self.d(), data.run, &const left_range))
Some(layout::text::adapt_textbox_with_range(self.d(), data.run, &left_range))
} else { None };
let right_box = option::map_default(&right_range, None, |range: &const Range| {
let right_box = right_range.map_default(None, |range: &Range| {
Some(layout::text::adapt_textbox_with_range(self.d(), data.run, range))
});
@ -252,7 +243,7 @@ impl RenderBox {
// TODO: consult CSS 'width', margin, border.
// TODO: If image isn't available, consult 'width'.
ImageBox(_, ref mut i) => Au::from_px(i.get_size().get_or_default(Size2D(0,0)).width),
TextBox(_,d) => d.run.min_width_for_range(&const d.range),
TextBox(_,d) => d.run.min_width_for_range(&d.range),
UnscannedTextBox(*) => fail!(~"Shouldn't see unscanned boxes here.")
}
}
@ -275,7 +266,7 @@ impl RenderBox {
// factor in min/pref widths of any text runs that it owns.
&TextBox(_,d) => {
let mut max_line_width: Au = Au(0);
for d.run.iter_natural_lines_for_range(&const d.range) |line_range| {
for d.run.iter_natural_lines_for_range(&d.range) |line_range| {
let mut line_width: Au = Au(0);
for d.run.glyphs.iter_glyphs_for_char_range(line_range) |_char_i, glyph| {
line_width += glyph.advance()
@ -309,7 +300,7 @@ impl RenderBox {
/* The box formed by the content edge, as defined in CSS 2.1 Section 8.1.
Coordinates are relative to the owning flow. */
pure fn content_box(&mut self) -> Rect<Au> {
fn content_box(&mut self) -> Rect<Au> {
let origin = {copy self.d().position.origin};
match self {
&ImageBox(_, ref mut i) => {
@ -344,20 +335,20 @@ impl RenderBox {
/* The box formed by the border edge, as defined in CSS 2.1 Section 8.1.
Coordinates are relative to the owning flow. */
pure fn border_box(&mut self) -> Rect<Au> {
fn border_box(&mut self) -> Rect<Au> {
// TODO: actually compute content_box + padding + border
self.content_box()
}
/* The box fromed by the margin edge, as defined in CSS 2.1 Section 8.1.
Coordinates are relative to the owning flow. */
pure fn margin_box(&mut self) -> Rect<Au> {
fn margin_box(&mut self) -> Rect<Au> {
// TODO: actually compute content_box + padding + border + margin
self.content_box()
}
fn style(&mut self) -> CompleteStyle/&self {
let d: &self/mut RenderBoxData = self.d();
fn style(&mut self) -> CompleteStyle<'self> {
let d: &'self mut RenderBoxData = self.d();
d.node.style()
}
@ -388,7 +379,7 @@ impl RenderBox {
* `list` - List to which items should be appended
*/
fn build_display_list(@mut self, _builder: &DisplayListBuilder, dirty: &Rect<Au>,
offset: &Point2D<Au>, list: &Mut<DisplayList>) {
offset: &Point2D<Au>, list: &Cell<DisplayList>) {
let box_bounds = self.d().position;
@ -409,30 +400,32 @@ impl RenderBox {
match m {
&UnscannedTextBox(*) => fail!(~"Shouldn't see unscanned boxes here."),
&TextBox(_,data) => {
do list.borrow_mut |list| {
let nearest_ancestor_element = self.nearest_ancestor_element();
let color = nearest_ancestor_element.style().color().to_gfx_color();
list.append_item(~DisplayItem::new_Text(&abs_box_bounds,
~data.run.serialize(),
data.range,
color));
// debug frames for text box bounds
debug!("%?", {
// text box bounds
list.append_item(~DisplayItem::new_Border(&abs_box_bounds,
Au::from_px(1),
rgb(0, 0, 200).to_gfx_color()));
// baseline "rect"
// TODO(Issue #221): create and use a Line display item for baseline.
let ascent = data.run.metrics_for_range(&data.range).ascent;
let baseline = Rect(abs_box_bounds.origin + Point2D(Au(0),ascent),
Size2D(abs_box_bounds.size.width, Au(0)));
list.append_item(~DisplayItem::new_Border(&baseline,
Au::from_px(1),
rgb(0, 200, 0).to_gfx_color()));
; ()});
}
let nearest_ancestor_element = self.nearest_ancestor_element();
let color = nearest_ancestor_element.style().color().to_gfx_color();
let mut l = list.take(); // FIXME: this should use with_mut_ref when that appears
l.append_item(~DisplayItem::new_Text(&abs_box_bounds,
~data.run.serialize(),
data.range,
color));
// debug frames for text box bounds
debug!("%?", {
// text box bounds
let mut l = list.take(); // FIXME: use with_mut_ref when that appears
l.append_item(~DisplayItem::new_Border(&abs_box_bounds,
Au::from_px(1),
rgb(0, 0, 200).to_gfx_color()));
// baseline "rect"
// TODO(Issue #221): create and use a Line display item for baseline.
let ascent = data.run.metrics_for_range(&data.range).ascent;
let baseline = Rect(abs_box_bounds.origin + Point2D(Au(0),ascent),
Size2D(abs_box_bounds.size.width, Au(0)));
l.append_item(~DisplayItem::new_Border(&baseline,
Au::from_px(1),
rgb(0, 200, 0).to_gfx_color()));
list.put_back(l);
; ()});
},
// TODO: items for background, border, outline
&GenericBox(_) => {}
@ -440,11 +433,11 @@ impl RenderBox {
//let i: &mut ImageHolder = unsafe { cast::transmute(i) }; // Rust #5074
match i.get_image() {
Some(image) => {
do list.borrow_mut |list| {
debug!("(building display list) building image box");
list.append_item(~DisplayItem::new_Image(&abs_box_bounds,
arc::clone(&image)));
}
debug!("(building display list) building image box");
let mut l = list.take(); // FIXME: use with_mut_ref when available
l.append_item(~DisplayItem::new_Image(&abs_box_bounds,
arc::clone(&image)));
list.put_back(l);
}
None => {
/* No image data at all? Okay, add some fallback content instead. */
@ -457,7 +450,7 @@ impl RenderBox {
self.add_border_to_list(list, &abs_box_bounds);
}
fn add_bgcolor_to_list(&mut self, list: &Mut<DisplayList>, abs_bounds: &Rect<Au>) {
fn add_bgcolor_to_list(&mut self, list: &Cell<DisplayList>, abs_bounds: &Rect<Au>) {
use std::cmp::FuzzyEq;
// FIXME: This causes a lot of background colors to be displayed when they are clearly not
@ -468,13 +461,13 @@ impl RenderBox {
let bgcolor = nearest_ancestor_element.style().background_color();
if !bgcolor.alpha.fuzzy_eq(&0.0) {
do list.borrow_mut |list| {
list.append_item(~DisplayItem::new_SolidColor(abs_bounds, bgcolor.to_gfx_color()));
}
let mut l = list.take(); // FIXME: use with_mut_ref when available
l.append_item(~DisplayItem::new_SolidColor(abs_bounds, bgcolor.to_gfx_color()));
list.put_back(l);
}
}
fn add_border_to_list(&mut self, list: &Mut<DisplayList>, abs_bounds: &Rect<Au>) {
fn add_border_to_list(&mut self, list: &Cell<DisplayList>, abs_bounds: &Rect<Au>) {
if !self.d().node.is_element() { return }
let top_width = self.style().border_top_width();
@ -509,10 +502,9 @@ impl RenderBox {
let top_color = self.style().border_top_color();
let color = top_color.to_gfx_color(); // FIXME
do list.borrow_mut |list| {
list.append_item(~DisplayItem::new_Border(&bounds, border_width, color));
}
let mut l = list.take(); // FIXME: use with_mut_ref when available
l.append_item(~DisplayItem::new_Border(&bounds, border_width, color));
list.put_back(l);
} else {
warn!("ignoring unimplemented border widths");
}
@ -578,12 +570,12 @@ impl RenderBox {
}
impl BoxedMutDebugMethods for RenderBox {
pure fn dump(@mut self) {
fn dump(@mut self) {
self.dump_indent(0u);
}
/* Dumps the node tree, for debugging, with indentation. */
pure fn dump_indent(@mut self, indent: uint) {
fn dump_indent(@mut self, indent: uint) {
let mut s = ~"";
for uint::range(0u, indent) |_i| {
s += ~" ";
@ -593,15 +585,21 @@ impl BoxedMutDebugMethods for RenderBox {
debug!("%s", s);
}
pure fn debug_str(@mut self) -> ~str {
let repr = match self {
@GenericBox(*) => ~"GenericBox",
@ImageBox(*) => ~"ImageBox",
@TextBox(_,d) => fmt!("TextBox(text=%s)", str::substr(d.run.text, d.range.begin(), d.range.length())),
@UnscannedTextBox(_, ref s) => fmt!("UnscannedTextBox(%s)", *s)
fn debug_str(@mut self) -> ~str {
let borrowed_self : &mut RenderBox = self; // FIXME: borrow checker workaround
let repr = match borrowed_self {
&GenericBox(*) => ~"GenericBox",
&ImageBox(*) => ~"ImageBox",
&TextBox(_,d) => fmt!("TextBox(text=%s)", str::substr(d.run.text, d.range.begin(), d.range.length())),
&UnscannedTextBox(_, ref s) => {
let s = s;
fmt!("UnscannedTextBox(%s)", *s)
}
};
fmt!("box b%?: %?", self.d().id, repr)
let borrowed_self : &mut RenderBox = self; // FIXME: borrow checker workaround
let id = borrowed_self.d().id;
fmt!("box b%?: %?", id, repr)
}
}

View file

@ -1,9 +1,8 @@
/** Creates CSS boxes from a DOM. */
use dom::element::*;
use dom::node::{AbstractNode, Comment, CommentNodeTypeId, Doctype, DoctypeNodeTypeId, Element};
use dom::node::{ElementNodeTypeId, Node, Text, TextNodeTypeId};
use dom;
use dom::node::{AbstractNode, CommentNodeTypeId, DoctypeNodeTypeId};
use dom::node::{ElementNodeTypeId, TextNodeTypeId};
use layout::block::BlockFlowData;
use layout::box::*;
use layout::context::LayoutContext;
@ -16,7 +15,7 @@ use util::tree;
use gfx::image::holder::ImageHolder;
use gfx::util::range::Range;
use newcss::values::{CSSDisplay, CSSDisplayBlock, CSSDisplayInline, CSSDisplayInlineBlock};
use newcss::values::{CSSDisplayNone, Inherit, Specified};
use newcss::values::{CSSDisplayNone};
pub struct LayoutTreeBuilder {
root_flow: Option<@mut FlowContext>,
@ -25,7 +24,7 @@ pub struct LayoutTreeBuilder {
}
pub impl LayoutTreeBuilder {
static pure fn new() -> LayoutTreeBuilder {
fn new() -> LayoutTreeBuilder {
LayoutTreeBuilder {
root_flow: None,
next_bid: -1,
@ -79,7 +78,7 @@ priv fn simulate_UA_display_rules(node: AbstractNode) -> CSSDisplay {
}
impl BoxGenerator {
static pure fn new(flow: @mut FlowContext) -> BoxGenerator {
fn new(flow: @mut FlowContext) -> BoxGenerator {
unsafe { debug!("Creating box generator for flow: %s", flow.debug_str()); }
BoxGenerator {
flow: flow,
@ -88,7 +87,7 @@ impl BoxGenerator {
}
/* Whether "spacer" boxes are needed to stand in for this DOM node */
pure fn inline_spacers_needed_for_node(&self, _: AbstractNode) -> bool {
fn inline_spacers_needed_for_node(&self, _: AbstractNode) -> bool {
return false;
}
@ -115,7 +114,10 @@ impl BoxGenerator {
match self.flow {
@InlineFlow(*) => {
let node_range_start = match self.flow {
@InlineFlow(*) => self.flow.inline().boxes.len(),
@InlineFlow(*) => {
let inline_flow = self.flow.inline();
inline_flow.boxes.len()
}
_ => 0
};
self.range_stack.push(node_range_start);
@ -141,7 +143,7 @@ impl BoxGenerator {
debug!("BoxGenerator[f%d]: attaching box[b%d] to block flow (node: %s)",
self.flow.d().id, new_box.d().id, node.debug_str());
fail_unless!(self.flow.block().box.is_none());
assert!(self.flow.block().box.is_none());
//XXXjdm We segfault when returning without this temporary.
let block = self.flow.block();
block.box = Some(new_box);
@ -153,7 +155,7 @@ impl BoxGenerator {
debug!("BoxGenerator[f%d]: attaching box[b%d] to root flow (node: %s)",
self.flow.d().id, new_box.d().id, node.debug_str());
fail_unless!(self.flow.root().box.is_none());
assert!(self.flow.root().box.is_none());
//XXXjdm We segfault when returning without this temporary.
let root = self.flow.root();
root.box = Some(new_box);
@ -176,17 +178,21 @@ impl BoxGenerator {
}
}
let mut node_range: Range = Range::new(self.range_stack.pop(), 0);
node_range.extend_to(self.flow.inline().boxes.len());
fail_unless!(node_range.length() > 0);
let inline_flow = self.flow.inline(); // FIXME: borrow checker workaround
node_range.extend_to(inline_flow.boxes.len());
assert!(node_range.length() > 0);
debug!("BoxGenerator: adding element range=%?", node_range);
let elems = &mut self.flow.inline().elems;
elems.add_mapping(node, &const node_range);
let elems = &mut inline_flow.elems;
elems.add_mapping(node, &node_range);
},
@BlockFlow(*) | @RootFlow(*) => {
fail_unless!(self.range_stack.len() == 0);
assert!(self.range_stack.len() == 0);
},
_ => { warn!("pop_node() not implemented for flow %?", self.flow.d().id) }
_ => {
let d = self.flow.d(); // FIXME: borrow checker workaround
warn!("pop_node() not implemented for flow %?", d.id)
}
}
}
}
@ -197,7 +203,7 @@ struct BuilderContext {
}
impl BuilderContext {
static pure fn new(collector: @mut BoxGenerator) -> BuilderContext {
fn new(collector: @mut BoxGenerator) -> BuilderContext {
unsafe { debug!("Creating new BuilderContext for flow: %s", collector.flow.debug_str()); }
BuilderContext {
default_collector: collector,
@ -211,8 +217,10 @@ impl BuilderContext {
}
priv fn attach_child_flow(&self, child: @mut FlowContext) {
let d = self.default_collector.flow.d(); // FIXME: borrow checker workaround
let cd = child.d(); // FIXME: borrow checker workaround
debug!("BuilderContext: Adding child flow f%? of f%?",
self.default_collector.flow.d().id, child.d().id);
d.id, cd.id);
tree::add_child(&FlowTree, self.default_collector.flow, child);
}
@ -321,7 +329,7 @@ pub impl LayoutTreeBuilder {
let flow = &mut this_ctx.default_collector.flow;
for tree::each_child(&FlowTree, flow) |child_flow: &@mut FlowContext| {
for (copy child_flow.d().node).each |node| {
fail_unless!(node.has_layout_data());
assert!(node.has_layout_data());
node.layout_data().flow = Some(*child_flow);
}
}
@ -482,7 +490,7 @@ pub impl LayoutTreeBuilder {
}
}
fn decide_box_type(&self, node: AbstractNode, display: CSSDisplay) -> RenderBoxType {
fn decide_box_type(&self, node: AbstractNode, _display: CSSDisplay) -> RenderBoxType {
if node.is_text() {
RenderBox_Text
} else if node.is_image_element() {

View file

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

View file

@ -2,20 +2,13 @@
/// Constructs display lists from render boxes.
///
use layout::box::{RenderBox, TextBox};
use core::cell::Cell;
use layout::context::LayoutContext;
use layout::flow::FlowContext;
use layout::text::TextBoxData;
use newcss::values::Specified;
use newcss::values::{CSSBackgroundColorColor, CSSBackgroundColorTransparent};
use util::tree;
use core::either::{Left, Right};
use core::mutable::Mut;
use core::vec::push;
use geom::point::Point2D;
use geom::rect::Rect;
use geom::size::Size2D;
use gfx::display_list::DisplayList;
use gfx::geometry::Au;
use gfx;
@ -27,25 +20,25 @@ use gfx;
Right now, the builder isn't used for much, but it establishes the
pattern we'll need once we support DL-based hit testing &c. */
pub struct DisplayListBuilder {
pub struct DisplayListBuilder<'self> {
ctx: &'self LayoutContext,
}
pub trait FlowDisplayListBuilderMethods {
fn build_display_list(@mut self, a: &DisplayListBuilder, b: &Rect<Au>, c: &Mut<DisplayList>);
fn build_display_list(@mut self, a: &DisplayListBuilder, b: &Rect<Au>, c: &Cell<DisplayList>);
fn build_display_list_for_child(@mut self,
a: &DisplayListBuilder,
b: @mut FlowContext,
c: &Rect<Au>,
d: &Point2D<Au>,
e: &Mut<DisplayList>);
e: &Cell<DisplayList>);
}
impl FlowDisplayListBuilderMethods for FlowContext {
fn build_display_list(@mut self,
builder: &DisplayListBuilder,
dirty: &Rect<Au>,
list: &Mut<DisplayList>) {
list: &Cell<DisplayList>) {
let zero = gfx::geometry::zero_point();
self.build_display_list_recurse(builder, dirty, &zero, list);
}
@ -54,14 +47,15 @@ impl FlowDisplayListBuilderMethods for FlowContext {
builder: &DisplayListBuilder,
child_flow: @mut FlowContext,
dirty: &Rect<Au>, offset: &Point2D<Au>,
list: &Mut<DisplayList>) {
list: &Cell<DisplayList>) {
// adjust the dirty rect to child flow context coordinates
let abs_flow_bounds = child_flow.d().position.translate(offset);
let adj_offset = offset.add(&child_flow.d().position.origin);
let d = child_flow.d(); // FIXME: borrow checker workaround
let abs_flow_bounds = d.position.translate(offset);
let adj_offset = offset.add(&d.position.origin);
debug!("build_display_list_for_child: rel=%?, abs=%?",
child_flow.d().position, abs_flow_bounds);
d.position, abs_flow_bounds);
debug!("build_display_list_for_child: dirty=%?, offset=%?",
dirty, offset);

View file

@ -1,14 +1,14 @@
use core;
use core::cell::Cell;
use dom::node::AbstractNode;
use layout::block::{BlockFlowData, BlockLayout};
use layout::box::RenderBox;
use layout::context::LayoutContext;
use layout::debug::BoxedMutDebugMethods;
use layout::display_list_builder::DisplayListBuilder;
use layout::inline::{InlineFlowData, InlineLayout, NodeRange};
use layout::inline::{InlineFlowData, InlineLayout};
use layout::root::{RootFlowData, RootLayout};
use util::tree;
use core::mutable::Mut;
use geom::rect::Rect;
use geom::point::Point2D;
use gfx::display_list::DisplayList;
@ -92,8 +92,8 @@ pub fn FlowData(id: int) -> FlowData {
}
}
pub impl FlowContext {
pure fn d(&mut self) -> &self/mut FlowData {
pub impl FlowContext {
fn d(&mut self) -> &'self mut FlowData {
unsafe {
match *self {
AbsoluteFlow(ref d) => cast::transmute(d),
@ -107,21 +107,21 @@ pub impl FlowContext {
}
}
pure fn inline(&mut self) -> &self/mut InlineFlowData {
fn inline(&mut self) -> &'self mut InlineFlowData {
match self {
&InlineFlow(_, ref i) => unsafe { cast::transmute(i) },
_ => fail!(fmt!("Tried to access inline data of non-inline: f%d", self.d().id))
}
}
pure fn block(&mut self) -> &self/mut BlockFlowData {
fn block(&mut self) -> &'self mut BlockFlowData {
match self {
&BlockFlow(_, ref mut b) => unsafe { cast::transmute(b) },
_ => fail!(fmt!("Tried to access block data of non-block: f%d", self.d().id))
}
}
pure fn root(&mut self) -> &self/mut RootFlowData {
fn root(&mut self) -> &'self mut RootFlowData {
match self {
&RootFlow(_, ref r) => unsafe { cast::transmute(r) },
_ => fail!(fmt!("Tried to access root data of non-root: f%d", self.d().id))
@ -156,8 +156,9 @@ pub impl FlowContext {
}
fn build_display_list_recurse(@mut self, builder: &DisplayListBuilder, dirty: &Rect<Au>,
offset: &Point2D<Au>, list: &Mut<DisplayList>) {
debug!("FlowContext::build_display_list at %?: %s", self.d().position, self.debug_str());
offset: &Point2D<Au>, list: &Cell<DisplayList>) {
let d = self.d(); // FIXME: borrow checker workaround
debug!("FlowContext::build_display_list at %?: %s", d.position, self.debug_str());
match self {
@RootFlow(*) => self.build_display_list_root(builder, dirty, offset, list),
@ -168,40 +169,58 @@ pub impl FlowContext {
}
// Actual methods that do not require much flow-specific logic
pure fn foldl_all_boxes<B: Copy>(&mut self,
seed: B,
cb: &pure fn(a: B,@mut RenderBox) -> B) -> B {
fn foldl_all_boxes<B: Copy>(&mut self,
seed: B,
cb: &fn(a: B, b: @mut RenderBox) -> B) -> B {
match self {
&RootFlow(*) => option::map_default(&self.root().box, seed, |box| { cb(seed, *box) }),
&BlockFlow(*) => option::map_default(&self.block().box, seed, |box| { cb(seed, *box) }),
&InlineFlow(*) => do self.inline().boxes.foldl(seed) |acc, box| { cb(*acc, *box) },
&RootFlow(*) => {
let root = self.root(); // FIXME: borrow checker workaround
root.box.map_default(seed, |box| { cb(seed, *box) })
}
&BlockFlow(*) => {
let block = self.block(); // FIXME: borrow checker workaround
block.box.map_default(seed, |box| { cb(seed, *box) })
}
&InlineFlow(*) => {
let inline = self.inline(); // FIXME: borrow checker workaround
inline.boxes.foldl(seed, |acc, box| { cb(*acc, *box) })
}
_ => fail!(fmt!("Don't know how to iterate node's RenderBoxes for %?", self))
}
}
pure fn foldl_boxes_for_node<B: Copy>(&mut self,
node: AbstractNode,
seed: B,
cb: &pure fn(a: B,@mut RenderBox) -> B)
-> B {
fn foldl_boxes_for_node<B: Copy>(&mut self,
node: AbstractNode,
seed: B,
cb: &fn(a: B,@mut RenderBox) -> B)
-> B {
do self.foldl_all_boxes(seed) |acc, box| {
if box.d().node == node { cb(acc, box) }
else { acc }
}
}
pure fn iter_all_boxes<T>(&mut self, cb: &pure fn(@mut RenderBox) -> T) {
fn iter_all_boxes<T>(&mut self, cb: &fn(@mut RenderBox) -> T) {
match self {
&RootFlow(*) => for self.root().box.each |box| { cb(*box); },
&BlockFlow(*) => for self.block().box.each |box| { cb(*box); },
&InlineFlow(*) => for self.inline().boxes.each |box| { cb(*box); },
&RootFlow(*) => {
let root = self.root(); // FIXME: borrow checker workaround
for root.box.each |box| { cb(*box); }
}
&BlockFlow(*) => {
let block = self.block(); // FIXME: borrow checker workaround
for block.box.each |box| { cb(*box); }
}
&InlineFlow(*) => {
let inline = self.inline(); // FIXME: borrow checker workaround
for inline.boxes.each |box| { cb(*box); }
}
_ => fail!(fmt!("Don't know how to iterate node's RenderBoxes for %?", self))
}
}
pure fn iter_boxes_for_node<T>(&mut self,
node: AbstractNode,
cb: &pure fn(@mut RenderBox) -> T) {
fn iter_boxes_for_node<T>(&mut self,
node: AbstractNode,
cb: &fn(@mut RenderBox) -> T) {
do self.iter_all_boxes |box| {
if box.d().node == node { cb(box); }
}
@ -212,13 +231,13 @@ pub impl FlowContext {
pub enum FlowTree { FlowTree }
impl FlowTree {
fn each_child(ctx: @mut FlowContext, f: &fn(box: @mut FlowContext) -> bool) {
tree::each_child(&self, &ctx, |box| f(*box) )
fn each_child(&self, ctx: @mut FlowContext, f: &fn(box: @mut FlowContext) -> bool) {
tree::each_child(self, &ctx, |box| f(*box) )
}
}
impl tree::ReadMethods<@mut FlowContext> for FlowTree {
fn with_tree_fields<R>(box: &@mut FlowContext, f: &fn(&mut tree::Tree<@mut FlowContext>) -> R) -> R {
fn with_tree_fields<R>(&self, box: &@mut FlowContext, f: &fn(&mut tree::Tree<@mut FlowContext>) -> R) -> R {
let tree = &mut box.d().tree;
f(tree)
}
@ -231,9 +250,9 @@ impl FlowTree {
}
impl tree::WriteMethods<@mut FlowContext> for FlowTree {
pure fn tree_eq(a: &@mut FlowContext, b: &@mut FlowContext) -> bool { core::managed::mut_ptr_eq(*a, *b) }
fn tree_eq(&self, a: &@mut FlowContext, b: &@mut FlowContext) -> bool { core::managed::mut_ptr_eq(*a, *b) }
fn with_tree_fields<R>(box: &@mut FlowContext, f: &fn(&mut tree::Tree<@mut FlowContext>) -> R) -> R {
fn with_tree_fields<R>(&self, box: &@mut FlowContext, f: &fn(&mut tree::Tree<@mut FlowContext>) -> R) -> R {
let tree = &mut box.d().tree;
f(tree)
}
@ -241,12 +260,12 @@ impl tree::WriteMethods<@mut FlowContext> for FlowTree {
impl BoxedMutDebugMethods for FlowContext {
pure fn dump(@mut self) {
fn dump(@mut self) {
self.dump_indent(0u);
}
/** Dumps the flow tree, for debugging, with indentation. */
pure fn dump_indent(@mut self, indent: uint) {
fn dump_indent(@mut self, indent: uint) {
let mut s = ~"|";
for uint::range(0u, indent) |_i| {
s += ~"---- ";
@ -263,10 +282,11 @@ impl BoxedMutDebugMethods for FlowContext {
}
}
pure fn debug_str(@mut self) -> ~str {
fn debug_str(@mut self) -> ~str {
let repr = match *self {
InlineFlow(*) => {
let mut s = self.inline().boxes.foldl(~"InlineFlow(children=", |s, box| {
let inline = self.inline(); // FIXME: borrow checker workaround
let mut s = inline.boxes.foldl(~"InlineFlow(children=", |s, box| {
fmt!("%s b%d", *s, box.d().id)
});
s += ~")";
@ -286,7 +306,8 @@ impl BoxedMutDebugMethods for FlowContext {
},
_ => ~"(Unknown flow)"
};
fmt!("f%? %?", self.d().id, repr)
let d = self.d(); // FIXME: borrow checker workaround
fmt!("f%? %?", d.id, repr)
}
}

View file

@ -1,26 +1,22 @@
use core;
use core::cell::Cell;
use dom::node::AbstractNode;
use layout::box::*;
use layout::context::LayoutContext;
use layout::debug::{BoxedDebugMethods, BoxedMutDebugMethods, DebugMethods};
use layout::display_list_builder::DisplayListBuilder;
use layout::flow::{FlowContext, InlineFlow};
use layout::text::{TextBoxData, UnscannedMethods, adapt_textbox_with_range};
use util::tree;
use layout::text::{UnscannedMethods, adapt_textbox_with_range};
use core::dlist::DList;
use geom::{Point2D, Rect, Size2D};
use gfx::display_list::DisplayList;
use gfx::font::FontStyle;
use gfx::geometry::Au;
use gfx::image::holder;
use gfx::text::text_run::TextRun;
use gfx::text::util::*;
use gfx::util::range::Range;
use newcss::values::{CSSTextAlignCenter, CSSTextAlignJustify, CSSTextAlignLeft, CSSTextAlignRight};
use newcss::units::{BoxAuto, BoxLength, Px};
use std::arc;
use core::mutable::Mut;
use std::deque::Deque;
use core::util;
/*
@ -51,7 +47,7 @@ pub struct NodeRange {
}
pub impl NodeRange {
static pure fn new(node: AbstractNode, range: &const Range) -> NodeRange {
fn new(node: AbstractNode, range: &Range) -> NodeRange {
NodeRange { node: node, range: copy *range }
}
}
@ -61,19 +57,19 @@ struct ElementMapping {
}
pub impl ElementMapping {
static pure fn new() -> ElementMapping {
fn new() -> ElementMapping {
ElementMapping { entries: ~[] }
}
fn add_mapping(&mut self, node: AbstractNode, range: &const Range) {
fn add_mapping(&mut self, node: AbstractNode, range: &Range) {
self.entries.push(NodeRange::new(node, range))
}
fn each(&self, cb: &pure fn(nr: &NodeRange) -> bool) {
fn each(&self, cb: &fn(nr: &NodeRange) -> bool) {
do self.entries.each |nr| { cb(nr) }
}
fn eachi(&self, cb: &pure fn(i: uint, nr: &NodeRange) -> bool) {
fn eachi(&self, cb: &fn(i: uint, nr: &NodeRange) -> bool) {
do self.entries.eachi |i, nr| { cb(i, nr) }
}
@ -158,7 +154,7 @@ priv struct TextRunScanner {
}
priv impl TextRunScanner {
static fn new() -> TextRunScanner {
fn new() -> TextRunScanner {
TextRunScanner {
clump: Range::empty(),
}
@ -167,7 +163,8 @@ priv impl TextRunScanner {
priv impl TextRunScanner {
fn scan_for_runs(&mut self, ctx: &mut LayoutContext, flow: @mut FlowContext) {
fail_unless!(flow.inline().boxes.len() > 0);
let inline = flow.inline();
assert!(inline.boxes.len() > 0);
let in_boxes = &mut flow.inline().boxes;
//do boxes.swap |in_boxes| {
@ -194,9 +191,9 @@ priv impl TextRunScanner {
// helper functions
fn can_coalesce_text_nodes(boxes: &[@mut RenderBox], left_i: uint, right_i: uint) -> bool {
fail_unless!(left_i < boxes.len());
fail_unless!(right_i > 0 && right_i < boxes.len());
fail_unless!(left_i != right_i);
assert!(left_i < boxes.len());
assert!(right_i > 0 && right_i < boxes.len());
assert!(left_i != right_i);
let (left, right) = (boxes[left_i], boxes[right_i]);
match (left, right) {
@ -223,7 +220,7 @@ priv impl TextRunScanner {
flow: @mut FlowContext,
in_boxes: &[@mut RenderBox],
out_boxes: &mut ~[@mut RenderBox]) {
fail_unless!(self.clump.length() > 0);
assert!(self.clump.length() > 0);
debug!("TextRunScanner: flushing boxes in range=%?", self.clump);
let is_singleton = self.clump.length() == 1;
@ -255,7 +252,7 @@ priv impl TextRunScanner {
debug!("TextRunScanner: pushing single text box in range: %?", self.clump);
let new_box = adapt_textbox_with_range(old_box.d(),
run,
&const Range::new(0, run.char_len()));
&Range::new(0, run.char_len()));
out_boxes.push(new_box);
},
(false, true) => {
@ -294,7 +291,7 @@ priv impl TextRunScanner {
debug!("TextRunScanner: pushing box(es) in range: %?", self.clump);
let clump = self.clump;
for clump.eachi |i| {
let range = &const new_ranges[i - self.clump.begin()];
let range = &new_ranges[i - self.clump.begin()];
if range.length() == 0 {
error!("Elided an UnscannedTextbox because it was zero-length after compression; %s",
in_boxes[i].debug_str());
@ -325,7 +322,8 @@ priv impl TextRunScanner {
}
debug!("--------------------");
self.clump.reset(self.clump.end(), 0);
let end = self.clump.end(); // FIXME: borrow checker workaround
self.clump.reset(end, 0);
} /* /fn flush_clump_to_list */
}
@ -337,18 +335,18 @@ struct PendingLine {
struct LineboxScanner {
flow: @mut FlowContext,
new_boxes: ~[@mut RenderBox],
work_list: @mut DList<@mut RenderBox>,
work_list: @mut Deque<@mut RenderBox>,
pending_line: PendingLine,
line_spans: ~[Range],
}
fn LineboxScanner(inline: @mut FlowContext) -> LineboxScanner {
fail_unless!(inline.starts_inline_flow());
assert!(inline.starts_inline_flow());
LineboxScanner {
flow: inline,
new_boxes: ~[],
work_list: DList(),
work_list: @mut Deque::new(),
pending_line: PendingLine {mut range: Range::empty(), mut width: Au(0)},
line_spans: ~[]
}
@ -375,17 +373,15 @@ impl LineboxScanner {
loop {
// acquire the next box to lay out from work list or box list
let cur_box = match self.work_list.pop() {
Some(box) => {
debug!("LineboxScanner: Working with box from work list: b%d", box.d().id);
box
},
None => {
if i == boxes.len() { break; }
let box = boxes[i]; i += 1;
debug!("LineboxScanner: Working with box from box list: b%d", box.d().id);
box
}
let cur_box = if self.work_list.is_empty() {
if i == boxes.len() { break; }
let box = boxes[i]; i += 1;
debug!("LineboxScanner: Working with box from box list: b%d", box.d().id);
box
} else {
let box = self.work_list.pop_front();
debug!("LineboxScanner: Working with box from work list: b%d", box.d().id);
box
};
let box_was_appended = self.try_append_to_line(ctx, cur_box);
@ -524,7 +520,7 @@ impl LineboxScanner {
match (left, right) {
(Some(left_box), Some(right_box)) => {
self.push_box_to_line(left_box);
self.work_list.push_head(right_box);
self.work_list.add_front(right_box);
},
(Some(left_box), None) => { self.push_box_to_line(left_box); }
(None, Some(right_box)) => { self.push_box_to_line(right_box); }
@ -542,7 +538,7 @@ impl LineboxScanner {
match (left, right) {
(Some(left_box), Some(right_box)) => {
self.push_box_to_line(left_box);
self.work_list.push_head(right_box);
self.work_list.add_front(right_box);
},
(Some(left_box), None) => {
self.push_box_to_line(left_box);
@ -557,7 +553,7 @@ impl LineboxScanner {
return true;
} else {
debug!("LineboxScanner: case=split box didn't fit, not appending and deferring original box.");
self.work_list.push_head(in_box);
self.work_list.add_front(in_box);
return false;
}
}
@ -569,7 +565,7 @@ impl LineboxScanner {
debug!("LineboxScanner: Pushing box b%d to line %u", box.d().id, self.line_spans.len());
if self.pending_line.range.length() == 0 {
fail_unless!(self.new_boxes.len() <= (core::u16::max_value as uint));
assert!(self.new_boxes.len() <= (core::u16::max_value as uint));
self.pending_line.range.reset(self.new_boxes.len(), 0);
}
self.pending_line.range.extend_by(1);
@ -600,20 +596,20 @@ pub fn InlineFlowData() -> InlineFlowData {
}
pub trait InlineLayout {
pure fn starts_inline_flow() -> bool;
fn starts_inline_flow(&self) -> bool;
fn bubble_widths_inline(@mut self, ctx: &mut LayoutContext);
fn assign_widths_inline(@mut self, ctx: &mut LayoutContext);
fn assign_height_inline(@mut self, ctx: &mut LayoutContext);
fn build_display_list_inline(@mut self, a: &DisplayListBuilder, b: &Rect<Au>, c: &Point2D<Au>,
d: &Mut<DisplayList>);
d: &Cell<DisplayList>);
}
impl InlineLayout for FlowContext {
pure fn starts_inline_flow() -> bool { match self { InlineFlow(*) => true, _ => false } }
fn starts_inline_flow(&self) -> bool { match *self { InlineFlow(*) => true, _ => false } }
fn bubble_widths_inline(@mut self, ctx: &mut LayoutContext) {
fail_unless!(self.starts_inline_flow());
assert!(self.starts_inline_flow());
let mut scanner = TextRunScanner::new();
scanner.scan_for_runs(ctx, self);
@ -636,7 +632,7 @@ impl InlineLayout for FlowContext {
contexts and boxes. When called on this context, the context has
had its width set by the parent context. */
fn assign_widths_inline(@mut self, ctx: &mut LayoutContext) {
fail_unless!(self.starts_inline_flow());
assert!(self.starts_inline_flow());
// initialize (content) box widths, if they haven't been
// already. This could be combined with LineboxScanner's walk
@ -685,17 +681,22 @@ impl InlineLayout for FlowContext {
let mut linebox_bounding_box = Au::zero_rect();
let boxes = &mut self.inline().boxes;
for line_span.eachi |box_i| {
let mut cur_box = boxes[box_i];
let cur_box : &mut RenderBox = boxes[box_i]; // FIXME: borrow checker workaround
// compute box height.
cur_box.d().position.size.height = match cur_box {
@ImageBox(_, ref img) => Au::from_px(img.size().height),
@TextBox(*) => { /* text boxes are initialized with dimensions */
cur_box.d().position.size.height
let d = cur_box.d(); // FIXME: borrow checker workaround
let cur_box : &mut RenderBox = boxes[box_i]; // FIXME: borrow checker workaround
d.position.size.height = match *cur_box {
ImageBox(_, ref img) => {
Au::from_px(img.size().height)
}
TextBox(*) => { /* text boxes are initialized with dimensions */
d.position.size.height
},
// TODO(Issue #225): different cases for 'inline-block', other replaced content
@GenericBox(*) => Au::from_px(30),
GenericBox(*) => Au::from_px(30),
_ => {
let cur_box = boxes[box_i]; // FIXME: borrow checker workaround
fail!(fmt!("Tried to assign height to unknown Box variant: %s",
cur_box.debug_str()))
}
@ -704,22 +705,23 @@ impl InlineLayout for FlowContext {
// compute bounding rect, with left baseline as origin.
// so, linebox height is a matter of lining up ideal baselines,
// and then using the union of all these rects.
let bounding_box = match cur_box {
let bounding_box = match *cur_box {
// adjust to baseline coords
// TODO(Issue #227): use left/right margins, border, padding for nonreplaced content,
// and also use top/bottom margins, border, padding for replaced or inline-block content.
// TODO(Issue #225): use height, width for 'inline-block', other replaced content
@ImageBox(*) | @GenericBox(*) => {
let box_bounds = cur_box.d().position;
box_bounds.translate(&Point2D(Au(0), -cur_box.d().position.size.height))
ImageBox(*) | GenericBox(*) => {
let box_bounds = d.position;
box_bounds.translate(&Point2D(Au(0), -d.position.size.height))
},
// adjust bounding box metric to box's horizontal offset
// TODO: we can use font metrics directly instead of re-measuring for the bounding box.
@TextBox(_, data) => {
let text_bounds = data.run.metrics_for_range(&const data.range).bounding_box;
text_bounds.translate(&Point2D(cur_box.d().position.origin.x, Au(0)))
TextBox(_, data) => {
let text_bounds = data.run.metrics_for_range(&data.range).bounding_box;
text_bounds.translate(&Point2D(d.position.origin.x, Au(0)))
},
_ => {
let cur_box = boxes[box_i]; // FIXME: borrow checker workaround
fail!(fmt!("Tried to compute bounding box of unknown Box variant: %s",
cur_box.debug_str()))
}
@ -750,14 +752,15 @@ impl InlineLayout for FlowContext {
}
fn build_display_list_inline(@mut self, builder: &DisplayListBuilder, dirty: &Rect<Au>,
offset: &Point2D<Au>, list: &Mut<DisplayList>) {
offset: &Point2D<Au>, list: &Cell<DisplayList>) {
fail_unless!(self.starts_inline_flow());
assert!(self.starts_inline_flow());
// TODO(Issue #228): once we form line boxes and have their cached bounds, we can be
// smarter and not recurse on a line if nothing in it can intersect dirty
let inline = self.inline(); // FIXME: borrow checker workaround
debug!("FlowContext[%d]: building display list for %u inline boxes",
self.d().id, self.inline().boxes.len());
self.d().id, inline.boxes.len());
let boxes = &mut self.inline().boxes;
for boxes.each |box| {
box.build_display_list(builder, dirty, offset, list)

View file

@ -1,13 +1,11 @@
/// The layout task. Performs layout on the DOM, builds display lists and sends them to be
/// rendered.
use content::content_task;
use css::matching::MatchMethods;
use css::select::new_css_select_ctx;
use dom::event::{Event, ReflowEvent};
use dom::node::{AbstractNode, LayoutData};
use layout::aux::LayoutAuxMethods;
use layout::box::RenderBox;
use layout::box_builder::LayoutTreeBuilder;
use layout::context::LayoutContext;
use layout::debug::{BoxedMutDebugMethods, DebugMethods};
@ -21,9 +19,6 @@ use util::time::time;
use core::cell::Cell;
use core::comm::{Chan, Port, SharedChan};
use core::mutable::Mut;
use core::task::*;
use core::util::replace;
use geom::point::Point2D;
use geom::rect::Rect;
use geom::size::Size2D;
@ -36,7 +31,6 @@ use gfx::render_task::{RenderMsg, RenderTask};
use newcss::select::SelectCtx;
use newcss::stylesheet::Stylesheet;
use newcss::types::OriginAuthor;
use std::arc::ARC;
use std::net::url::Url;
pub type LayoutTask = SharedChan<Msg>;
@ -102,7 +96,7 @@ struct Layout {
font_ctx: @mut FontContext,
// This is used to root reader data
layout_refs: ~[@mut LayoutData],
css_select_ctx: Mut<SelectCtx>,
css_select_ctx: @mut SelectCtx,
}
fn Layout(render_task: RenderTask,
@ -119,7 +113,7 @@ fn Layout(render_task: RenderTask,
from_content: from_content,
font_ctx: fctx,
layout_refs: ~[],
css_select_ctx: Mut(new_css_select_ctx())
css_select_ctx: @mut new_css_select_ctx()
}
}
@ -162,9 +156,7 @@ impl Layout {
fn handle_add_stylesheet(&self, sheet: Stylesheet) {
let sheet = Cell(sheet);
do self.css_select_ctx.borrow_mut |ctx| {
ctx.append_sheet(sheet.take(), OriginAuthor);
}
self.css_select_ctx.append_sheet(sheet.take(), OriginAuthor);
}
fn handle_build(&mut self, data: &BuildData) {
@ -202,9 +194,7 @@ impl Layout {
NoDamage | ReflowDamage => {}
MatchSelectorsDamage => {
do time("layout: selector matching") {
do self.css_select_ctx.borrow_imm |ctx| {
node.restyle_subtree(ctx);
}
node.restyle_subtree(self.css_select_ctx);
}
}
}
@ -235,16 +225,16 @@ impl Layout {
ctx: &layout_ctx,
};
let display_list = Mut(DisplayList::new());
let display_list = @Cell(DisplayList::new());
// TODO: set options on the builder before building
// TODO: be smarter about what needs painting
layout_root.build_display_list(&builder,
&copy layout_root.d().position,
&display_list);
display_list);
let render_layer = RenderLayer {
display_list: display_list.unwrap(),
display_list: display_list.take(),
size: Size2D(screen_size.width.to_px() as uint,
screen_size.height.to_px() as uint)
};
@ -257,7 +247,7 @@ impl Layout {
}
fn handle_query(query: LayoutQuery,
fn handle_query(&self, query: LayoutQuery,
reply_chan: Chan<LayoutQueryResponse>) {
match query {
ContentBox(node) => {

View file

@ -1,5 +1,4 @@
use au = gfx::geometry;
use newcss::values::*;
use core::cell::Cell;
use geom::point::Point2D;
use geom::rect::Rect;
use gfx::display_list::DisplayList;
@ -7,10 +6,8 @@ use gfx::geometry::Au;
use layout::block::BlockLayout;
use layout::box::RenderBox;
use layout::context::LayoutContext;
use layout::flow::{FlowContext, FlowTree, InlineBlockFlow, BlockFlow, RootFlow};
use layout::flow::{FlowContext, FlowTree, RootFlow};
use layout::display_list_builder::DisplayListBuilder;
use util::tree;
use core::mutable::Mut;
pub struct RootFlowData {
box: Option<@mut RenderBox>
@ -23,18 +20,18 @@ pub fn RootFlowData() -> RootFlowData {
}
pub trait RootLayout {
pure fn starts_root_flow() -> bool;
fn starts_root_flow(&self) -> bool;
fn bubble_widths_root(@mut self, ctx: &LayoutContext);
fn assign_widths_root(@mut self, ctx: &LayoutContext);
fn assign_height_root(@mut self, ctx: &LayoutContext);
fn build_display_list_root(@mut self, a: &DisplayListBuilder, b: &Rect<Au>,
c: &Point2D<Au>, d: &Mut<DisplayList>);
c: &Point2D<Au>, d: &Cell<DisplayList>);
}
impl RootLayout for FlowContext {
pure fn starts_root_flow() -> bool {
match self {
fn starts_root_flow(&self) -> bool {
match *self {
RootFlow(*) => true,
_ => false
}
@ -42,12 +39,12 @@ impl RootLayout for FlowContext {
/* defer to the block algorithm */
fn bubble_widths_root(@mut self, ctx: &LayoutContext) {
fail_unless!(self.starts_root_flow());
assert!(self.starts_root_flow());
self.bubble_widths_block(ctx)
}
fn assign_widths_root(@mut self, ctx: &LayoutContext) {
fail_unless!(self.starts_root_flow());
assert!(self.starts_root_flow());
self.d().position.origin = Au::zero_point();
self.d().position.size.width = ctx.screen_size.size.width;
@ -56,7 +53,7 @@ impl RootLayout for FlowContext {
}
fn assign_height_root(@mut self, ctx: &LayoutContext) {
fail_unless!(self.starts_root_flow());
assert!(self.starts_root_flow());
// this is essentially the same as assign_height_block(), except
// the root adjusts self height to at least cover the viewport.
@ -77,8 +74,8 @@ impl RootLayout for FlowContext {
}
fn build_display_list_root(@mut self, builder: &DisplayListBuilder, dirty: &Rect<Au>,
offset: &Point2D<Au>, list: &Mut<DisplayList>) {
fail_unless!(self.starts_root_flow());
offset: &Point2D<Au>, list: &Cell<DisplayList>) {
assert!(self.starts_root_flow());
self.build_display_list_block(builder, dirty, offset, list);
}

View file

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

View file

@ -1,21 +1,18 @@
use ShareGlContext = sharegl::platform::Context;
use dom::event::{Event, ResizeEvent};
use dom::event::Event;
use platform::resize_rate_limiter::ResizeRateLimiter;
use azure::azure_hl::{BackendType, B8G8R8A8, DataSourceSurface, DrawTarget, SourceSurfaceMethods};
use core::comm::{Chan, SharedChan, Port};
use core::task::TaskBuilder;
use core::util;
use geom::matrix::{Matrix4, identity};
use geom::matrix::identity;
use geom::point::Point2D;
use geom::rect::Rect;
use geom::size::Size2D;
use gfx::compositor::{Compositor, LayerBuffer, LayerBufferSet};
use gfx::opts::Opts;
use gfx::util::time;
use layers::layers::ImageLayer;
use core::cell::Cell;
use std::cmp::FuzzyEq;
use glut::glut;
use layers;
use sharegl;
@ -290,7 +287,7 @@ struct SurfaceSet {
fn lend_surface(surfaces: &mut SurfaceSet, receiver: comm::Chan<LayerBufferSet>) {
// We are in a position to lend out the surface?
fail_unless!(surfaces.front.have);
assert!(surfaces.front.have);
// Ok then take it
let old_layer_buffers = util::replace(&mut surfaces.front.layer_buffer_set.buffers, ~[]);
let new_layer_buffers = do old_layer_buffers.map |layer_buffer| {
@ -312,14 +309,14 @@ fn lend_surface(surfaces: &mut SurfaceSet, receiver: comm::Chan<LayerBufferSet>)
// But we (hopefully) have another!
surfaces.front <-> surfaces.back;
// Let's look
fail_unless!(surfaces.front.have);
assert!(surfaces.front.have);
}
fn return_surface(surfaces: &mut SurfaceSet, layer_buffer_set: LayerBufferSet) {
//#debug("osmain: returning surface %?", layer_buffer_set);
// We have room for a return
fail_unless!(surfaces.front.have);
fail_unless!(!surfaces.back.have);
assert!(surfaces.front.have);
assert!(!surfaces.back.have);
surfaces.back.layer_buffer_set = layer_buffer_set;

View file

@ -28,7 +28,7 @@ pub impl ResizeRateLimiter {
fn window_resized(&mut self, width: uint, height: uint) {
match self.last_response_port {
None => {
fail_unless!(self.next_resize_event.is_none());
assert!(self.next_resize_event.is_none());
self.send_event(width, height);
}
Some(*) => {
@ -48,7 +48,7 @@ pub impl ResizeRateLimiter {
fn check_resize_response(&mut self) {
match self.next_resize_event {
Some((copy width, copy height)) => {
fail_unless!(self.last_response_port.is_some());
assert!(self.last_response_port.is_some());
if self.last_response_port.get_ref().peek() {
self.send_event(width, height);
self.next_resize_event = None;

View file

@ -24,6 +24,21 @@ extern mod sharegl;
extern mod stb_image;
extern mod std;
#[cfg(target_os="macos")]
extern mod core_graphics;
#[cfg(target_os="macos")]
extern mod core_text;
use engine::{Engine, LoadURLMsg};
use platform::osmain::{AddKeyHandler, OSMain};
pub use gfx::opts::{Opts, Png, Screen}; // FIXME: Do we really want "Screen" and "Png" visible?
pub use gfx::resource;
pub use gfx::resource::image_cache_task::ImageCacheTask;
pub use gfx::resource::resource_task::ResourceTask;
pub use gfx::text;
pub use gfx::util::url::make_url;
pub mod content {
pub mod content_task;
}
@ -95,26 +110,6 @@ pub mod platform {
#[path = "util/mod.rs"]
pub mod util;
use servo_util = util;
#[cfg(target_os="macos")]
extern mod core_graphics;
#[cfg(target_os="macos")]
extern mod core_text;
use engine::{Engine, ExitMsg, LoadURLMsg}; // FIXME: "ExitMsg" is pollution.
use platform::osmain::{AddKeyHandler, OSMain};
use core::option::swap_unwrap;
use core::comm::{Port, Chan};
pub use gfx::opts::{Opts, Png, Screen}; // FIXME: Do we really want "Screen" and "Png" visible?
pub use gfx::resource;
pub use gfx::resource::image_cache_task::ImageCacheTask;
pub use gfx::resource::resource_task::ResourceTask;
pub use gfx::text;
pub use gfx::util::url::make_url;
fn main() {
let args = os::args();
run(&gfx::opts::from_cmdline_args(args))
@ -125,7 +120,7 @@ fn run(opts: &Opts) {
match &opts.render_mode {
&Screen => run_pipeline_screen(opts),
&Png(ref outfile) => {
fail_unless!(!opts.urls.is_empty());
assert!(!opts.urls.is_empty());
if opts.urls.len() > 1u {
fail!(~"servo asks that you stick to a single URL in PNG output mode")
}

View file

@ -1,5 +1,3 @@
use core::vec;
// A generic tree datatype.
//
// TODO: Use traits.
@ -13,12 +11,12 @@ pub struct Tree<T> {
}
pub trait ReadMethods<T> {
fn with_tree_fields<R>(&T, f: &fn(&mut Tree<T>) -> R) -> R;
fn with_tree_fields<R>(&self, &T, f: &fn(&mut Tree<T>) -> R) -> R;
}
pub trait WriteMethods<T> {
fn with_tree_fields<R>(&T, f: &fn(&mut Tree<T>) -> R) -> R;
pure fn tree_eq(&T, &T) -> bool;
fn with_tree_fields<R>(&self, &T, f: &fn(&mut Tree<T>) -> R) -> R;
fn tree_eq(&self, &T, &T) -> bool;
}
pub fn each_child<T:Copy,O:ReadMethods<T>>(ops: &O, node: &T, f: &fn(&T) -> bool) {
@ -69,7 +67,7 @@ pub fn empty<T>() -> Tree<T> {
}
pub fn add_child<T:Copy,O:WriteMethods<T>>(ops: &O, parent: T, child: T) {
fail_unless!(!ops.tree_eq(&parent, &child));
assert!(!ops.tree_eq(&parent, &child));
ops.with_tree_fields(&child, |child_tf| {
match child_tf.parent {
@ -77,8 +75,8 @@ pub fn add_child<T:Copy,O:WriteMethods<T>>(ops: &O, parent: T, child: T) {
None => { child_tf.parent = Some(parent); }
}
fail_unless!(child_tf.prev_sibling.is_none());
fail_unless!(child_tf.next_sibling.is_none());
assert!(child_tf.prev_sibling.is_none());
assert!(child_tf.next_sibling.is_none());
ops.with_tree_fields(&parent, |parent_tf| {
match copy parent_tf.last_child {
@ -87,7 +85,7 @@ pub fn add_child<T:Copy,O:WriteMethods<T>>(ops: &O, parent: T, child: T) {
}
Some(lc) => {
ops.with_tree_fields(&lc, |lc_tf| {
fail_unless!(lc_tf.next_sibling.is_none());
assert!(lc_tf.next_sibling.is_none());
lc_tf.next_sibling = Some(child);
});
child_tf.prev_sibling = Some(lc);
@ -104,7 +102,7 @@ pub fn remove_child<T:Copy,O:WriteMethods<T>>(ops: &O, parent: T, child: T) {
match copy child_tf.parent {
None => { fail!(~"Not a child"); }
Some(parent_n) => {
fail_unless!(ops.tree_eq(&parent, &parent_n));
assert!(ops.tree_eq(&parent, &parent_n));
// adjust parent fields
do ops.with_tree_fields(&parent) |parent_tf| {
@ -159,33 +157,33 @@ pub fn get_parent<T:Copy,O:ReadMethods<T>>(ops: &O, node: &T) -> Option<T> {
#[cfg(test)]
mod test {
use super::*;
use core::managed::ptr_eq;
use core::managed::mut_ptr_eq;
struct dummy {
fields: Tree<@dummy>,
fields: Tree<@mut dummy>,
value: uint
}
enum dtree { dtree }
impl ReadMethods<@dummy> for dtree {
fn with_tree_fields<R>(d: &@dummy, f: &fn(&Tree<@dummy>) -> R) -> R {
f(&d.fields)
impl ReadMethods<@mut dummy> for dtree {
fn with_tree_fields<R>(&self, d: &@mut dummy, f: &fn(&mut Tree<@mut dummy>) -> R) -> R {
f(&mut d.fields)
}
}
impl WriteMethods<@dummy> for dtree {
fn with_tree_fields<R>(d: &@dummy, f: &fn(&Tree<@dummy>) -> R) -> R {
f(&d.fields)
impl WriteMethods<@mut dummy> for dtree {
fn with_tree_fields<R>(&self, d: &@mut dummy, f: &fn(&mut Tree<@mut dummy>) -> R) -> R {
f(&mut d.fields)
}
pure fn tree_eq(a: &@dummy, b: &@dummy) -> bool { ptr_eq(*a, *b) }
fn tree_eq(&self, a: &@mut dummy, b: &@mut dummy) -> bool { mut_ptr_eq(*a, *b) }
}
fn new_dummy(v: uint) -> @dummy {
@dummy {fields: empty(), value: v}
fn new_dummy(v: uint) -> @mut dummy {
@mut dummy {fields: empty(), value: v}
}
fn parent_with_3_children() -> (@dummy, ~[@dummy]) {
fn parent_with_3_children() -> (@mut dummy, ~[@mut dummy]) {
let children = ~[new_dummy(0u),
new_dummy(1u),
new_dummy(2u)];
@ -203,10 +201,10 @@ mod test {
let (p, children) = parent_with_3_children();
let mut i = 0u;
for each_child(&dtree, &p) |c| {
fail_unless!(c.value == i);
assert!(c.value == i);
i += 1u;
}
fail_unless!(i == children.len());
assert!(i == children.len());
}
#[test]
@ -217,7 +215,7 @@ mod test {
i += 1u;
break;
}
fail_unless!(i == 1u);
assert!(i == 1u);
}
#[test]
@ -229,7 +227,7 @@ mod test {
for each_child(&dtree, &p) |_c| {
i += 1;
}
fail_unless!(i == 2);
assert!(i == 2);
}
#[test]
@ -241,7 +239,7 @@ mod test {
for each_child(&dtree, &p) |_c| {
i += 1;
}
fail_unless!(i == 2);
assert!(i == 2);
}
#[test]
@ -253,7 +251,7 @@ mod test {
for each_child(&dtree, &p) |_c| {
i += 1;
}
fail_unless!(i == 2);
assert!(i == 2);
}
#[test]
@ -267,6 +265,6 @@ mod test {
for each_child(&dtree, &p) |_c| {
i += 1;
}
fail_unless!(i == 0);
assert!(i == 0);
}
}

@ -1 +1 @@
Subproject commit 08f3a25f9465e7bf5638ddea384cfb2d17272e36
Subproject commit 4fc8d3f311a9c11078c574f5d82221c65367c70d