mirror of
https://github.com/servo/servo.git
synced 2025-08-05 21:50:18 +01:00
Refactor DisplayList/DisplayItem to be a struct with a closure, and
add draw methods to DisplayList/DisplayItem
This commit is contained in:
parent
6436862007
commit
458eae9236
3 changed files with 106 additions and 58 deletions
|
@ -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
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue