diff --git a/src/servo/gfx/render_task.rs b/src/servo/gfx/render_task.rs index fc109f75433..75263388fb6 100644 --- a/src/servo/gfx/render_task.rs +++ b/src/servo/gfx/render_task.rs @@ -23,7 +23,7 @@ use pipes::{Port, Chan}; type Renderer = comm::Chan; -enum Msg { +pub enum Msg { RenderMsg(dl::DisplayList), ExitMsg(pipes::Chan<()>) } @@ -56,7 +56,7 @@ fn RenderTask(+compositor: C) -> RenderTask { do draw_target.with_ref |draw_target| { clear(draw_target); - draw_display_list(draw_target, display_list); + display_list.draw(draw_target) } #debug("renderer: returning surface"); @@ -82,19 +82,6 @@ impl u8 : to_float { } } -fn draw_display_list(draw_target: &DrawTarget, display_list: dl::DisplayList) { - for display_list.each |item| { - #debug["drawing %?", item]; - - match item.item { - dl::SolidColor(r, g, b) => draw_solid_color(draw_target, item, r, g, b), - dl::Image(image) => draw_image(draw_target, item, image), - dl::Text(text_run) => draw_text(draw_target, item, text_run), - dl::Padding(*) => fail ~"should never see padding" - } - } -} - trait ToAzureRect { fn to_azure_rect() -> Rect; } @@ -106,16 +93,16 @@ impl Rect : ToAzureRect { } } -fn draw_solid_color(draw_target: &DrawTarget, item: dl::DisplayItem, r: u8, g: u8, b: u8) { +pub fn draw_solid_color(draw_target: &DrawTarget, bounds: &Rect, r: u8, g: u8, b: u8) { let color = Color(r.to_float() as AzFloat, g.to_float() as AzFloat, b.to_float() as AzFloat, 1f as AzFloat); - draw_target.fill_rect(item.bounds.to_azure_rect(), ColorPattern(color)); + draw_target.fill_rect(bounds.to_azure_rect(), ColorPattern(color)); } -fn draw_image(draw_target: &DrawTarget, item: dl::DisplayItem, image: ARC<~Image>) unsafe { +pub fn draw_image(draw_target: &DrawTarget, bounds: Rect, image: ARC<~Image>) { let image = std::arc::get(&image); let size = Size2D(image.width as i32, image.height as i32); let stride = image.width * 4; @@ -124,14 +111,14 @@ fn draw_image(draw_target: &DrawTarget, item: dl::DisplayItem, image: ARC<~Image B8G8R8A8); let source_rect = Rect(Point2D(0 as AzFloat, 0 as AzFloat), Size2D(image.width as AzFloat, image.height as AzFloat)); - let dest_rect = item.bounds.to_azure_rect(); + let dest_rect = bounds.to_azure_rect(); let draw_surface_options = DrawSurfaceOptions(Linear, true); let draw_options = DrawOptions(1.0f as AzFloat, 0); draw_target.draw_surface(azure_surface, dest_rect, source_rect, draw_surface_options, draw_options); } -fn draw_text(draw_target: &DrawTarget, item: dl::DisplayItem, text_run: TextRun) { +pub fn draw_text(draw_target: &DrawTarget, bounds: Rect, text_run: &TextRun) { use ptr::{addr_of, null}; use vec::unsafe::to_ptr; use libc::types::common::c99::{uint16_t, uint32_t}; @@ -147,7 +134,6 @@ fn draw_text(draw_target: &DrawTarget, item: dl::DisplayItem, text_run: TextRun) let draw_target = draw_target.azure_draw_target; - let bounds = copy item.bounds; // FIXME: The font library should not be created here let flib = FontLibrary(); let font = flib.get_test_font(); @@ -230,11 +216,11 @@ fn get_cairo_font(font: &Font) -> *cairo_scaled_font_t { use azure::cairo; use cairo::cairo_matrix_t; use cairo::bindgen::{cairo_matrix_init_identity, - cairo_matrix_scale, - cairo_font_options_create, - cairo_scaled_font_create, - cairo_font_options_destroy, - cairo_font_face_destroy}; + cairo_matrix_scale, + cairo_font_options_create, + cairo_scaled_font_create, + cairo_font_options_destroy, + cairo_font_face_destroy}; // FIXME: error handling diff --git a/src/servo/layout/display_list.rs b/src/servo/layout/display_list.rs index 7f55632676f..c8c0dd485f6 100644 --- a/src/servo/layout/display_list.rs +++ b/src/servo/layout/display_list.rs @@ -1,25 +1,85 @@ +use azure::azure_hl::DrawTarget; +use gfx::render_task::{draw_solid_color, draw_image, draw_text}; use gfx::geometry::*; use geom::rect::Rect; use image::base::Image; use servo_text::text_run::TextRun; -use std::arc::ARC; +use std::arc::{ARC, clone}; use dvec::DVec; -// TODO: convert to DisplayItem trait with methods like bounds(), paint(), etc. -enum ItemKind { - SolidColor(u8, u8, u8), - Image(ARC<~Image>), - Text(TextRun), - // FIXME: Shape code does not understand the alignment without this - Padding(u8, u8, u8, u8) -} - struct DisplayItem { - item: ItemKind, - bounds: Rect + draw: ~fn((&DisplayItem), (&DrawTarget)), + bounds : Rect, // TODO: whose coordinate system should this use? + data : DisplayItemData } -impl DisplayItem : Copy { } +enum DisplayItemData { + SolidColorData(u8, u8, u8), + TextData(TextRun), + ImageData(ARC<~image::base::Image>), + PaddingData(u8, u8, u8, u8) // This is a hack to make fonts work (?) +} -type DisplayList = DVec; +fn draw_SolidColor(self: &DisplayItem, ctx: &DrawTarget) { + match self.data { + SolidColorData(r,g,b) => draw_solid_color(ctx, &self.bounds, r, g, b), + _ => fail + } +} + +fn draw_Text(self: &DisplayItem, ctx: &DrawTarget) { + match self.data { + TextData(run) => draw_text(ctx, self.bounds, &run), + _ => fail + } +} + +fn draw_Image(self: &DisplayItem, ctx: &DrawTarget) { + match self.data { + ImageData(img) => draw_image(ctx, self.bounds, img), + _ => fail + } +} + +fn SolidColor(bounds: Rect, r: u8, g: u8, b: u8) -> DisplayItem { + DisplayItem { + // TODO: this seems wrong. + draw: |self, ctx| draw_SolidColor(self, ctx), + bounds: bounds, + data: SolidColorData(r, g, b) + } +} + +fn Text(bounds: Rect, run: TextRun) -> DisplayItem { + DisplayItem { + draw: |self, ctx| draw_Text(self, ctx), + bounds: bounds, + data: TextData(run) + } +} + +// ARC should be cloned into ImageData, but Images are not sendable +fn Image(bounds: Rect, image: ARC<~image::base::Image>) -> DisplayItem { + DisplayItem { + // TODO: this seems wrong. + draw: |self, ctx| draw_Image(self, ctx), + bounds: bounds, + data: ImageData(clone(&image)) + } +} + +type DisplayList = DVec<~DisplayItem>; + +trait DisplayListMethods { + fn draw(ctx: &DrawTarget); +} + +impl DisplayList : DisplayListMethods { + fn draw(ctx: &DrawTarget) { + for self.each |item| { + #debug["drawing %?", item]; + item.draw(item, ctx); + } + } +} \ No newline at end of file diff --git a/src/servo/layout/display_list_builder.rs b/src/servo/layout/display_list_builder.rs index cb23b6850f9..1cd7450f51b 100644 --- a/src/servo/layout/display_list_builder.rs +++ b/src/servo/layout/display_list_builder.rs @@ -63,22 +63,31 @@ Creates a display list item for a single block. "] #[allow(non_implicitly_copyable_typarams)] fn box_to_display_items(list: dl::DisplayList, box: @Box, origin: Point2D) { + + // TODO: each box should know how to make its own display items. + // The display list builder should mainly hold information about + // the initial request and desired result---for example, is the + // DisplayList to be used for painting or hit testing. This can + // influence which boxes are created. + + // TODO: to implement stacking contexts correctly, we need to + // create a set of display lists, one per each layer of a stacking + // context. (CSS 2.1, Section 9.9.1). Each box is passed the list + // set representing the box's stacking context. When asked to + // construct its constituent display items, each box puts its + // DisplayItems into the correct stack layer (according to CSS 2.1 + // Appendix E). and then builder flattens the list at the end. + #debug("request to display a box from origin %?", origin); - let bounds = Rect(origin, copy box.bounds.size); + let bounds : Rect = Rect(origin, copy box.bounds.size); match box.kind { TextBoxKind(subbox) => { let run = copy subbox.run; assert run.is_some(); - list.push(dl::DisplayItem { - item: dl::SolidColor(255u8, 255u8, 255u8), - bounds: bounds - } ); - list.push(dl::DisplayItem { - item: dl::Text(run.get()), - bounds: bounds - }); + list.push(~dl::SolidColor(bounds, 255u8, 255u8, 255u8)); + list.push(~dl::Text(bounds, run.get())); return; } _ => { @@ -90,11 +99,7 @@ fn box_to_display_items(list: dl::DisplayList, box: @Box, origin: Point2D) { let image = box.appearance.get_image(); if image.is_some() { - let display_item = dl::DisplayItem { - item: dl::Image(option::unwrap(image)), - bounds: bounds - }; - list.push(display_item); + list.push(~dl::Image(bounds, option::unwrap(image))) } else { // DAC // TODO: shouldn't need to unbox CSSValue by now @@ -104,10 +109,7 @@ fn box_to_display_items(list: dl::DisplayList, box: @Box, origin: Point2D) { Specified(BgTransparent) | _ => util::color::rgba(0,0,0,0.0) }; #debug("Assigning color %? to box with bounds %?", color, bounds); - list.push(dl::DisplayItem { - item: dl::SolidColor(color.red, color.green, color.blue), - bounds: bounds - }); + list.push(~dl::SolidColor(bounds, color.red, color.green, color.blue)); } }