From 64fb0fbe60b0ed20be67f2a2a1ec7a9f4a0285ed Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Sat, 10 Nov 2012 23:44:18 -0800 Subject: [PATCH] dom, gfx, layout, submodules: Implement "color" --- src/rust-css | 2 +- src/servo/dom/node.rs | 4 ++++ src/servo/gfx/display_list.rs | 15 ++++++++----- src/servo/gfx/font.rs | 42 ++++++++++++++++++----------------- src/servo/layout/box.rs | 29 +++++++++++++++++++++--- 5 files changed, 62 insertions(+), 30 deletions(-) diff --git a/src/rust-css b/src/rust-css index 4c76cb47736..7f9bd3c32ba 160000 --- a/src/rust-css +++ b/src/rust-css @@ -1 +1 @@ -Subproject commit 4c76cb47736c71cc3fcdaf67531bfef5024ac4c3 +Subproject commit 7f9bd3c32baae72bec864085e81df7773542f790 diff --git a/src/servo/dom/node.rs b/src/servo/dom/node.rs index 802f564fdba..6f990397f14 100644 --- a/src/servo/dom/node.rs +++ b/src/servo/dom/node.rs @@ -29,6 +29,10 @@ impl NodeTree : tree::ReadMethods { tree::each_child(&self, node, f) } + fn get_parent(node: &Node) -> Option { + tree::get_parent(&self, node) + } + fn with_tree_fields(n: &Node, f: fn(&tree::Tree) -> R) -> R { n.read(|n| f(&n.tree)) } diff --git a/src/servo/gfx/display_list.rs b/src/servo/gfx/display_list.rs index e15da1a67f0..372d3f173fc 100644 --- a/src/servo/gfx/display_list.rs +++ b/src/servo/gfx/display_list.rs @@ -31,7 +31,7 @@ pub enum DisplayItem { // TODO: need to provide spacing data for text run. // (i.e, to support rendering of CSS 'word-spacing' and 'letter-spacing') // TODO: don't copy text runs, ever. - Text(DisplayItemData, ~SendableTextRun, Range), + Text(DisplayItemData, ~SendableTextRun, Range, Color), Image(DisplayItemData, ARC<~image::base::Image>), Border(DisplayItemData, Au, Color) } @@ -40,7 +40,7 @@ impl DisplayItem { pure fn d(&self) -> &self/DisplayItemData { match *self { SolidColor(ref d, _) => d, - Text(ref d, _, _) => d, + Text(ref d, _, _, _) => d, Image(ref d, _) => d, Border(ref d, _, _) => d } @@ -49,12 +49,12 @@ impl DisplayItem { fn draw_into_context(&self, ctx: &RenderContext) { match *self { 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 font = new_run.font; let origin = self.d().bounds.origin; 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)), Border(_, width, color) => ctx.draw_border(&self.d().bounds, width, color), @@ -73,8 +73,11 @@ impl DisplayItem { Border(DisplayItemData::new(bounds), width, color) } - static pure fn new_Text(bounds: &Rect, run: ~SendableTextRun, range: Range) -> DisplayItem { - Text(DisplayItemData::new(bounds), move run, range) + static pure fn new_Text(bounds: &Rect, + 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 diff --git a/src/servo/gfx/font.rs b/src/servo/gfx/font.rs index 664d6330832..b31d9d3c8b9 100644 --- a/src/servo/gfx/font.rs +++ b/src/servo/gfx/font.rs @@ -1,8 +1,4 @@ -use azure::{ - AzFloat, - AzScaledFontRef, -}; - +use color::Color; use gfx::au; use gfx::{Au, RenderContext}; use geom::{Point2D, Rect, Size2D}; @@ -13,7 +9,8 @@ use text::{ TextRun, }; -use azure::azure_hl::BackendType; +use azure::{AzFloat, AzScaledFontRef}; +use azure::azure_hl::{BackendType, ColorPattern}; use core::dvec::DVec; // FontHandle encapsulates access to the platform's font API, @@ -300,7 +297,11 @@ impl Font { // Public API pub trait FontMethods { - fn draw_text_into_context(rctx: &RenderContext, run: &TextRun, range: Range, baseline_origin: Point2D); + fn draw_text_into_context(rctx: &RenderContext, + run: &TextRun, + range: Range, + baseline_origin: Point2D, + color: Color); fn measure_text(&TextRun, Range) -> RunMetrics; fn shape_text(@self, &str) -> GlyphStore; fn get_descriptor() -> FontDescriptor; @@ -313,7 +314,11 @@ pub trait FontMethods { } pub impl Font : FontMethods { - fn draw_text_into_context(rctx: &RenderContext, run: &TextRun, range: Range, baseline_origin: Point2D) { + fn draw_text_into_context(rctx: &RenderContext, + run: &TextRun, + range: Range, + baseline_origin: Point2D, + color: Color) { use libc::types::common::c99::{uint16_t, uint32_t}; use azure::{AzDrawOptions, AzGlyph, @@ -324,14 +329,9 @@ pub impl Font : FontMethods { let target = rctx.get_draw_target(); let azfont = self.get_azure_font(); - let color = { - r: 0f as AzFloat, - g: 0f as AzFloat, - b: 0f as AzFloat, - a: 1f as AzFloat - }; - let pattern = AzCreateColorPattern(ptr::to_unsafe_ptr(&color)); - assert pattern.is_not_null(); + let pattern = ColorPattern(color); + let azure_pattern = pattern.azure_color_pattern; + assert azure_pattern.is_not_null(); let options: AzDrawOptions = { mAlpha: 1f as AzFloat, @@ -365,10 +365,12 @@ pub impl Font : FontMethods { }}; // TODO: this call needs to move into azure_hl.rs - AzDrawTargetFillGlyphs(target.azure_draw_target, azfont, - ptr::to_unsafe_ptr(&glyphbuf), pattern, ptr::to_unsafe_ptr(&options), ptr::null()); - - AzReleaseColorPattern(pattern); + AzDrawTargetFillGlyphs(target.azure_draw_target, + azfont, + ptr::to_unsafe_ptr(&glyphbuf), + azure_pattern, + ptr::to_unsafe_ptr(&options), + ptr::null()); } fn measure_text(run: &TextRun, range: Range) -> RunMetrics { diff --git a/src/servo/layout/box.rs b/src/servo/layout/box.rs index 0e68b56e5e1..433c61f5c88 100644 --- a/src/servo/layout/box.rs +++ b/src/servo/layout/box.rs @@ -25,6 +25,7 @@ use newcss::values::{CSSDisplay, Specified, CSSBackgroundColorColor, CSSBackgrou use servo_text::TextRun; use util::range::*; use util::tree; +use util::tree::ReadMethods; use arc = std::arc; use arc::ARC; @@ -411,10 +412,16 @@ impl RenderBox : RenderBoxMethods { match *self { UnscannedTextBox(*) => fail ~"Shouldn't see unscanned boxes here.", 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!("%?", { - 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())) ; ()}); }, @@ -423,7 +430,8 @@ impl RenderBox : RenderBoxMethods { }, ImageBox(_,i) => { 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. */ 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 trait ToGfxColor { fn to_gfx_color(&self) -> gfx::color::Color;