mirror of
https://github.com/servo/servo.git
synced 2025-08-03 12:40:06 +01:00
Make servo build again
This commit is contained in:
parent
557de81c87
commit
3cf9b0f2b0
52 changed files with 376 additions and 317 deletions
|
@ -1 +1 @@
|
|||
Subproject commit f1670147011cee03a94c751d6d77a30c2330ee4d
|
||||
Subproject commit 461dcedfb36240f3c82f1d193f8cb42c9528fe34
|
|
@ -1,7 +1,7 @@
|
|||
use azure::azure_hl::{DrawTarget};
|
||||
use geom::rect::Rect;
|
||||
|
||||
struct LayerBuffer {
|
||||
pub struct LayerBuffer {
|
||||
draw_target: DrawTarget,
|
||||
|
||||
// The rect in the containing RenderLayer that this represents.
|
||||
|
@ -13,7 +13,7 @@ struct LayerBuffer {
|
|||
|
||||
/// A set of layer buffers. This is an atomic unit used to switch between the front and back
|
||||
/// buffers.
|
||||
struct LayerBufferSet {
|
||||
pub struct LayerBufferSet {
|
||||
buffers: ~[LayerBuffer]
|
||||
}
|
||||
|
||||
|
@ -21,7 +21,7 @@ struct LayerBufferSet {
|
|||
The interface used to by the renderer to aquire draw targets for
|
||||
each rendered frame and submit them to be drawn to the display
|
||||
*/
|
||||
trait Compositor {
|
||||
pub trait Compositor {
|
||||
fn begin_drawing(next_dt: pipes::Chan<LayerBufferSet>);
|
||||
fn draw(next_dt: pipes::Chan<LayerBufferSet>, +draw_me: LayerBufferSet);
|
||||
}
|
||||
|
|
|
@ -95,7 +95,7 @@ trait DisplayListMethods {
|
|||
fn draw_into_context(ctx: &RenderContext);
|
||||
}
|
||||
|
||||
impl DisplayList {
|
||||
pub impl DisplayList {
|
||||
static fn new() -> DisplayList {
|
||||
DisplayList { list: ~[] }
|
||||
}
|
||||
|
|
|
@ -43,7 +43,7 @@ pub trait FontHandleMethods {
|
|||
//
|
||||
// `new` should be part of trait FontHandleMethods.
|
||||
|
||||
impl FontHandle {
|
||||
pub impl FontHandle {
|
||||
#[cfg(target_os = "macos")]
|
||||
static pub fn new_from_buffer(fctx: &native::FontContextHandle, buf: ~[u8], style: &SpecifiedFontStyle) -> Result<FontHandle, ()> {
|
||||
quartz::font::QuartzFontHandle::new_from_buffer(fctx, move buf, style)
|
||||
|
@ -56,7 +56,7 @@ impl FontHandle {
|
|||
}
|
||||
|
||||
// Used to abstract over the shaper's choice of fixed int representation.
|
||||
type FractionalPixel = float;
|
||||
pub type FractionalPixel = float;
|
||||
|
||||
pub type FontTableTag = u32;
|
||||
|
||||
|
@ -80,11 +80,11 @@ pub type FontTable/& = quartz::font::QuartzFontTable;
|
|||
#[cfg(target_os = "linux")]
|
||||
pub type FontTable/& = freetype::font::FreeTypeFontTable;
|
||||
|
||||
trait FontTableMethods {
|
||||
pub trait FontTableMethods {
|
||||
fn with_buffer(fn&(*u8, uint));
|
||||
}
|
||||
|
||||
struct FontMetrics {
|
||||
pub struct FontMetrics {
|
||||
underline_size: Au,
|
||||
underline_offset: Au,
|
||||
leading: Au,
|
||||
|
@ -96,7 +96,7 @@ struct FontMetrics {
|
|||
}
|
||||
|
||||
// TODO(Issue #200): use enum from CSS bindings for 'font-weight'
|
||||
enum CSSFontWeight {
|
||||
pub enum CSSFontWeight {
|
||||
FontWeight100,
|
||||
FontWeight200,
|
||||
FontWeight300,
|
||||
|
@ -239,7 +239,7 @@ pub impl FontGroup {
|
|||
}
|
||||
}
|
||||
|
||||
struct RunMetrics {
|
||||
pub struct RunMetrics {
|
||||
// may be negative due to negative width (i.e., kerning of '.' in 'P.T.')
|
||||
advance_width: Au,
|
||||
ascent: Au, // nonzero
|
||||
|
@ -262,7 +262,7 @@ pub struct Font {
|
|||
backend: BackendType,
|
||||
}
|
||||
|
||||
impl Font {
|
||||
pub impl Font {
|
||||
static fn new_from_buffer(ctx: &FontContext, buffer: ~[u8],
|
||||
style: &SpecifiedFontStyle, backend: BackendType) -> Result<@Font, ()> {
|
||||
|
||||
|
@ -395,9 +395,9 @@ pub impl Font : FontMethods {
|
|||
use azure::{AzDrawOptions,
|
||||
AzGlyph,
|
||||
AzGlyphBuffer};
|
||||
use azure::bindgen::{AzCreateColorPattern,
|
||||
AzDrawTargetFillGlyphs,
|
||||
AzReleaseColorPattern};
|
||||
use azure::azure::bindgen::{AzCreateColorPattern,
|
||||
AzDrawTargetFillGlyphs,
|
||||
AzReleaseColorPattern};
|
||||
|
||||
let target = rctx.get_draw_target();
|
||||
let azfontref = self.get_azure_font();
|
||||
|
|
|
@ -36,7 +36,7 @@ type FontContextHandle/& = quartz::font_context::QuartzFontContextHandle;
|
|||
#[cfg(target_os = "linux")]
|
||||
type FontContextHandle/& = freetype::font_context::FreeTypeFontContextHandle;
|
||||
|
||||
trait FontContextHandleMethods {
|
||||
pub trait FontContextHandleMethods {
|
||||
pure fn clone(&const self) -> FontContextHandle;
|
||||
fn create_font_from_identifier(~str, UsedFontStyle) -> Result<FontHandle, ()>;
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ pub impl FontListHandle {
|
|||
}
|
||||
}
|
||||
|
||||
type FontFamilyMap = linear::LinearMap<~str, @FontFamily>;
|
||||
pub type FontFamilyMap = linear::LinearMap<~str, @FontFamily>;
|
||||
|
||||
trait FontListHandleMethods {
|
||||
fn get_available_families(&const self, fctx: &native::FontContextHandle) -> FontFamilyMap;
|
||||
|
@ -132,7 +132,7 @@ pub impl FontFamily {
|
|||
|
||||
// In the common case, each FontFamily will have a singleton FontEntry, or
|
||||
// it will have the standard four faces: Normal, Bold, Italic, BoldItalic.
|
||||
struct FontEntry {
|
||||
pub struct FontEntry {
|
||||
family: @FontFamily,
|
||||
face_name: ~str,
|
||||
priv weight: CSSFontWeight,
|
||||
|
@ -141,7 +141,7 @@ struct FontEntry {
|
|||
// TODO: array of OpenType features, etc.
|
||||
}
|
||||
|
||||
impl FontEntry {
|
||||
pub impl FontEntry {
|
||||
static fn new(family: @FontFamily, handle: FontHandle) -> FontEntry {
|
||||
FontEntry {
|
||||
family: family,
|
||||
|
|
|
@ -5,7 +5,7 @@ use fc = fontconfig;
|
|||
use ft = freetype;
|
||||
|
||||
use gfx_font::FontHandle;
|
||||
use gfx_font_list::{FontEntry, FontFamily};
|
||||
use gfx_font_list::{FontEntry, FontFamily, FontFamilyMap};
|
||||
|
||||
use core::dvec::DVec;
|
||||
use core::send_map::{linear, SendMap};
|
||||
|
@ -19,9 +19,11 @@ pub impl FontconfigFontListHandle {
|
|||
FontconfigFontListHandle { fctx: () }
|
||||
}
|
||||
|
||||
fn get_available_families(&const self,
|
||||
_fctx: &native::FontContextHandle)
|
||||
-> linear::LinearMap<~str, @FontFamily> {
|
||||
fn get_available_families() -> FontFamilyMap {
|
||||
fail;
|
||||
}
|
||||
|
||||
fn load_variations_for_family(family: @FontFamily) {
|
||||
fail
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,8 @@ use gfx_font::{
|
|||
FontHandle,
|
||||
FontHandleMethods,
|
||||
FontMetrics,
|
||||
FontTable,
|
||||
FontTableMethods,
|
||||
FontTableTag,
|
||||
FractionalPixel,
|
||||
SpecifiedFontStyle,
|
||||
|
@ -15,7 +17,7 @@ use geometry::Au;
|
|||
use text::glyph::GlyphIndex;
|
||||
use text::util::{float_to_fixed, fixed_to_float};
|
||||
|
||||
use freetype::{
|
||||
use freetype::freetype::{
|
||||
FTErrorMethods,
|
||||
FT_Error,
|
||||
FT_F26Dot6,
|
||||
|
@ -30,7 +32,7 @@ use freetype::{
|
|||
FT_UInt,
|
||||
FT_Size_Metrics,
|
||||
};
|
||||
use freetype::bindgen::{
|
||||
use freetype::freetype::bindgen::{
|
||||
FT_Init_FreeType,
|
||||
FT_Done_FreeType,
|
||||
FT_New_Memory_Face,
|
||||
|
@ -48,6 +50,16 @@ fn fixed_to_float_ft(f: i32) -> float {
|
|||
fixed_to_float(6, f)
|
||||
}
|
||||
|
||||
pub struct FreeTypeFontTable {
|
||||
bogus: ()
|
||||
}
|
||||
|
||||
pub impl FreeTypeFontTable : FontTableMethods {
|
||||
fn with_buffer(blk: fn&(*u8, uint)) {
|
||||
fail
|
||||
}
|
||||
}
|
||||
|
||||
pub struct FreeTypeFontHandle {
|
||||
// The font binary. This must stay valid for the lifetime of the font,
|
||||
// if the font is created using FT_Memory_Face.
|
||||
|
@ -184,7 +196,7 @@ pub impl FreeTypeFontHandle : FontHandleMethods {
|
|||
}
|
||||
}
|
||||
|
||||
fn get_table_for_tag(_tag: FontTableTag) -> Option<~[u8]> {
|
||||
fn get_table_for_tag(_tag: FontTableTag) -> Option<FontTable> {
|
||||
fail;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
extern mod freetype;
|
||||
|
||||
use freetype::{
|
||||
use freetype::freetype::{
|
||||
FTErrorMethods,
|
||||
FT_Error,
|
||||
FT_Library,
|
||||
};
|
||||
use freetype::bindgen::{
|
||||
use freetype::freetype::bindgen::{
|
||||
FT_Init_FreeType,
|
||||
FT_Done_FreeType
|
||||
};
|
||||
|
@ -38,6 +38,10 @@ pub impl FreeTypeFontContextHandle {
|
|||
}
|
||||
|
||||
pub impl FreeTypeFontContextHandle : FontContextHandleMethods {
|
||||
pure fn clone(&const self) -> FreeTypeFontContextHandle {
|
||||
fail
|
||||
}
|
||||
|
||||
fn create_font_from_identifier(_identifier: ~str, _style: UsedFontStyle)
|
||||
-> Result<FontHandle, ()> {
|
||||
|
||||
|
|
|
@ -41,12 +41,12 @@ pub fn from_cmdline_args(args: &[~str]) -> Opts {
|
|||
copy opt_match.free
|
||||
};
|
||||
|
||||
let render_mode = match getopts::opt_maybe_str(copy opt_match, ~"o") {
|
||||
let render_mode = match getopts::opt_maybe_str(&opt_match, ~"o") {
|
||||
Some(move output_file) => { Png(move output_file) }
|
||||
None => { Screen }
|
||||
};
|
||||
|
||||
let render_backend = match getopts::opt_maybe_str(copy opt_match, ~"r") {
|
||||
let render_backend = match getopts::opt_maybe_str(&opt_match, ~"r") {
|
||||
Some(move backend_str) => {
|
||||
if backend_str == ~"direct2d" {
|
||||
Direct2DBackend
|
||||
|
@ -65,12 +65,12 @@ pub fn from_cmdline_args(args: &[~str]) -> Opts {
|
|||
None => CairoBackend
|
||||
};
|
||||
|
||||
let tile_size: uint = match getopts::opt_maybe_str(copy opt_match, ~"s") {
|
||||
let tile_size: uint = match getopts::opt_maybe_str(&opt_match, ~"s") {
|
||||
Some(move tile_size_str) => from_str::from_str(tile_size_str).get(),
|
||||
None => 512,
|
||||
};
|
||||
|
||||
let n_render_threads: uint = match getopts::opt_maybe_str(move opt_match, ~"t") {
|
||||
let n_render_threads: uint = match getopts::opt_maybe_str(&opt_match, ~"t") {
|
||||
Some(move n_render_threads_str) => from_str::from_str(n_render_threads_str).get(),
|
||||
None => 1, // FIXME: Number of cores.
|
||||
};
|
||||
|
|
|
@ -16,7 +16,7 @@ use geom::rect::Rect;
|
|||
use geom::size::Size2D;
|
||||
use std::arc::ARC;
|
||||
|
||||
struct RenderContext {
|
||||
pub struct RenderContext {
|
||||
canvas: &LayerBuffer,
|
||||
font_ctx: @FontContext,
|
||||
opts: &Opts
|
||||
|
|
|
@ -106,7 +106,7 @@ impl<C: Compositor Send> Renderer<C> {
|
|||
let layer_buffer_set_cell = Cell(move layer_buffer_set);
|
||||
let layer_buffer_set_channel_cell = Cell(move layer_buffer_set_channel);
|
||||
|
||||
#debug("renderer: rendering");
|
||||
debug!("renderer: rendering");
|
||||
|
||||
do util::time::time(~"rendering") {
|
||||
let layer_buffer_set = layer_buffer_set_cell.take();
|
||||
|
@ -150,7 +150,7 @@ impl<C: Compositor Send> Renderer<C> {
|
|||
}
|
||||
};
|
||||
|
||||
#debug("renderer: returning surface");
|
||||
debug!("renderer: returning surface");
|
||||
self.compositor.draw(move layer_buffer_set_channel, move layer_buffer_set);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ pub fn factory(url: Url, progress_chan: Chan<ProgressMsg>) {
|
|||
assert url.scheme == ~"http";
|
||||
|
||||
do spawn |move url| {
|
||||
#debug("http_loader: requesting via http: %?", copy url);
|
||||
debug!("http_loader: requesting via http: %?", copy url);
|
||||
let request = uv_http_request(copy url);
|
||||
let errored = @mut false;
|
||||
do request.begin |event, copy url| {
|
||||
|
@ -18,13 +18,13 @@ pub fn factory(url: Url, progress_chan: Chan<ProgressMsg>) {
|
|||
match event {
|
||||
http_client::Status(*) => { }
|
||||
http_client::Payload(data) => {
|
||||
#debug("http_loader: got data from %?", url);
|
||||
debug!("http_loader: got data from %?", url);
|
||||
let mut junk = None;
|
||||
*data <-> junk;
|
||||
progress_chan.send(Payload(option::unwrap(move junk)));
|
||||
}
|
||||
http_client::Error(*) => {
|
||||
#debug("http_loader: error loading %?", url);
|
||||
debug!("http_loader: error loading %?", url);
|
||||
*errored = true;
|
||||
progress_chan.send(Done(Err(())));
|
||||
}
|
||||
|
|
|
@ -178,7 +178,7 @@ impl ImageCache {
|
|||
|
||||
for msg_handlers.each |handler| { (*handler)(&msg) }
|
||||
|
||||
#debug("image_cache_task: received: %?", msg);
|
||||
debug!("image_cache_task: received: %?", msg);
|
||||
|
||||
match move msg {
|
||||
Prefetch(move url) => self.prefetch(move url),
|
||||
|
@ -249,7 +249,7 @@ impl ImageCache {
|
|||
|
||||
do spawn |move to_cache, move url_cell| {
|
||||
let url = url_cell.take();
|
||||
#debug("image_cache_task: started fetch for %s", url.to_str());
|
||||
debug!("image_cache_task: started fetch for %s", url.to_str());
|
||||
|
||||
let image = load_image_data(copy url, resource_task);
|
||||
|
||||
|
@ -259,7 +259,7 @@ impl ImageCache {
|
|||
Err(())
|
||||
};
|
||||
to_cache.send(StorePrefetchedImageData(copy url, move result));
|
||||
#debug("image_cache_task: ended fetch for %s", (copy url).to_str());
|
||||
debug!("image_cache_task: ended fetch for %s", (copy url).to_str());
|
||||
}
|
||||
|
||||
self.set_state(move url, Prefetching(DoNotDecode));
|
||||
|
@ -327,7 +327,7 @@ impl ImageCache {
|
|||
|
||||
do spawn |move url_cell, move decode, move data, move to_cache| {
|
||||
let url = url_cell.take();
|
||||
#debug("image_cache_task: started image decode for %s", url.to_str());
|
||||
debug!("image_cache_task: started image decode for %s", url.to_str());
|
||||
let image = decode(data);
|
||||
let image = if image.is_some() {
|
||||
Some(ARC(~option::unwrap(move image)))
|
||||
|
@ -335,7 +335,7 @@ impl ImageCache {
|
|||
None
|
||||
};
|
||||
to_cache.send(StoreImage(copy url, move image));
|
||||
#debug("image_cache_task: ended image decode for %s", url.to_str());
|
||||
debug!("image_cache_task: ended image decode for %s", url.to_str());
|
||||
}
|
||||
|
||||
self.set_state(move url, Decoding);
|
||||
|
|
|
@ -100,11 +100,11 @@ impl ResourceManager {
|
|||
|
||||
match self.get_loader_factory(&url) {
|
||||
Some(loader_factory) => {
|
||||
#debug("resource_task: loading url: %s", to_str(copy url));
|
||||
debug!("resource_task: loading url: %s", to_str(copy url));
|
||||
loader_factory(move url, progress_chan);
|
||||
}
|
||||
None => {
|
||||
#debug("resource_task: no loader for scheme %s", url.scheme);
|
||||
debug!("resource_task: no loader for scheme %s", url.scheme);
|
||||
progress_chan.send(Done(Err(())));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,58 +36,68 @@ pub mod native;
|
|||
|
||||
#[cfg(target_os = "macos")]
|
||||
pub mod quartz {
|
||||
#[path = "quartz/font.rs"]
|
||||
pub mod font;
|
||||
#[path = "quartz/font_context.rs"]
|
||||
pub mod font_context;
|
||||
#[path = "quartz/font_list.rs"]
|
||||
pub mod font_list;
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
pub mod freetype {
|
||||
#[path = "freetype/font.rs"]
|
||||
pub mod font;
|
||||
#[path = "freetype/font_context.rs"]
|
||||
pub mod font_context;
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
pub mod fontconfig {
|
||||
#[path = "fontconfig/font_list.rs"]
|
||||
pub mod font_list;
|
||||
}
|
||||
|
||||
// Images
|
||||
pub mod image {
|
||||
#[path = "image/base.rs"]
|
||||
pub mod base;
|
||||
pub mod encode {
|
||||
#[path = "image/encode/tga.rs"]
|
||||
pub mod tga;
|
||||
}
|
||||
#[path = "image/holder.rs"]
|
||||
pub mod holder;
|
||||
}
|
||||
|
||||
// Text
|
||||
pub mod text {
|
||||
pub mod glyph;
|
||||
pub mod text_run;
|
||||
pub mod util;
|
||||
pub mod shaper;
|
||||
|
||||
// Below are the actual platform-specific parts.
|
||||
pub mod harfbuzz {
|
||||
pub mod shaper;
|
||||
}
|
||||
}
|
||||
#[path = "text/mod.rs"]
|
||||
pub mod text;
|
||||
|
||||
// FIXME: Blech. This does not belong in the GFX module.
|
||||
pub mod resource {
|
||||
#[path = "resource/file_loader.rs"]
|
||||
pub mod file_loader;
|
||||
#[path = "resource/http_loader.rs"]
|
||||
pub mod http_loader;
|
||||
#[path = "resource/image_cache_task.rs"]
|
||||
pub mod image_cache_task;
|
||||
#[path = "resource/local_image_cache.rs"]
|
||||
pub mod local_image_cache;
|
||||
#[path = "resource/resource_task.rs"]
|
||||
pub mod resource_task;
|
||||
}
|
||||
|
||||
pub mod util {
|
||||
#[path = "util/cache.rs"]
|
||||
pub mod cache;
|
||||
#[path = "util/range.rs"]
|
||||
pub mod range;
|
||||
#[path = "util/time.rs"]
|
||||
pub mod time;
|
||||
#[path = "util/url.rs"]
|
||||
pub mod url;
|
||||
#[path = "util/vec.rs"]
|
||||
pub mod vec;
|
||||
}
|
||||
|
||||
|
@ -95,3 +105,7 @@ use servo_util = util;
|
|||
use gfx_font = font;
|
||||
use gfx_font_context = font_context;
|
||||
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,5 +0,0 @@
|
|||
// FIXME: Blech. We need crate-relative imports.
|
||||
pub use servo_gfx_font = font;
|
||||
pub use servo_gfx_font_list = font_list;
|
||||
pub use servo_gfx_util = util;
|
||||
|
|
@ -29,10 +29,10 @@ struct GlyphEntry {
|
|||
pure fn GlyphEntry(value: u32) -> GlyphEntry { GlyphEntry { value: value } }
|
||||
|
||||
/// The index of a particular glyph within a font
|
||||
type GlyphIndex = u32;
|
||||
pub type GlyphIndex = u32;
|
||||
|
||||
// TODO: unify with bit flags?
|
||||
enum BreakType {
|
||||
pub enum BreakType {
|
||||
BreakTypeNone,
|
||||
BreakTypeNormal,
|
||||
BreakTypeHyphen
|
||||
|
@ -426,7 +426,7 @@ impl DetailedGlyphStore {
|
|||
|
||||
// This struct is used by GlyphStore clients to provide new glyph data.
|
||||
// It should be allocated on the stack and passed by reference to GlyphStore.
|
||||
struct GlyphData {
|
||||
pub struct GlyphData {
|
||||
index: GlyphIndex,
|
||||
advance: Au,
|
||||
offset: Point2D<Au>,
|
||||
|
@ -435,7 +435,7 @@ struct GlyphData {
|
|||
ligature_start: bool,
|
||||
}
|
||||
|
||||
pure fn GlyphData(index: GlyphIndex,
|
||||
pub pure fn GlyphData(index: GlyphIndex,
|
||||
advance: Au,
|
||||
offset: Option<Point2D<Au>>,
|
||||
is_missing: bool,
|
||||
|
@ -505,13 +505,13 @@ impl GlyphInfo {
|
|||
}
|
||||
|
||||
// Public data structure and API for storing and retrieving glyph data
|
||||
struct GlyphStore {
|
||||
pub struct GlyphStore {
|
||||
// we use a DVec here instead of a mut vec, since this is much safer.
|
||||
entry_buffer: ~[GlyphEntry],
|
||||
detail_store: DetailedGlyphStore,
|
||||
}
|
||||
|
||||
impl 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 {
|
||||
|
|
|
@ -209,6 +209,9 @@ pub impl HarfbuzzShaper : ShaperMethods {
|
|||
self.save_glyph_results(text, glyphs, hb_buffer);
|
||||
hb_buffer_destroy(hb_buffer);
|
||||
}
|
||||
}
|
||||
|
||||
pub impl HarfbuzzShaper {
|
||||
|
||||
priv fn save_glyph_results(text: &str, glyphs: &mut GlyphStore, buffer: *hb_buffer_t) {
|
||||
let glyph_data = ShapedGlyphData::new(buffer);
|
||||
|
@ -239,8 +242,9 @@ pub impl HarfbuzzShaper : ShaperMethods {
|
|||
let mut i = 0u;
|
||||
while i < byte_max {
|
||||
byteToGlyph[i] = NO_GLYPH;
|
||||
let {ch, next} = str::char_range_at(text, i); ignore(ch);
|
||||
i = next;
|
||||
let range = str::char_range_at(text, i);
|
||||
ignore(range.ch);
|
||||
i = range.next;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -260,9 +264,9 @@ pub impl HarfbuzzShaper : ShaperMethods {
|
|||
debug!("(char idx): char->(glyph index):");
|
||||
let mut i = 0u;
|
||||
while i < byte_max {
|
||||
let {ch, next} = str::char_range_at(text, i);
|
||||
debug!("%u: %? --> %d", i, ch, byteToGlyph[i] as int);
|
||||
i = next;
|
||||
let range = str::char_range_at(text, i);
|
||||
debug!("%u: %? --> %d", i, range.ch, byteToGlyph[i] as int);
|
||||
i = range.next;
|
||||
}
|
||||
|
||||
// some helpers
|
||||
|
@ -285,16 +289,18 @@ pub impl HarfbuzzShaper : ShaperMethods {
|
|||
// find a range of chars corresponding to this glyph, plus
|
||||
// any trailing chars that do not have associated glyphs.
|
||||
while char_byte_span.end() < byte_max {
|
||||
let {ch, next} = str::char_range_at(text, char_byte_span.end()); ignore(ch);
|
||||
char_byte_span.extend_to(next);
|
||||
let range = str::char_range_at(text, char_byte_span.end());
|
||||
ignore(range.ch);
|
||||
char_byte_span.extend_to(range.next);
|
||||
|
||||
debug!("Processing char byte span: off=%u, len=%u for glyph idx=%u",
|
||||
char_byte_span.begin(), char_byte_span.length(), glyph_span.begin());
|
||||
|
||||
while char_byte_span.end() != byte_max && byteToGlyph[char_byte_span.end()] == NO_GLYPH {
|
||||
debug!("Extending char byte span to include byte offset=%u with no associated glyph", char_byte_span.end());
|
||||
let {ch, next} = str::char_range_at(text, char_byte_span.end()); ignore(ch);
|
||||
char_byte_span.extend_to(next);
|
||||
let range = str::char_range_at(text, char_byte_span.end());
|
||||
ignore(range.ch);
|
||||
char_byte_span.extend_to(range.next);
|
||||
}
|
||||
|
||||
// extend glyph range to max glyph index covered by char_span,
|
||||
|
@ -356,8 +362,9 @@ pub impl HarfbuzzShaper : ShaperMethods {
|
|||
// extend, clipping at end of text range.
|
||||
while covered_byte_span.end() < byte_max
|
||||
&& byteToGlyph[covered_byte_span.end()] == NO_GLYPH {
|
||||
let {ch, next} = str::char_range_at(text, covered_byte_span.end()); ignore(ch);
|
||||
covered_byte_span.extend_to(next);
|
||||
let range = str::char_range_at(text, covered_byte_span.end());
|
||||
ignore(range.ch);
|
||||
covered_byte_span.extend_to(range.next);
|
||||
}
|
||||
|
||||
if covered_byte_span.begin() >= byte_max {
|
||||
|
@ -400,8 +407,9 @@ pub impl HarfbuzzShaper : ShaperMethods {
|
|||
// set the other chars, who have no glyphs
|
||||
let mut i = covered_byte_span.begin();
|
||||
loop {
|
||||
let {ch, next} = str::char_range_at(text, i); ignore(ch);
|
||||
i = next;
|
||||
let range = str::char_range_at(text, i);
|
||||
ignore(range.ch);
|
||||
i = range.next;
|
||||
if i >= covered_byte_span.end() { break; }
|
||||
char_idx += 1;
|
||||
glyphs.add_nonglyph_for_char_index(char_idx, false, false);
|
||||
|
|
|
@ -7,3 +7,14 @@ servo.rc. This is not ideal and may be changed in the future. */
|
|||
pub use shaper::Shaper;
|
||||
pub use text_run::TextRun;
|
||||
pub use text_run::SendableTextRun;
|
||||
|
||||
pub mod glyph;
|
||||
pub mod text_run;
|
||||
pub mod util;
|
||||
pub mod shaper;
|
||||
|
||||
// Below are the actual platform-specific parts.
|
||||
pub mod harfbuzz {
|
||||
#[path = "harfbuzz/shaper.rs"]
|
||||
pub mod shaper;
|
||||
}
|
|
@ -9,14 +9,14 @@ use text::glyph::GlyphStore;
|
|||
|
||||
pub type Shaper/& = harfbuzz::shaper::HarfbuzzShaper;
|
||||
|
||||
trait ShaperMethods {
|
||||
pub trait ShaperMethods {
|
||||
fn shape_text(text: &str, glyphs: &mut GlyphStore);
|
||||
|
||||
}
|
||||
|
||||
// TODO(Issue #163): this is a workaround for static methods and
|
||||
// typedefs not working well together. It should be removed.
|
||||
impl Shaper {
|
||||
pub impl Shaper {
|
||||
static pub fn new(font: @Font) -> Shaper {
|
||||
harfbuzz::shaper::HarfbuzzShaper::new(font)
|
||||
}
|
||||
|
|
|
@ -42,7 +42,7 @@ impl SendableTextRun {
|
|||
}
|
||||
}
|
||||
|
||||
impl TextRun {
|
||||
pub impl TextRun {
|
||||
static fn new(font: @Font, text: ~str) -> TextRun {
|
||||
let mut glyph_store = GlyphStore::new(str::char_len(text));
|
||||
TextRun::compute_potential_breaks(text, &mut glyph_store);
|
||||
|
@ -63,7 +63,9 @@ impl TextRun {
|
|||
let mut char_j = 0u;
|
||||
let mut prev_is_whitespace = false;
|
||||
while byte_i < text.len() {
|
||||
let {ch, next} = str::char_range_at(text, byte_i);
|
||||
let range = str::char_range_at(text, byte_i);
|
||||
let ch = range.ch;
|
||||
let next = range.next;
|
||||
// set char properties.
|
||||
match ch {
|
||||
' ' => { glyphs.set_char_is_space(char_j); },
|
||||
|
|
|
@ -7,7 +7,7 @@ pub fn time<T>(msg: &str, callback: fn() -> T) -> T{
|
|||
let end_time = precise_time_ns();
|
||||
let ms = ((end_time - start_time) / 1000000u64) as uint;
|
||||
if ms >= 5 {
|
||||
#debug("%s took %u ms", msg, ms);
|
||||
debug!("%s took %u ms", msg, ms);
|
||||
}
|
||||
return move val;
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ pub fn make_url(str_url: ~str, current_url: Option<Url>) -> Url {
|
|||
~"file://" + os::getcwd().push(str_url).to_str()
|
||||
} else {
|
||||
let current_url = current_url.get();
|
||||
#debug("make_url: current_url: %?", current_url);
|
||||
debug!("make_url: current_url: %?", current_url);
|
||||
if current_url.path.is_empty() || current_url.path.ends_with("/") {
|
||||
current_url.scheme + "://" + current_url.host + "/" + str_url
|
||||
} else {
|
||||
|
@ -47,7 +47,7 @@ mod make_url_tests {
|
|||
fn should_create_absolute_file_url_if_current_url_is_none_and_str_url_looks_filey() {
|
||||
let file = ~"local.html";
|
||||
let url = make_url(move file, None);
|
||||
#debug("url: %?", url);
|
||||
debug!("url: %?", url);
|
||||
assert url.scheme == ~"file";
|
||||
assert url.path.contains(os::getcwd().to_str());
|
||||
}
|
||||
|
|
|
@ -48,7 +48,7 @@ pub enum PingMsg {
|
|||
|
||||
pub type ContentTask = pipes::SharedChan<ControlMsg>;
|
||||
|
||||
fn ContentTask(layout_task: LayoutTask,
|
||||
pub fn ContentTask(layout_task: LayoutTask,
|
||||
dom_event_port: pipes::Port<Event>,
|
||||
dom_event_chan: pipes::SharedChan<Event>,
|
||||
resource_task: ResourceTask,
|
||||
|
@ -102,7 +102,7 @@ pub struct Content {
|
|||
mut damage: Damage,
|
||||
}
|
||||
|
||||
fn Content(layout_task: LayoutTask,
|
||||
pub fn Content(layout_task: LayoutTask,
|
||||
control_port: pipes::Port<ControlMsg>,
|
||||
control_chan: pipes::SharedChan<ControlMsg>,
|
||||
resource_task: ResourceTask,
|
||||
|
|
|
@ -81,7 +81,7 @@ unsafe fn unwrap(obj: *JSObject) -> *rust_box<Document> {
|
|||
}
|
||||
|
||||
extern fn finalize(_fop: *JSFreeOp, obj: *JSObject) {
|
||||
#debug("document finalize!");
|
||||
debug!("document finalize!");
|
||||
unsafe {
|
||||
let val = JS_GetReservedSlot(obj, 0);
|
||||
let _doc: @Document = cast::reinterpret_cast(&RUST_JSVAL_TO_PRIVATE(val));
|
||||
|
|
|
@ -23,7 +23,7 @@ use node::unwrap;
|
|||
|
||||
|
||||
extern fn finalize(_fop: *JSFreeOp, obj: *JSObject) {
|
||||
#debug("element finalize!");
|
||||
debug!("element finalize!");
|
||||
unsafe {
|
||||
let val = JS_GetReservedSlot(obj, 0);
|
||||
let _node: ~NodeBundle = cast::reinterpret_cast(&RUST_JSVAL_TO_PRIVATE(val));
|
||||
|
|
|
@ -61,19 +61,19 @@ pub fn create(cx: *JSContext, node: Node, scope: NodeScope) -> jsobj unsafe {
|
|||
}
|
||||
}
|
||||
|
||||
struct NodeBundle {
|
||||
pub struct NodeBundle {
|
||||
node: Node,
|
||||
scope: NodeScope,
|
||||
}
|
||||
|
||||
fn NodeBundle(n: Node, s: NodeScope) -> NodeBundle {
|
||||
pub fn NodeBundle(n: Node, s: NodeScope) -> NodeBundle {
|
||||
NodeBundle {
|
||||
node : n,
|
||||
scope : s
|
||||
}
|
||||
}
|
||||
|
||||
unsafe fn unwrap(obj: *JSObject) -> *rust_box<NodeBundle> {
|
||||
pub unsafe fn unwrap(obj: *JSObject) -> *rust_box<NodeBundle> {
|
||||
let val = js::GetReservedSlot(obj, 0);
|
||||
cast::reinterpret_cast(&JSVAL_TO_PRIVATE(val))
|
||||
}
|
||||
|
|
|
@ -12,27 +12,27 @@ use js::glue::bindgen::*;
|
|||
use ptr::null;
|
||||
use content::content_task::{Content, task_from_context};
|
||||
|
||||
enum DOMString {
|
||||
pub enum DOMString {
|
||||
str(~str),
|
||||
null_string
|
||||
}
|
||||
|
||||
type rust_box<T> = {rc: uint, td: *sys::TypeDesc, next: *(), prev: *(), payload: T};
|
||||
pub type rust_box<T> = {rc: uint, td: *sys::TypeDesc, next: *(), prev: *(), payload: T};
|
||||
|
||||
unsafe fn squirrel_away<T>(x: @T) -> *rust_box<T> {
|
||||
pub unsafe fn squirrel_away<T>(x: @T) -> *rust_box<T> {
|
||||
let y: *rust_box<T> = cast::reinterpret_cast(&x);
|
||||
cast::forget(x);
|
||||
y
|
||||
}
|
||||
|
||||
unsafe fn squirrel_away_unique<T>(x: ~T) -> *rust_box<T> {
|
||||
pub unsafe fn squirrel_away_unique<T>(x: ~T) -> *rust_box<T> {
|
||||
let y: *rust_box<T> = cast::reinterpret_cast(&x);
|
||||
cast::forget(move x);
|
||||
y
|
||||
}
|
||||
|
||||
//XXX very incomplete
|
||||
fn jsval_to_str(cx: *JSContext, v: JSVal) -> Result<~str, ()> {
|
||||
pub fn jsval_to_str(cx: *JSContext, v: JSVal) -> Result<~str, ()> {
|
||||
let jsstr;
|
||||
if RUST_JSVAL_IS_STRING(v) == 1 {
|
||||
jsstr = RUST_JSVAL_TO_STRING(v)
|
||||
|
@ -55,7 +55,7 @@ fn jsval_to_str(cx: *JSContext, v: JSVal) -> Result<~str, ()> {
|
|||
}
|
||||
}
|
||||
|
||||
unsafe fn domstring_to_jsval(cx: *JSContext, string: &DOMString) -> JSVal {
|
||||
pub unsafe fn domstring_to_jsval(cx: *JSContext, string: &DOMString) -> JSVal {
|
||||
match *string {
|
||||
null_string => {
|
||||
JSVAL_NULL
|
||||
|
|
|
@ -57,7 +57,7 @@ unsafe fn unwrap(obj: *JSObject) -> *rust_box<Window> {
|
|||
}
|
||||
|
||||
extern fn finalize(_fop: *JSFreeOp, obj: *JSObject) {
|
||||
#debug("finalize!");
|
||||
debug!("finalize!");
|
||||
unsafe {
|
||||
let val = JS_GetReservedSlot(obj, 0);
|
||||
let _: @Window = cast::reinterpret_cast(&RUST_JSVAL_TO_PRIVATE(val));
|
||||
|
|
|
@ -224,7 +224,7 @@ impl<T:Copy Send,A> Scope<T,A> {
|
|||
let const_read_ptr = ptr::const_offset(h.read_ptr(), 0);
|
||||
let const_write_ptr = ptr::const_offset(h.write_ptr(), 0);
|
||||
if self.d.layout_active && const_read_ptr == const_write_ptr {
|
||||
#debug["marking handle %? as dirty", h];
|
||||
debug!("marking handle %? as dirty", h);
|
||||
h.set_write_ptr(cast::reinterpret_cast(&self.clone(h.read_ptr())));
|
||||
h.set_next_dirty(self.d.first_dirty);
|
||||
self.d.first_dirty = *h;
|
||||
|
|
|
@ -2,12 +2,12 @@ use newcss::stylesheet::Stylesheet;
|
|||
use dom::node::{NodeScope, Node};
|
||||
use std::arc::ARC;
|
||||
|
||||
struct Document {
|
||||
pub struct Document {
|
||||
root: Node,
|
||||
scope: NodeScope,
|
||||
}
|
||||
|
||||
fn Document(root: Node, scope: NodeScope) -> Document {
|
||||
pub fn Document(root: Node, scope: NodeScope) -> Document {
|
||||
Document {
|
||||
root : root,
|
||||
scope : scope,
|
||||
|
|
|
@ -4,7 +4,7 @@ use dvec::DVec;
|
|||
use geom::size::Size2D;
|
||||
use std::net::url::Url;
|
||||
|
||||
struct ElementData {
|
||||
pub struct ElementData {
|
||||
tag_name: ~str,
|
||||
kind: ~ElementKind,
|
||||
attrs: DVec<~Attr>,
|
||||
|
@ -43,7 +43,7 @@ impl ElementData {
|
|||
}
|
||||
}
|
||||
|
||||
fn ElementData(tag_name: ~str, kind: ~ElementKind) -> ElementData {
|
||||
pub fn ElementData(tag_name: ~str, kind: ~ElementKind) -> ElementData {
|
||||
ElementData {
|
||||
tag_name : move tag_name,
|
||||
kind : move kind,
|
||||
|
@ -51,29 +51,29 @@ fn ElementData(tag_name: ~str, kind: ~ElementKind) -> ElementData {
|
|||
}
|
||||
}
|
||||
|
||||
struct Attr {
|
||||
pub struct Attr {
|
||||
name: ~str,
|
||||
value: ~str,
|
||||
}
|
||||
|
||||
fn Attr(name: ~str, value: ~str) -> Attr {
|
||||
pub fn Attr(name: ~str, value: ~str) -> Attr {
|
||||
Attr {
|
||||
name : move name,
|
||||
value : move value,
|
||||
}
|
||||
}
|
||||
|
||||
fn HTMLImageData() -> HTMLImageData {
|
||||
pub fn HTMLImageData() -> HTMLImageData {
|
||||
HTMLImageData {
|
||||
image: None
|
||||
}
|
||||
}
|
||||
|
||||
struct HTMLImageData {
|
||||
pub struct HTMLImageData {
|
||||
mut image: Option<Url>
|
||||
}
|
||||
|
||||
enum HeadingLevel {
|
||||
pub enum HeadingLevel {
|
||||
Heading1,
|
||||
Heading2,
|
||||
Heading3,
|
||||
|
@ -82,7 +82,7 @@ enum HeadingLevel {
|
|||
Heading6,
|
||||
}
|
||||
|
||||
enum ElementKind {
|
||||
pub enum ElementKind {
|
||||
HTMLAnchorElement,
|
||||
HTMLAsideElement,
|
||||
HTMLBRElement,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
enum Event {
|
||||
pub enum Event {
|
||||
ResizeEvent(uint, uint, pipes::Chan<()>),
|
||||
ReflowEvent
|
||||
}
|
||||
|
|
|
@ -16,15 +16,15 @@ use ptr::null;
|
|||
use std::arc::ARC;
|
||||
use util::tree;
|
||||
|
||||
enum NodeData = {
|
||||
pub enum NodeData = {
|
||||
tree: tree::Tree<Node>,
|
||||
kind: ~NodeKind,
|
||||
};
|
||||
|
||||
/* The tree holding Nodes (read-only) */
|
||||
enum NodeTree { NodeTree }
|
||||
pub enum NodeTree { NodeTree }
|
||||
|
||||
impl NodeTree : tree::ReadMethods<Node> {
|
||||
impl NodeTree {
|
||||
fn each_child(node: &Node, f: fn(&Node) -> bool) {
|
||||
tree::each_child(&self, node, f)
|
||||
}
|
||||
|
@ -32,7 +32,9 @@ impl NodeTree : tree::ReadMethods<Node> {
|
|||
fn get_parent(node: &Node) -> Option<Node> {
|
||||
tree::get_parent(&self, node)
|
||||
}
|
||||
}
|
||||
|
||||
impl NodeTree : tree::ReadMethods<Node> {
|
||||
fn with_tree_fields<R>(n: &Node, f: fn(&tree::Tree<Node>) -> R) -> R {
|
||||
n.read(|n| f(&n.tree))
|
||||
}
|
||||
|
@ -91,14 +93,14 @@ pub enum NodeKind {
|
|||
Text(~str)
|
||||
}
|
||||
|
||||
struct DoctypeData {
|
||||
pub struct DoctypeData {
|
||||
name: ~str,
|
||||
public_id: Option<~str>,
|
||||
system_id: Option<~str>,
|
||||
force_quirks: bool
|
||||
}
|
||||
|
||||
fn DoctypeData(name: ~str, public_id: Option<~str>,
|
||||
pub fn DoctypeData(name: ~str, public_id: Option<~str>,
|
||||
system_id: Option<~str>, force_quirks: bool) -> DoctypeData {
|
||||
DoctypeData {
|
||||
name : move name,
|
||||
|
@ -110,7 +112,7 @@ fn DoctypeData(name: ~str, public_id: Option<~str>,
|
|||
|
||||
|
||||
|
||||
fn define_bindings(compartment: &bare_compartment, doc: @Document,
|
||||
pub fn define_bindings(compartment: &bare_compartment, doc: @Document,
|
||||
win: @Window) {
|
||||
bindings::window::init(compartment, win);
|
||||
bindings::document::init(compartment, doc);
|
||||
|
@ -129,11 +131,11 @@ enum LayoutData = {
|
|||
mut flow: Option<@FlowContext>
|
||||
};
|
||||
|
||||
type Node = cow::Handle<NodeData, LayoutData>;
|
||||
pub type Node = cow::Handle<NodeData, LayoutData>;
|
||||
|
||||
type NodeScope = cow::Scope<NodeData, LayoutData>;
|
||||
pub type NodeScope = cow::Scope<NodeData, LayoutData>;
|
||||
|
||||
fn NodeScope() -> NodeScope {
|
||||
pub fn NodeScope() -> NodeScope {
|
||||
cow::Scope()
|
||||
}
|
||||
|
||||
|
@ -148,8 +150,7 @@ impl NodeScope : NodeScopeExtensions {
|
|||
}
|
||||
}
|
||||
|
||||
#[allow(non_implicitly_copyable_typarams)]
|
||||
impl NodeScope : tree::ReadMethods<Node> {
|
||||
impl NodeScope {
|
||||
fn each_child(node: &Node, f: fn(&Node) -> bool) {
|
||||
tree::each_child(&self, node, f)
|
||||
}
|
||||
|
@ -157,18 +158,23 @@ impl NodeScope : tree::ReadMethods<Node> {
|
|||
fn get_parent(node: &Node) -> Option<Node> {
|
||||
tree::get_parent(&self, node)
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(non_implicitly_copyable_typarams)]
|
||||
impl NodeScope : tree::ReadMethods<Node> {
|
||||
fn with_tree_fields<R>(node: &Node, f: fn(&tree::Tree<Node>) -> R) -> R {
|
||||
self.read(node, |n| f(&n.tree))
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(non_implicitly_copyable_typarams)]
|
||||
impl NodeScope : tree::WriteMethods<Node> {
|
||||
impl NodeScope {
|
||||
fn add_child(node: Node, child: Node) {
|
||||
tree::add_child(&self, node, child)
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(non_implicitly_copyable_typarams)]
|
||||
impl NodeScope : tree::WriteMethods<Node> {
|
||||
pure fn eq(a: &Node, b: &Node) -> bool { a == b }
|
||||
|
||||
fn with_tree_fields<R>(node: &Node, f: fn(&tree::Tree<Node>) -> R) -> R {
|
||||
|
|
|
@ -3,13 +3,13 @@ use content::content_task::{ControlMsg, Timer, ExitMsg};
|
|||
use js::jsapi::JSVal;
|
||||
use dvec::DVec;
|
||||
|
||||
enum TimerControlMsg {
|
||||
pub enum TimerControlMsg {
|
||||
TimerMessage_Fire(~TimerData),
|
||||
TimerMessage_Close,
|
||||
TimerMessage_TriggerExit //XXXjdm this is just a quick hack to talk to the content task
|
||||
}
|
||||
|
||||
struct Window {
|
||||
pub struct Window {
|
||||
timer_chan: Chan<TimerControlMsg>,
|
||||
|
||||
drop {
|
||||
|
@ -63,7 +63,7 @@ impl Window {
|
|||
}
|
||||
}
|
||||
|
||||
fn Window(content_chan: pipes::SharedChan<ControlMsg>) -> Window {
|
||||
pub fn Window(content_chan: pipes::SharedChan<ControlMsg>) -> Window {
|
||||
|
||||
Window {
|
||||
timer_chan: do task::spawn_listener |timer_port: Port<TimerControlMsg>,
|
||||
|
|
|
@ -23,7 +23,7 @@ pub enum Msg {
|
|||
ExitMsg(Chan<()>)
|
||||
}
|
||||
|
||||
struct Engine<C:Compositor Send Copy> {
|
||||
pub struct Engine<C:Compositor Send Copy> {
|
||||
request_port: comm::Port<Msg>,
|
||||
compositor: C,
|
||||
render_task: RenderTask,
|
||||
|
@ -33,7 +33,7 @@ struct Engine<C:Compositor Send Copy> {
|
|||
content_task: ContentTask
|
||||
}
|
||||
|
||||
fn Engine<C:Compositor Send Copy>(compositor: C,
|
||||
pub fn Engine<C:Compositor Send Copy>(compositor: C,
|
||||
opts: &Opts,
|
||||
dom_event_port: pipes::Port<Event>,
|
||||
dom_event_chan: pipes::SharedChan<Event>,
|
||||
|
|
|
@ -12,7 +12,7 @@ use std::net::url::Url;
|
|||
use std::net::url;
|
||||
|
||||
/// Where a style sheet comes from.
|
||||
enum StylesheetProvenance {
|
||||
pub enum StylesheetProvenance {
|
||||
UrlProvenance(Url),
|
||||
InlineProvenance(Url, ~str),
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ use resource::resource_task::{Done, Load, Payload, ResourceTask};
|
|||
|
||||
use core::comm::{Chan, Port};
|
||||
use cssparse::{InlineProvenance, StylesheetProvenance, UrlProvenance, spawn_css_parser};
|
||||
use hubbub::hubbub;
|
||||
use hubbub::Attribute;
|
||||
use newcss::stylesheet::Stylesheet;
|
||||
use std::net::url::Url;
|
||||
|
@ -97,7 +98,7 @@ fn js_script_listener(to_parent : comm::Chan<~[~[u8]]>, from_parent : comm::Port
|
|||
break;
|
||||
}
|
||||
Done(Err(*)) => {
|
||||
#error("error loading script %s", url.to_str());
|
||||
error!("error loading script %s", url.to_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,11 +11,11 @@ use layout::display_list_builder::DisplayListBuilder;
|
|||
use layout::flow::{FlowContext, FlowTree, InlineBlockFlow, BlockFlow, RootFlow};
|
||||
use util::tree;
|
||||
|
||||
struct BlockFlowData {
|
||||
pub struct BlockFlowData {
|
||||
mut box: Option<@RenderBox>
|
||||
}
|
||||
|
||||
fn BlockFlowData() -> BlockFlowData {
|
||||
pub fn BlockFlowData() -> BlockFlowData {
|
||||
BlockFlowData {
|
||||
box: None
|
||||
}
|
||||
|
|
|
@ -71,7 +71,7 @@ padding, backgrounds. It is analogous to a CSS nonreplaced content box.
|
|||
|
||||
It also holds data specific to different box types, such as text.
|
||||
*/
|
||||
struct RenderBoxData {
|
||||
pub struct RenderBoxData {
|
||||
/* originating DOM node */
|
||||
node : Node,
|
||||
/* reference to containing flow context, which this box
|
||||
|
@ -105,32 +105,7 @@ pub enum SplitBoxResult {
|
|||
SplitDidNotFit(Option<@RenderBox>, Option<@RenderBox>)
|
||||
}
|
||||
|
||||
trait RenderBoxMethods {
|
||||
pure fn d(&self) -> &self/RenderBoxData;
|
||||
|
||||
pure fn is_replaced() -> bool;
|
||||
pure fn can_split() -> bool;
|
||||
pure fn is_whitespace_only() -> bool;
|
||||
// TODO(Issue #220): this should be a pure/const method
|
||||
fn can_merge_with_box(@self, other: @RenderBox) -> bool;
|
||||
pure fn content_box() -> Rect<Au>;
|
||||
pure fn border_box() -> Rect<Au>;
|
||||
pure fn margin_box() -> Rect<Au>;
|
||||
|
||||
fn split_to_width(@self, &LayoutContext, Au, starts_line: bool) -> SplitBoxResult;
|
||||
fn get_min_width(&LayoutContext) -> Au;
|
||||
fn get_pref_width(&LayoutContext) -> Au;
|
||||
fn get_used_width() -> (Au, Au);
|
||||
fn get_used_height() -> (Au, Au);
|
||||
|
||||
fn build_display_list(@self,
|
||||
builder: &DisplayListBuilder,
|
||||
dirty: &Rect<Au>,
|
||||
offset: &Point2D<Au>,
|
||||
dl: &mut DisplayList);
|
||||
}
|
||||
|
||||
fn RenderBoxData(node: Node, ctx: @FlowContext, id: int) -> RenderBoxData {
|
||||
pub fn RenderBoxData(node: Node, ctx: @FlowContext, id: int) -> RenderBoxData {
|
||||
RenderBoxData {
|
||||
node : node,
|
||||
mut ctx : ctx,
|
||||
|
@ -140,7 +115,7 @@ fn RenderBoxData(node: Node, ctx: @FlowContext, id: int) -> RenderBoxData {
|
|||
}
|
||||
}
|
||||
|
||||
impl RenderBox : RenderBoxMethods {
|
||||
impl RenderBox {
|
||||
pure fn d(&self) -> &self/RenderBoxData {
|
||||
match *self {
|
||||
GenericBox(ref d) => d,
|
||||
|
|
|
@ -22,7 +22,7 @@ pub struct LayoutTreeBuilder {
|
|||
mut next_cid: int
|
||||
}
|
||||
|
||||
impl LayoutTreeBuilder {
|
||||
pub impl LayoutTreeBuilder {
|
||||
static pure fn new() -> LayoutTreeBuilder {
|
||||
LayoutTreeBuilder {
|
||||
root_flow: None,
|
||||
|
|
|
@ -6,7 +6,7 @@ use std::net::url::Url;
|
|||
|
||||
/* Represents layout task context. */
|
||||
|
||||
struct LayoutContext {
|
||||
pub struct LayoutContext {
|
||||
font_ctx: @FontContext,
|
||||
image_cache: @LocalImageCache,
|
||||
doc_url: Url,
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
trait BoxedDebugMethods {
|
||||
pub trait BoxedDebugMethods {
|
||||
pure fn dump(@self);
|
||||
pure fn dump_indent(@self, ident: uint);
|
||||
pure fn debug_str(@self) -> ~str;
|
||||
}
|
||||
|
||||
trait DebugMethods {
|
||||
pub trait DebugMethods {
|
||||
pure fn dump(&self);
|
||||
pure fn dump_indent(&self, ident: uint);
|
||||
pure fn debug_str(&self) -> ~str;
|
||||
|
|
|
@ -43,7 +43,7 @@ Currently, the important types of flows are:
|
|||
|
||||
/* The type of the formatting context, and data specific to each
|
||||
context, such as linebox structures or float lists */
|
||||
enum FlowContext {
|
||||
pub enum FlowContext {
|
||||
AbsoluteFlow(FlowData),
|
||||
BlockFlow(FlowData, BlockFlowData),
|
||||
FloatFlow(FlowData),
|
||||
|
@ -63,20 +63,6 @@ enum FlowContextType {
|
|||
Flow_Table
|
||||
}
|
||||
|
||||
trait FlowContextMethods {
|
||||
pure fn d(&self) -> &self/FlowData;
|
||||
pure fn inline(&self) -> &self/InlineFlowData;
|
||||
pure fn block(&self) -> &self/BlockFlowData;
|
||||
pure fn root(&self) -> &self/RootFlowData;
|
||||
fn bubble_widths(@self, &LayoutContext);
|
||||
fn assign_widths(@self, &LayoutContext);
|
||||
fn assign_height(@self, &LayoutContext);
|
||||
fn build_display_list_recurse(@self, &DisplayListBuilder, dirty: &Rect<Au>,
|
||||
offset: &Point2D<Au>, &mut DisplayList);
|
||||
pure fn foldl_boxes_for_node<B: Copy>(Node, +seed: B, cb: pure fn&(+a: B,@RenderBox) -> B) -> B;
|
||||
pure fn iter_boxes_for_node<T>(Node, cb: pure fn&(@RenderBox) -> T);
|
||||
}
|
||||
|
||||
/* A particular kind of layout context. It manages the positioning of
|
||||
render boxes within the context. */
|
||||
struct FlowData {
|
||||
|
@ -106,7 +92,7 @@ fn FlowData(id: int) -> FlowData {
|
|||
}
|
||||
}
|
||||
|
||||
impl FlowContext : FlowContextMethods {
|
||||
impl FlowContext {
|
||||
pure fn d(&self) -> &self/FlowData {
|
||||
match *self {
|
||||
AbsoluteFlow(ref d) => d,
|
||||
|
@ -216,22 +202,27 @@ impl FlowContext : FlowContextMethods {
|
|||
}
|
||||
|
||||
/* The tree holding FlowContexts */
|
||||
enum FlowTree { FlowTree }
|
||||
pub enum FlowTree { FlowTree }
|
||||
|
||||
impl FlowTree : tree::ReadMethods<@FlowContext> {
|
||||
impl FlowTree {
|
||||
fn each_child(ctx: @FlowContext, f: fn(box: @FlowContext) -> bool) {
|
||||
tree::each_child(&self, &ctx, |box| f(*box) )
|
||||
}
|
||||
}
|
||||
|
||||
impl FlowTree : tree::ReadMethods<@FlowContext> {
|
||||
fn with_tree_fields<R>(box: &@FlowContext, f: fn(&tree::Tree<@FlowContext>) -> R) -> R {
|
||||
f(&box.d().tree)
|
||||
}
|
||||
}
|
||||
|
||||
impl FlowTree : tree::WriteMethods<@FlowContext> {
|
||||
impl FlowTree {
|
||||
fn add_child(parent: @FlowContext, child: @FlowContext) {
|
||||
tree::add_child(&self, parent, child)
|
||||
}
|
||||
}
|
||||
|
||||
impl FlowTree : tree::WriteMethods<@FlowContext> {
|
||||
|
||||
pure fn eq(a: &@FlowContext, b: &@FlowContext) -> bool { core::box::ptr_eq(*a, *b) }
|
||||
|
||||
|
|
|
@ -39,12 +39,12 @@ serve as the starting point, but the current design doesn't make it
|
|||
hard to try out that alternative.
|
||||
*/
|
||||
|
||||
struct NodeRange {
|
||||
pub struct NodeRange {
|
||||
node: Node,
|
||||
range: Range,
|
||||
}
|
||||
|
||||
impl NodeRange {
|
||||
pub impl NodeRange {
|
||||
static pure fn new(node: Node, range: &const Range) -> NodeRange {
|
||||
NodeRange { node: node, range: copy *range }
|
||||
}
|
||||
|
@ -557,7 +557,7 @@ impl LineboxScanner {
|
|||
}
|
||||
}
|
||||
|
||||
struct InlineFlowData {
|
||||
pub struct InlineFlowData {
|
||||
// A vec of all inline render boxes. Several boxes may
|
||||
// correspond to one Node/Element.
|
||||
boxes: DVec<@RenderBox>,
|
||||
|
@ -570,7 +570,7 @@ struct InlineFlowData {
|
|||
elems: ElementMapping
|
||||
}
|
||||
|
||||
fn InlineFlowData() -> InlineFlowData {
|
||||
pub fn InlineFlowData() -> InlineFlowData {
|
||||
InlineFlowData {
|
||||
boxes: DVec(),
|
||||
lines: DVec(),
|
||||
|
|
|
@ -75,7 +75,7 @@ impl Damage {
|
|||
}
|
||||
}
|
||||
|
||||
struct BuildData {
|
||||
pub struct BuildData {
|
||||
node: Node,
|
||||
url: Url,
|
||||
dom_event_chan: pipes::SharedChan<Event>,
|
||||
|
@ -84,7 +84,7 @@ struct BuildData {
|
|||
damage: Damage,
|
||||
}
|
||||
|
||||
fn LayoutTask(render_task: RenderTask,
|
||||
pub fn LayoutTask(render_task: RenderTask,
|
||||
img_cache_task: ImageCacheTask,
|
||||
opts: Opts) -> LayoutTask {
|
||||
do spawn_listener::<Msg> |from_content, move img_cache_task, move opts| {
|
||||
|
|
|
@ -10,11 +10,11 @@ use layout::flow::{FlowContext, FlowTree, InlineBlockFlow, BlockFlow, RootFlow};
|
|||
use layout::display_list_builder::DisplayListBuilder;
|
||||
use util::tree;
|
||||
|
||||
struct RootFlowData {
|
||||
pub struct RootFlowData {
|
||||
mut box: Option<@RenderBox>
|
||||
}
|
||||
|
||||
fn RootFlowData() -> RootFlowData {
|
||||
pub fn RootFlowData() -> RootFlowData {
|
||||
RootFlowData {
|
||||
box: None
|
||||
}
|
||||
|
|
|
@ -14,9 +14,10 @@ use geom::size::Size2D;
|
|||
use gfx::compositor::{Compositor, LayerBuffer, LayerBufferSet};
|
||||
use gfx::opts::Opts;
|
||||
use gfx::util::time;
|
||||
use layers::ImageLayer;
|
||||
use layers::layers::ImageLayer;
|
||||
use std::cell::Cell;
|
||||
use std::cmp::FuzzyEq;
|
||||
use glut::glut;
|
||||
|
||||
pub struct OSMain {
|
||||
chan: comm::Chan<Msg>
|
||||
|
@ -40,12 +41,12 @@ pub enum Msg {
|
|||
Exit
|
||||
}
|
||||
|
||||
fn OSMain(dom_event_chan: pipes::SharedChan<Event>, opts: Opts) -> OSMain {
|
||||
pub fn OSMain(dom_event_chan: pipes::SharedChan<Event>, opts: Opts) -> OSMain {
|
||||
let dom_event_chan = Cell(move dom_event_chan);
|
||||
OSMain {
|
||||
chan: do on_osmain::<Msg> |po, move dom_event_chan, move opts| {
|
||||
do platform::runmain {
|
||||
#debug("preparing to enter main loop");
|
||||
debug!("preparing to enter main loop");
|
||||
|
||||
// FIXME: Use the servo options.
|
||||
let mode;
|
||||
|
@ -139,7 +140,7 @@ fn mainloop(mode: Mode,
|
|||
AddKeyHandler(move key_ch) => key_handlers.push(move key_ch),
|
||||
BeginDrawing(move sender) => lend_surface(surfaces, move sender),
|
||||
Draw(move sender, move draw_target) => {
|
||||
#debug("osmain: received new frame");
|
||||
debug!("osmain: received new frame");
|
||||
return_surface(surfaces, move draw_target);
|
||||
lend_surface(surfaces, move sender);
|
||||
|
||||
|
@ -226,7 +227,7 @@ fn mainloop(mode: Mode,
|
|||
match window {
|
||||
GlutWindow(window) => {
|
||||
do glut::reshape_func(window) |width, height| {
|
||||
#debug("osmain: window resized to %d,%d", width as int, height as int);
|
||||
debug!("osmain: window resized to %d,%d", width as int, height as int);
|
||||
check_for_messages();
|
||||
resize_rate_limiter.window_resized(width as uint, height as uint);
|
||||
//composite();
|
||||
|
@ -286,7 +287,7 @@ fn lend_surface(surfaces: &SurfaceSet, receiver: pipes::Chan<LayerBufferSet>) {
|
|||
rect: copy layer_buffer.rect,
|
||||
stride: layer_buffer.stride
|
||||
};
|
||||
#debug("osmain: lending surface %?", layer_buffer);
|
||||
debug!("osmain: lending surface %?", layer_buffer);
|
||||
move layer_buffer
|
||||
};
|
||||
surfaces.front.layer_buffer_set.buffers = move old_layer_buffers;
|
||||
|
|
|
@ -23,67 +23,215 @@ extern mod stb_image;
|
|||
extern mod std;
|
||||
|
||||
pub mod content {
|
||||
#[path = "content/content_task.rs"]
|
||||
pub mod content_task;
|
||||
}
|
||||
|
||||
pub mod css {
|
||||
#[path = "css/select_handler.rs"]
|
||||
priv mod select_handler;
|
||||
#[path = "css/node_util.rs"]
|
||||
priv mod node_util;
|
||||
#[path = "css/node_void_ptr.rs"]
|
||||
priv mod node_void_ptr;
|
||||
|
||||
#[path = "css/select.rs"]
|
||||
pub mod select;
|
||||
#[path = "css/matching.rs"]
|
||||
pub mod matching;
|
||||
#[path = "css/node_style.rs"]
|
||||
pub mod node_style;
|
||||
}
|
||||
|
||||
pub mod dom {
|
||||
pub mod bindings {
|
||||
#[path = "dom/bindings/document.rs"]
|
||||
pub mod document;
|
||||
#[path = "dom/bindings/element.rs"]
|
||||
pub mod element;
|
||||
#[path = "dom/bindings/node.rs"]
|
||||
pub mod node;
|
||||
#[path = "dom/bindings/utils.rs"]
|
||||
pub mod utils;
|
||||
#[path = "dom/bindings/window.rs"]
|
||||
pub mod window;
|
||||
}
|
||||
#[path = "dom/cow.rs"]
|
||||
pub mod cow;
|
||||
#[path = "dom/document.rs"]
|
||||
pub mod document;
|
||||
#[path = "dom/element.rs"]
|
||||
pub mod element;
|
||||
#[path = "dom/event.rs"]
|
||||
pub mod event;
|
||||
#[path = "dom/node.rs"]
|
||||
pub mod node;
|
||||
#[path = "dom/window.rs"]
|
||||
pub mod window;
|
||||
}
|
||||
|
||||
pub mod engine;
|
||||
|
||||
pub mod layout {
|
||||
#[path = "layout/block.rs"]
|
||||
pub mod block;
|
||||
#[path = "layout/box.rs"]
|
||||
pub mod box;
|
||||
#[path = "layout/box_builder.rs"]
|
||||
pub mod box_builder;
|
||||
#[path = "layout/context.rs"]
|
||||
pub mod context;
|
||||
#[path = "layout/debug.rs"]
|
||||
pub mod debug;
|
||||
#[path = "layout/display_list_builder.rs"]
|
||||
pub mod display_list_builder;
|
||||
#[path = "layout/flow.rs"]
|
||||
pub mod flow;
|
||||
#[path = "layout/layout_task.rs"]
|
||||
pub mod layout_task;
|
||||
#[path = "layout/inline.rs"]
|
||||
pub mod inline;
|
||||
#[path = "layout/root.rs"]
|
||||
pub mod root;
|
||||
#[path = "layout/text.rs"]
|
||||
pub mod text;
|
||||
#[path = "layout/traverse.rs"]
|
||||
pub mod traverse;
|
||||
#[path = "layout/aux.rs"]
|
||||
mod aux;
|
||||
}
|
||||
|
||||
pub mod html {
|
||||
#[path = "html/cssparse.rs"]
|
||||
pub mod cssparse;
|
||||
#[path = "html/hubbub_html_parser.rs"]
|
||||
pub mod hubbub_html_parser;
|
||||
}
|
||||
|
||||
pub mod platform {
|
||||
#[path = "platform/base.rs"]
|
||||
pub mod base;
|
||||
#[path = "platform/osmain.rs"]
|
||||
pub mod osmain;
|
||||
#[path = "platform/resize_rate_limiter.rs"]
|
||||
priv mod resize_rate_limiter;
|
||||
}
|
||||
|
||||
pub mod util {
|
||||
pub mod actor;
|
||||
pub mod tree;
|
||||
}
|
||||
#[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::comm::*; // FIXME: Bad!
|
||||
use core::option::swap_unwrap;
|
||||
use core::pipes::{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))
|
||||
}
|
||||
|
||||
#[allow(non_implicitly_copyable_typarams)]
|
||||
fn run(opts: &Opts) {
|
||||
match opts.render_mode {
|
||||
Screen => run_pipeline_screen(opts),
|
||||
Png(outfile) => {
|
||||
assert opts.urls.is_not_empty();
|
||||
if opts.urls.len() > 1u {
|
||||
fail ~"servo asks that you stick to a single URL in PNG output mode"
|
||||
}
|
||||
run_pipeline_png(opts, outfile)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn run_pipeline_screen(opts: &Opts) {
|
||||
let (dom_event_chan, dom_event_port) = pipes::stream();
|
||||
let dom_event_chan = pipes::SharedChan(move dom_event_chan);
|
||||
|
||||
// The platform event handler thread
|
||||
let osmain = OSMain(dom_event_chan.clone(), copy *opts);
|
||||
|
||||
// Send each file to render then wait for keypress
|
||||
let (keypress_to_engine, keypress_from_osmain) = pipes::stream();
|
||||
osmain.chan.send(AddKeyHandler(move keypress_to_engine));
|
||||
|
||||
// Create a servo instance
|
||||
let resource_task = ResourceTask();
|
||||
let image_cache_task = ImageCacheTask(copy resource_task);
|
||||
let engine_task = Engine(osmain, opts, move dom_event_port, move dom_event_chan,
|
||||
move resource_task, move image_cache_task);
|
||||
|
||||
for opts.urls.each |filename| {
|
||||
let url = make_url(copy *filename, None);
|
||||
debug!("master: Sending url `%s`", url.to_str());
|
||||
engine_task.send(LoadURLMsg(move url));
|
||||
debug!("master: Waiting for keypress");
|
||||
|
||||
match keypress_from_osmain.try_recv() {
|
||||
Some(*) => { }
|
||||
None => { error!("keypress stream closed unexpectedly") }
|
||||
};
|
||||
}
|
||||
|
||||
// Shut everything down
|
||||
debug!("master: Shut down");
|
||||
let (exit_chan, exit_response_from_engine) = pipes::stream();
|
||||
engine_task.send(engine::ExitMsg(move exit_chan));
|
||||
exit_response_from_engine.recv();
|
||||
|
||||
osmain.chan.send(platform::osmain::Exit);
|
||||
}
|
||||
|
||||
fn run_pipeline_png(_opts: &Opts, _outfile: &str) {
|
||||
fail ~"PNG compositor is broken";
|
||||
}
|
||||
|
||||
#[cfg(broken)]
|
||||
fn run_pipeline_png(url: ~str, outfile: &str) {
|
||||
// Use a PNG encoder as the graphics compositor
|
||||
use gfx::png_compositor;
|
||||
use png_compositor::PngCompositor;
|
||||
use io::{Writer, buffered_file_writer};
|
||||
use resource::resource_task::ResourceTask;
|
||||
use resource::image_cache_task::SyncImageCacheTask;
|
||||
|
||||
listen(|pngdata_from_compositor| {
|
||||
let (dom_event_chan, dom_event_port) = pipes::stream();
|
||||
let dom_event_chan = pipes::SharedChan(move dom_event_chan);
|
||||
|
||||
let compositor = PngCompositor(pngdata_from_compositor);
|
||||
let resource_task = ResourceTask();
|
||||
// For the PNG pipeline we are using a synchronous image task so that all images will be
|
||||
// fulfilled before the first paint.
|
||||
let image_cache_task = SyncImageCacheTask(resource_task);
|
||||
let engine_task = Engine(copy compositor, move dom_event_port, move dom_event_chan,
|
||||
move resource_task, move image_cache_task);
|
||||
engine_task.send(LoadURLMsg(make_url(copy url, None)));
|
||||
|
||||
match buffered_file_writer(&Path(outfile)) {
|
||||
Ok(writer) => writer.write(pngdata_from_compositor.recv()),
|
||||
Err(e) => fail e
|
||||
}
|
||||
|
||||
let (exit_chan, exit_response_from_engine) = pipes::stream();
|
||||
engine_task.send(engine::ExitMsg(move exit_chan));
|
||||
exit_response_from_engine.recv();
|
||||
compositor.send(png_compositor::Exit);
|
||||
})
|
||||
}
|
||||
|
|
|
@ -1,113 +0,0 @@
|
|||
#[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::comm::*; // FIXME: Bad!
|
||||
use core::option::swap_unwrap;
|
||||
use core::pipes::{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))
|
||||
}
|
||||
|
||||
#[allow(non_implicitly_copyable_typarams)]
|
||||
fn run(opts: &Opts) {
|
||||
match opts.render_mode {
|
||||
Screen => run_pipeline_screen(opts),
|
||||
Png(outfile) => {
|
||||
assert opts.urls.is_not_empty();
|
||||
if opts.urls.len() > 1u {
|
||||
fail ~"servo asks that you stick to a single URL in PNG output mode"
|
||||
}
|
||||
run_pipeline_png(opts, outfile)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn run_pipeline_screen(opts: &Opts) {
|
||||
let (dom_event_chan, dom_event_port) = pipes::stream();
|
||||
let dom_event_chan = pipes::SharedChan(move dom_event_chan);
|
||||
|
||||
// The platform event handler thread
|
||||
let osmain = OSMain(dom_event_chan.clone(), copy *opts);
|
||||
|
||||
// Send each file to render then wait for keypress
|
||||
let (keypress_to_engine, keypress_from_osmain) = pipes::stream();
|
||||
osmain.chan.send(AddKeyHandler(move keypress_to_engine));
|
||||
|
||||
// Create a servo instance
|
||||
let resource_task = ResourceTask();
|
||||
let image_cache_task = ImageCacheTask(copy resource_task);
|
||||
let engine_task = Engine(osmain, opts, move dom_event_port, move dom_event_chan,
|
||||
move resource_task, move image_cache_task);
|
||||
|
||||
for opts.urls.each |filename| {
|
||||
let url = make_url(copy *filename, None);
|
||||
#debug["master: Sending url `%s`", url.to_str()];
|
||||
engine_task.send(LoadURLMsg(move url));
|
||||
#debug["master: Waiting for keypress"];
|
||||
|
||||
match keypress_from_osmain.try_recv() {
|
||||
Some(*) => { }
|
||||
None => { #error("keypress stream closed unexpectedly") }
|
||||
};
|
||||
}
|
||||
|
||||
// Shut everything down
|
||||
#debug["master: Shut down"];
|
||||
let (exit_chan, exit_response_from_engine) = pipes::stream();
|
||||
engine_task.send(engine::ExitMsg(move exit_chan));
|
||||
exit_response_from_engine.recv();
|
||||
|
||||
osmain.chan.send(platform::osmain::Exit);
|
||||
}
|
||||
|
||||
fn run_pipeline_png(_opts: &Opts, _outfile: &str) {
|
||||
fail ~"PNG compositor is broken";
|
||||
}
|
||||
|
||||
#[cfg(broken)]
|
||||
fn run_pipeline_png(url: ~str, outfile: &str) {
|
||||
// Use a PNG encoder as the graphics compositor
|
||||
use gfx::png_compositor;
|
||||
use png_compositor::PngCompositor;
|
||||
use io::{Writer, buffered_file_writer};
|
||||
use resource::resource_task::ResourceTask;
|
||||
use resource::image_cache_task::SyncImageCacheTask;
|
||||
|
||||
listen(|pngdata_from_compositor| {
|
||||
let (dom_event_chan, dom_event_port) = pipes::stream();
|
||||
let dom_event_chan = pipes::SharedChan(move dom_event_chan);
|
||||
|
||||
let compositor = PngCompositor(pngdata_from_compositor);
|
||||
let resource_task = ResourceTask();
|
||||
// For the PNG pipeline we are using a synchronous image task so that all images will be
|
||||
// fulfilled before the first paint.
|
||||
let image_cache_task = SyncImageCacheTask(resource_task);
|
||||
let engine_task = Engine(copy compositor, move dom_event_port, move dom_event_chan,
|
||||
move resource_task, move image_cache_task);
|
||||
engine_task.send(LoadURLMsg(make_url(copy url, None)));
|
||||
|
||||
match buffered_file_writer(&Path(outfile)) {
|
||||
Ok(writer) => writer.write(pngdata_from_compositor.recv()),
|
||||
Err(e) => fail e
|
||||
}
|
||||
|
||||
let (exit_chan, exit_response_from_engine) = pipes::stream();
|
||||
engine_task.send(engine::ExitMsg(move exit_chan));
|
||||
exit_response_from_engine.recv();
|
||||
compositor.send(png_compositor::Exit);
|
||||
})
|
||||
}
|
|
@ -1,3 +1,5 @@
|
|||
pub use gfx::util::cache;
|
||||
pub use gfx::util::time;
|
||||
|
||||
pub mod actor;
|
||||
pub mod tree;
|
Loading…
Add table
Add a link
Reference in a new issue