dom, gfx, layout, submodules: Implement "color"

This commit is contained in:
Patrick Walton 2012-11-10 23:44:18 -08:00
parent 7917da2f8c
commit 64fb0fbe60
5 changed files with 62 additions and 30 deletions

@ -1 +1 @@
Subproject commit 4c76cb47736c71cc3fcdaf67531bfef5024ac4c3 Subproject commit 7f9bd3c32baae72bec864085e81df7773542f790

View file

@ -29,6 +29,10 @@ impl NodeTree : tree::ReadMethods<Node> {
tree::each_child(&self, node, f) tree::each_child(&self, node, f)
} }
fn get_parent(node: &Node) -> Option<Node> {
tree::get_parent(&self, node)
}
fn with_tree_fields<R>(n: &Node, f: fn(&tree::Tree<Node>) -> R) -> R { fn with_tree_fields<R>(n: &Node, f: fn(&tree::Tree<Node>) -> R) -> R {
n.read(|n| f(&n.tree)) n.read(|n| f(&n.tree))
} }

View file

@ -31,7 +31,7 @@ pub enum DisplayItem {
// TODO: need to provide spacing data for text run. // TODO: need to provide spacing data for text run.
// (i.e, to support rendering of CSS 'word-spacing' and 'letter-spacing') // (i.e, to support rendering of CSS 'word-spacing' and 'letter-spacing')
// TODO: don't copy text runs, ever. // TODO: don't copy text runs, ever.
Text(DisplayItemData, ~SendableTextRun, Range), Text(DisplayItemData, ~SendableTextRun, Range, Color),
Image(DisplayItemData, ARC<~image::base::Image>), Image(DisplayItemData, ARC<~image::base::Image>),
Border(DisplayItemData, Au, Color) Border(DisplayItemData, Au, Color)
} }
@ -40,7 +40,7 @@ impl DisplayItem {
pure fn d(&self) -> &self/DisplayItemData { pure fn d(&self) -> &self/DisplayItemData {
match *self { match *self {
SolidColor(ref d, _) => d, SolidColor(ref d, _) => d,
Text(ref d, _, _) => d, Text(ref d, _, _, _) => d,
Image(ref d, _) => d, Image(ref d, _) => d,
Border(ref d, _, _) => d Border(ref d, _, _) => d
} }
@ -49,12 +49,12 @@ impl DisplayItem {
fn draw_into_context(&self, ctx: &RenderContext) { fn draw_into_context(&self, ctx: &RenderContext) {
match *self { match *self {
SolidColor(_, color) => ctx.draw_solid_color(&self.d().bounds, color), SolidColor(_, color) => ctx.draw_solid_color(&self.d().bounds, color),
Text(_, run, range) => { Text(_, run, range, color) => {
let new_run = @run.deserialize(ctx.font_ctx); let new_run = @run.deserialize(ctx.font_ctx);
let font = new_run.font; let font = new_run.font;
let origin = self.d().bounds.origin; let origin = self.d().bounds.origin;
let baseline_origin = Point2D(origin.x, origin.y + font.metrics.ascent); let baseline_origin = Point2D(origin.x, origin.y + font.metrics.ascent);
font.draw_text_into_context(ctx, new_run, range, baseline_origin); font.draw_text_into_context(ctx, new_run, range, baseline_origin, color);
}, },
Image(_, ref img) => ctx.draw_image(self.d().bounds, clone_arc(img)), Image(_, ref img) => ctx.draw_image(self.d().bounds, clone_arc(img)),
Border(_, width, color) => ctx.draw_border(&self.d().bounds, width, color), Border(_, width, color) => ctx.draw_border(&self.d().bounds, width, color),
@ -73,8 +73,11 @@ impl DisplayItem {
Border(DisplayItemData::new(bounds), width, color) Border(DisplayItemData::new(bounds), width, color)
} }
static pure fn new_Text(bounds: &Rect<Au>, run: ~SendableTextRun, range: Range) -> DisplayItem { static pure fn new_Text(bounds: &Rect<Au>,
Text(DisplayItemData::new(bounds), move run, range) run: ~SendableTextRun,
range: Range,
color: Color) -> DisplayItem {
Text(DisplayItemData::new(bounds), move run, range, color)
} }
// ARC should be cloned into ImageData, but Images are not sendable // ARC should be cloned into ImageData, but Images are not sendable

View file

@ -1,8 +1,4 @@
use azure::{ use color::Color;
AzFloat,
AzScaledFontRef,
};
use gfx::au; use gfx::au;
use gfx::{Au, RenderContext}; use gfx::{Au, RenderContext};
use geom::{Point2D, Rect, Size2D}; use geom::{Point2D, Rect, Size2D};
@ -13,7 +9,8 @@ use text::{
TextRun, TextRun,
}; };
use azure::azure_hl::BackendType; use azure::{AzFloat, AzScaledFontRef};
use azure::azure_hl::{BackendType, ColorPattern};
use core::dvec::DVec; use core::dvec::DVec;
// FontHandle encapsulates access to the platform's font API, // FontHandle encapsulates access to the platform's font API,
@ -300,7 +297,11 @@ impl Font {
// Public API // Public API
pub trait FontMethods { pub trait FontMethods {
fn draw_text_into_context(rctx: &RenderContext, run: &TextRun, range: Range, baseline_origin: Point2D<Au>); fn draw_text_into_context(rctx: &RenderContext,
run: &TextRun,
range: Range,
baseline_origin: Point2D<Au>,
color: Color);
fn measure_text(&TextRun, Range) -> RunMetrics; fn measure_text(&TextRun, Range) -> RunMetrics;
fn shape_text(@self, &str) -> GlyphStore; fn shape_text(@self, &str) -> GlyphStore;
fn get_descriptor() -> FontDescriptor; fn get_descriptor() -> FontDescriptor;
@ -313,7 +314,11 @@ pub trait FontMethods {
} }
pub impl Font : FontMethods { pub impl Font : FontMethods {
fn draw_text_into_context(rctx: &RenderContext, run: &TextRun, range: Range, baseline_origin: Point2D<Au>) { fn draw_text_into_context(rctx: &RenderContext,
run: &TextRun,
range: Range,
baseline_origin: Point2D<Au>,
color: Color) {
use libc::types::common::c99::{uint16_t, uint32_t}; use libc::types::common::c99::{uint16_t, uint32_t};
use azure::{AzDrawOptions, use azure::{AzDrawOptions,
AzGlyph, AzGlyph,
@ -324,14 +329,9 @@ pub impl Font : FontMethods {
let target = rctx.get_draw_target(); let target = rctx.get_draw_target();
let azfont = self.get_azure_font(); let azfont = self.get_azure_font();
let color = { let pattern = ColorPattern(color);
r: 0f as AzFloat, let azure_pattern = pattern.azure_color_pattern;
g: 0f as AzFloat, assert azure_pattern.is_not_null();
b: 0f as AzFloat,
a: 1f as AzFloat
};
let pattern = AzCreateColorPattern(ptr::to_unsafe_ptr(&color));
assert pattern.is_not_null();
let options: AzDrawOptions = { let options: AzDrawOptions = {
mAlpha: 1f as AzFloat, mAlpha: 1f as AzFloat,
@ -365,10 +365,12 @@ pub impl Font : FontMethods {
}}; }};
// TODO: this call needs to move into azure_hl.rs // TODO: this call needs to move into azure_hl.rs
AzDrawTargetFillGlyphs(target.azure_draw_target, azfont, AzDrawTargetFillGlyphs(target.azure_draw_target,
ptr::to_unsafe_ptr(&glyphbuf), pattern, ptr::to_unsafe_ptr(&options), ptr::null()); azfont,
ptr::to_unsafe_ptr(&glyphbuf),
AzReleaseColorPattern(pattern); azure_pattern,
ptr::to_unsafe_ptr(&options),
ptr::null());
} }
fn measure_text(run: &TextRun, range: Range) -> RunMetrics { fn measure_text(run: &TextRun, range: Range) -> RunMetrics {

View file

@ -25,6 +25,7 @@ use newcss::values::{CSSDisplay, Specified, CSSBackgroundColorColor, CSSBackgrou
use servo_text::TextRun; use servo_text::TextRun;
use util::range::*; use util::range::*;
use util::tree; use util::tree;
use util::tree::ReadMethods;
use arc = std::arc; use arc = std::arc;
use arc::ARC; use arc::ARC;
@ -411,10 +412,16 @@ impl RenderBox : RenderBoxMethods {
match *self { match *self {
UnscannedTextBox(*) => fail ~"Shouldn't see unscanned boxes here.", UnscannedTextBox(*) => fail ~"Shouldn't see unscanned boxes here.",
TextBox(_,d) => { TextBox(_,d) => {
list.append_item(~DisplayItem::new_Text(&abs_box_bounds, ~d.run.serialize(), d.range)); let nearest_element = self.nearest_element();
let color = nearest_element.style().color().to_gfx_color();
list.append_item(~DisplayItem::new_Text(&abs_box_bounds,
~d.run.serialize(),
d.range,
color));
// debug frames for text box bounds // debug frames for text box bounds
debug!("%?", { debug!("%?", {
list.append_item(~DisplayItem::new_Border(&abs_box_bounds, au::from_px(1), list.append_item(~DisplayItem::new_Border(&abs_box_bounds,
au::from_px(1),
rgb(0, 0, 200).to_gfx_color())) rgb(0, 0, 200).to_gfx_color()))
; ()}); ; ()});
}, },
@ -423,7 +430,8 @@ impl RenderBox : RenderBoxMethods {
}, },
ImageBox(_,i) => { ImageBox(_,i) => {
match i.get_image() { match i.get_image() {
Some(image) => list.append_item(~DisplayItem::new_Image(&abs_box_bounds, arc::clone(&image))), Some(image) => list.append_item(~DisplayItem::new_Image(&abs_box_bounds,
arc::clone(&image))),
/* No image data at all? Okay, add some fallback content instead. */ /* No image data at all? Okay, add some fallback content instead. */
None => () None => ()
} }
@ -525,6 +533,21 @@ impl RenderBox : BoxedDebugMethods {
} }
} }
// Other methods
impl RenderBox {
/// Returns the nearest ancestor-or-self node. Infallible.
fn nearest_element(@self) -> Node {
let mut node = self.d().node;
while !node.is_element() {
match NodeTree.get_parent(&node) {
None => fail ~"no nearest element?!",
Some(move parent) => node = move parent,
}
}
node
}
}
// FIXME: This belongs somewhere else // FIXME: This belongs somewhere else
trait ToGfxColor { trait ToGfxColor {
fn to_gfx_color(&self) -> gfx::color::Color; fn to_gfx_color(&self) -> gfx::color::Color;