diff --git a/src/components/gfx/render_context.rs b/src/components/gfx/render_context.rs index c9d278fea96..80f58af5ee8 100644 --- a/src/components/gfx/render_context.rs +++ b/src/components/gfx/render_context.rs @@ -5,12 +5,18 @@ use servo_msg::compositor_msg::LayerBuffer; use font_context::FontContext; use geometry::Au; +use newcss::values::CSSBorderStyle; +use newcss::values::{CSSBorderStyleNone, CSSBorderStyleHidden, CSSBorderStyleDotted, CSSBorderStyleDashed, CSSBorderStyleSolid, CSSBorderStyleDouble, CSSBorderStyleGroove, CSSBorderStyleRidge, CSSBorderStyleInset, CSSBorderStyleOutset}; use opts::Opts; use azure::azure_hl::{B8G8R8A8, Color, ColorPattern, DrawOptions}; use azure::azure_hl::{DrawSurfaceOptions, DrawTarget, Linear, StrokeOptions}; +use azure::{AZ_CAP_BUTT, AZ_CAP_ROUND}; +use azure::AZ_JOIN_BEVEL; use azure::AzFloat; +use std::vec; use std::libc::types::common::c99::uint16_t; +use std::libc::size_t; use geom::point::Point2D; use geom::rect::Rect; use geom::size::Size2D; @@ -37,39 +43,39 @@ impl<'self> RenderContext<'self> { pub fn draw_border(&self, bounds: &Rect, border: SideOffsets2D, - color: SideOffsets2D) { + color: SideOffsets2D, + style: SideOffsets2D) { let draw_opts = DrawOptions(1 as AzFloat, 0 as uint16_t); - let stroke_fields = 2; // CAP_SQUARE - let mut stroke_opts = StrokeOptions(0 as AzFloat, 10 as AzFloat, stroke_fields); - let rect = bounds.to_azure_rect(); let border = border.to_float_px(); self.canvas.draw_target.make_current(); - + let mut dash: [AzFloat, ..2] = [0 as AzFloat, 0 as AzFloat]; + let mut stroke_opts = StrokeOptions(0 as AzFloat, 10 as AzFloat); + // draw top border - stroke_opts.line_width = border.top; + RenderContext::apply_border_style(style.top, border.top, dash, &mut stroke_opts); let y = rect.origin.y + border.top * 0.5; let start = Point2D(rect.origin.x, y); let end = Point2D(rect.origin.x + rect.size.width, y); self.canvas.draw_target.stroke_line(start, end, &ColorPattern(color.top), &stroke_opts, &draw_opts); // draw right border - stroke_opts.line_width = border.right; + RenderContext::apply_border_style(style.right, border.right, dash, &mut stroke_opts); let x = rect.origin.x + rect.size.width - border.right * 0.5; let start = Point2D(x, rect.origin.y); let end = Point2D(x, rect.origin.y + rect.size.height); self.canvas.draw_target.stroke_line(start, end, &ColorPattern(color.right), &stroke_opts, &draw_opts); // draw bottom border - stroke_opts.line_width = border.bottom; + RenderContext::apply_border_style(style.bottom, border.bottom, dash, &mut stroke_opts); let y = rect.origin.y + rect.size.height - border.bottom * 0.5; let start = Point2D(rect.origin.x, y); let end = Point2D(rect.origin.x + rect.size.width, y); self.canvas.draw_target.stroke_line(start, end, &ColorPattern(color.bottom), &stroke_opts, &draw_opts); // draw left border - stroke_opts.line_width = border.left; + RenderContext::apply_border_style(style.left, border.left, dash, &mut stroke_opts); let x = rect.origin.x + border.left * 0.5; let start = Point2D(x, rect.origin.y); let end = Point2D(x, rect.origin.y + rect.size.height); @@ -106,6 +112,62 @@ impl<'self> RenderContext<'self> { self.canvas.draw_target.make_current(); self.canvas.draw_target.fill_rect(&rect, &pattern); } + + fn apply_border_style(style: CSSBorderStyle, border_width: AzFloat, dash: &mut [AzFloat], stroke_opts: &mut StrokeOptions){ + match style{ + CSSBorderStyleNone => { + } + CSSBorderStyleHidden => { + } + //FIXME(sammykim): This doesn't work with dash_pattern and cap_style well. I referred firefox code. + CSSBorderStyleDotted => { + stroke_opts.line_width = border_width; + + if border_width > 2.0 { + dash[0] = 0 as AzFloat; + dash[1] = border_width * 2.0; + + stroke_opts.set_cap_style(AZ_CAP_ROUND as u8); + } else { + dash[0] = border_width; + dash[1] = border_width; + } + stroke_opts.mDashPattern = vec::raw::to_ptr(dash); + stroke_opts.mDashLength = dash.len() as size_t; + } + CSSBorderStyleDashed => { + stroke_opts.set_cap_style(AZ_CAP_BUTT as u8); + stroke_opts.line_width = border_width; + dash[0] = border_width*3 as AzFloat; + dash[1] = border_width*3 as AzFloat; + stroke_opts.mDashPattern = vec::raw::to_ptr(dash); + stroke_opts.mDashLength = dash.len() as size_t; + } + //FIXME(sammykim): BorderStyleSolid doesn't show proper join-style with comparing firefox. + CSSBorderStyleSolid => { + stroke_opts.set_cap_style(AZ_CAP_BUTT as u8); + stroke_opts.set_join_style(AZ_JOIN_BEVEL as u8); + stroke_opts.line_width = border_width; + stroke_opts.mDashLength = 0 as size_t; + } + //FIXME(sammykim): Five more styles should be implemented. + CSSBorderStyleDouble => { + + } + CSSBorderStyleGroove => { + + } + CSSBorderStyleRidge => { + + } + CSSBorderStyleInset => { + + } + CSSBorderStyleOutset => { + + } + } + } } trait to_float {