diff --git a/src/rust-azure b/src/rust-azure index 06d659d6a87..6ca8a28d257 160000 --- a/src/rust-azure +++ b/src/rust-azure @@ -1 +1 @@ -Subproject commit 06d659d6a875c6e48e78cf3e3082e11cf7bbb169 +Subproject commit 6ca8a28d2575379ad6e47ae72aa4c879743f3cf7 diff --git a/src/servo/css/parser.rs b/src/servo/css/parser.rs index 5d49f084ce8..05bb6d5ab80 100644 --- a/src/servo/css/parser.rs +++ b/src/servo/css/parser.rs @@ -165,6 +165,8 @@ impl TokenReader : ParserMethods { ~"font-size" => parse_font_size(val).extract(|res| FontSize(res)), ~"height" => parse_box_sizing(val).extract(|res| Height(res)), ~"width" => parse_box_sizing(val).extract(|res| Width(res)), + ~"border-width" => parse_length(val).map(|res| BorderWidth(Specified(*res))), + ~"border-color" => parse_color(val).map(|res| BorderColor(Specified(BdrColor(*res)))), _ => { #debug["Recieved unknown style property '%s'", val]; None } }; match desc { diff --git a/src/servo/css/parser_util.rs b/src/servo/css/parser_util.rs index 3e5a589f831..d36edd28100 100644 --- a/src/servo/css/parser_util.rs +++ b/src/servo/css/parser_util.rs @@ -64,7 +64,7 @@ fn parse_box_sizing(str : &str) -> ParseResult { match str.to_str() { ~"auto" => Value(BoxAuto), ~"inherit" => CSSInherit, - _ => Fail, + _ => Fail } } diff --git a/src/servo/css/resolve/matching.rs b/src/servo/css/resolve/matching.rs index c71e4518e95..f894529fc13 100644 --- a/src/servo/css/resolve/matching.rs +++ b/src/servo/css/resolve/matching.rs @@ -181,7 +181,9 @@ impl Node : PrivStyleMethods { FontSize(size) => layout.style.font_size = size, Height(size) => layout.style.height = size, Color(col) => layout.style.text_color = col, - Width(size) => layout.style.width = size + Width(size) => layout.style.width = size, + BorderColor(col) => layout.style.border_color = col, + BorderWidth(size) => layout.style.border_width = size, }; }) } diff --git a/src/servo/css/styles.rs b/src/servo/css/styles.rs index 6c349257a6d..d2844aba77c 100644 --- a/src/servo/css/styles.rs +++ b/src/servo/css/styles.rs @@ -20,7 +20,10 @@ type SpecifiedStyle = {mut background_color : CSSValue, mut font_size : CSSValue, mut height : CSSValue, mut text_color : CSSValue, - mut width : CSSValue + mut width : CSSValue, + mut border_color : CSSValue, + mut border_style : CSSValue, + mut border_width : CSSValue }; trait DefaultStyleMethods { @@ -83,7 +86,10 @@ fn empty_style_for_node_kind(kind: &NodeKind) -> SpecifiedStyle { mut font_size : Initial, mut height : Initial, mut text_color : Initial, - mut width : Initial} + mut width : Initial, + mut border_color : Initial, + mut border_style : Initial, + mut border_width : Initial} } trait StyleMethods { diff --git a/src/servo/css/values.rs b/src/servo/css/values.rs index 6a5a11f86b1..2b7b3d6c153 100644 --- a/src/servo/css/values.rs +++ b/src/servo/css/values.rs @@ -117,6 +117,24 @@ enum CSSBackgroundImage { BgImageNone, } +enum CSSBorderColor { + BdrColor(SharedColor), + BdrColorTransparent +} + +enum CSSBorderStyle { + BdrStyleNone, + BdrStyleHidden, + BdrStyleDotted, + BdrStyleDashed, + BdrStyleSolid, + BdrStyleDouble, + BdrStyleGroove, + BdrStyleRidge, + BdrStyleInset, + BdrStyleOutset, +} + enum CSSColor { TextColor(SharedColor) } @@ -165,7 +183,9 @@ enum StyleDeclaration { FontSize(CSSValue), Height(CSSValue), Color(CSSValue), - Width(CSSValue) + Width(CSSValue), + BorderColor(CSSValue), + BorderWidth(CSSValue) } pub enum Attr { diff --git a/src/servo/gfx/display_list.rs b/src/servo/gfx/display_list.rs index d3abb70696b..0e7bf4b41af 100644 --- a/src/servo/gfx/display_list.rs +++ b/src/servo/gfx/display_list.rs @@ -1,5 +1,5 @@ use azure::azure_hl::DrawTarget; -use gfx::render_task::{draw_solid_color, draw_image, draw_text}; +use gfx::render_task::{draw_solid_color, draw_image, draw_text, draw_border}; use gfx::geometry::*; use geom::rect::Rect; use image::base::Image; @@ -27,6 +27,7 @@ pub enum DisplayItemData { // TODO: don't copy text runs, ever. TextData(~SendableTextRun, uint, uint), ImageData(ARC<~image::base::Image>), + BorderData(au, u8, u8, u8) } fn draw_SolidColor(self: &DisplayItem, ctx: &RenderContext) { @@ -53,6 +54,13 @@ fn draw_Image(self: &DisplayItem, ctx: &RenderContext) { } } +fn draw_Border(self: &DisplayItem, ctx: &RenderContext) { + match self.data { + BorderData(width, r, g, b) => draw_border(ctx, &self.bounds, width, r, g, b), + _ => fail + } +} + pub fn SolidColor(bounds: Rect, r: u8, g: u8, b: u8) -> DisplayItem { DisplayItem { draw: |self, ctx| draw_SolidColor(self, ctx), @@ -61,6 +69,14 @@ pub fn SolidColor(bounds: Rect, r: u8, g: u8, b: u8) -> DisplayItem { } } +pub fn Border(bounds: Rect, width: au, r: u8, g: u8, b: u8) -> DisplayItem { + DisplayItem { + draw: |self, ctx| draw_Border(self, ctx), + bounds: bounds, + data: BorderData(width, r, g, b) + } +} + pub fn Text(bounds: Rect, run: ~SendableTextRun, offset: uint, length: uint) -> DisplayItem { DisplayItem { draw: |self, ctx| draw_Text(self, ctx), diff --git a/src/servo/gfx/render_task.rs b/src/servo/gfx/render_task.rs index ac8a4901162..06a0f41f33d 100644 --- a/src/servo/gfx/render_task.rs +++ b/src/servo/gfx/render_task.rs @@ -6,7 +6,7 @@ use azure::bindgen::AzDrawTargetFillGlyphs; use azure::cairo::{cairo_font_face_t, cairo_scaled_font_t}; use azure::cairo_hl::ImageSurface; use azure::{AzDrawOptions, AzFloat, AzGlyph, AzGlyphBuffer}; -use azure_hl::{AsAzureRect, B8G8R8A8, Color, ColorPattern, DrawOptions, DrawSurfaceOptions}; +use azure_hl::{AsAzureRect, B8G8R8A8, Color, ColorPattern, DrawOptions, DrawSurfaceOptions, StrokeOptions}; use azure_hl::{DrawTarget, Linear}; use comm::*; use compositor::Compositor; @@ -19,6 +19,7 @@ use mod gfx::render_layers; use gfx::render_layers::RenderLayer; use image::base::Image; use libc::size_t; +use libc::types::common::c99::uint16_t; use pipes::{Port, Chan}; use platform::osmain; use ptr::to_unsafe_ptr; @@ -141,6 +142,20 @@ pub fn draw_solid_color(ctx: &RenderContext, bounds: &Rect, r: u8, g: u8, b: ctx.canvas.draw_target.fill_rect(&bounds.to_azure_rect(), &ColorPattern(color)); } +pub fn draw_border(ctx: &RenderContext, bounds: &Rect, width: au, r: u8, g: u8, b: u8) { + let rect = bounds.to_azure_rect(); + let color = Color(r.to_float() as AzFloat, + g.to_float() as AzFloat, + b.to_float() as AzFloat, + 1f as AzFloat); + let pattern = ColorPattern(color); + let stroke_fields = 2; // CAP_SQUARE + let stroke_opts = StrokeOptions(au::to_px(width) as AzFloat, 10 as AzFloat, stroke_fields); + let draw_opts = DrawOptions(1 as AzFloat, 0 as uint16_t); + + ctx.canvas.draw_target.stroke_rect(&rect, &pattern, &stroke_opts, &draw_opts); +} + pub fn draw_image(ctx: &RenderContext, bounds: Rect, image: ARC<~Image>) { let image = std::arc::get(&image); let size = Size2D(image.width as i32, image.height as i32); diff --git a/src/servo/layout/box.rs b/src/servo/layout/box.rs index 5499e9ae1e2..4b9868bcf54 100644 --- a/src/servo/layout/box.rs +++ b/src/servo/layout/box.rs @@ -1,5 +1,6 @@ /* Fundamental layout structures and algorithms. */ +use servo_util::color::rgb; use arc = std::arc; use arc::ARC; use au = gfx::geometry; @@ -8,7 +9,7 @@ use core::dvec::DVec; use core::to_str::ToStr; use core::rand; use css::styles::SpecifiedStyle; -use css::values::{BoxSizing, Length, Px, CSSDisplay, Specified, BgColor, BgColorTransparent}; +use css::values::{BoxSizing, Length, Px, CSSDisplay, Specified, BgColor, BgColorTransparent, BdrColor}; use dl = gfx::display_list; use dom::element::{ElementKind, HTMLDivElement, HTMLImageElement}; use dom::node::{Element, Node, NodeData, NodeKind, NodeTree}; @@ -410,6 +411,8 @@ impl RenderBox : RenderBoxMethods { } } } + + self.add_border_to_list(list, bounds); } fn add_bgcolor_to_list(list: &dl::DisplayList, bounds: Rect) { @@ -424,6 +427,32 @@ impl RenderBox : RenderBoxMethods { list.push(~dl::SolidColor(bounds, bgcolor.red, bgcolor.green, bgcolor.blue)); } } + + fn add_border_to_list(list: &dl::DisplayList, bounds: Rect) { + let style = self.d().node.style(); + match style.border_width { + Specified(Px(px)) => { + // If there's a border, let's try to display *something* + let border_width = au::from_frac_px(px); + let bounds = Rect { + origin: Point2D { + x: bounds.origin.x - border_width / au(2), + y: bounds.origin.y - border_width / au(2), + }, + size: Size2D { + width: bounds.size.width + border_width, + height: bounds.size.height + border_width + } + }; + let color = match style.border_color { + Specified(BdrColor(color)) => color, + _ => rgb(0, 0, 0) // FIXME + }; + list.push(~dl::Border(bounds, border_width, color.red, color.green, color.blue)); + } + _ => () // TODO + } + } } impl RenderBox : BoxedDebugMethods { diff --git a/src/test/test-border.css b/src/test/test-border.css new file mode 100644 index 00000000000..e797cdfa2d0 --- /dev/null +++ b/src/test/test-border.css @@ -0,0 +1,4 @@ +img { + border-width: 10px; + border-color: blue +} \ No newline at end of file diff --git a/src/test/test-border.html b/src/test/test-border.html new file mode 100644 index 00000000000..56e448e58c1 --- /dev/null +++ b/src/test/test-border.html @@ -0,0 +1,11 @@ + + + + + + + + + + +