mirror of
https://github.com/servo/servo.git
synced 2025-08-05 13:40:08 +01:00
Update to Rust 0.6.
This commit is contained in:
parent
b9f82b8d05
commit
c850b59680
97 changed files with 1049 additions and 1135 deletions
|
@ -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
|
2
src/rust
2
src/rust
|
@ -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
|
|
@ -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: ~[] }
|
||||
}
|
||||
|
||||
|
|
|
@ -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(());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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 }
|
||||
}
|
||||
|
|
|
@ -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() }
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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 }
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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))
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 =
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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) => {
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
|
|
@ -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(%?): %?",
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
|
|
|
@ -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!");
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)));
|
||||
}
|
||||
|
|
|
@ -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")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
}
|
|
@ -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() {
|
||||
|
|
|
@ -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?");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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};
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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| {
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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,
|
||||
© 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) => {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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.")
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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")
|
||||
}
|
||||
|
|
|
@ -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
|
Loading…
Add table
Add a link
Reference in a new issue