Refactor DisplayList/DisplayItem to be a struct with a closure, and

add draw methods to DisplayList/DisplayItem
This commit is contained in:
Brian J. Burg 2012-09-11 14:09:38 -07:00
parent 6436862007
commit 458eae9236
3 changed files with 106 additions and 58 deletions

View file

@ -23,7 +23,7 @@ use pipes::{Port, Chan};
type Renderer = comm::Chan<Msg>;
enum Msg {
pub enum Msg {
RenderMsg(dl::DisplayList),
ExitMsg(pipes::Chan<()>)
}
@ -56,7 +56,7 @@ fn RenderTask<C: Compositor Send>(+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<AzFloat>;
}
@ -106,16 +93,16 @@ impl Rect<au> : 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<au>, 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<au>, 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<au>, 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

View file

@ -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<au>
draw: ~fn((&DisplayItem), (&DrawTarget)),
bounds : Rect<au>, // 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<DisplayItem>;
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<au>, 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<au>, 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<au>, 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);
}
}
}

View file

@ -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<au>) {
// 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<au> = 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<au>) {
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<au>) {
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));
}
}