diff options
-rw-r--r-- | src/components/gfx/display_list.rs | 12 | ||||
-rw-r--r-- | src/components/gfx/render_context.rs | 66 | ||||
-rw-r--r-- | src/components/main/layout/box.rs | 67 |
3 files changed, 86 insertions, 59 deletions
diff --git a/src/components/gfx/display_list.rs b/src/components/gfx/display_list.rs index 5d6f5188faa..3c220974b9b 100644 --- a/src/components/gfx/display_list.rs +++ b/src/components/gfx/display_list.rs @@ -20,7 +20,7 @@ use render_context::RenderContext; use text::SendableTextRun; use std::cast::transmute_region; -use geom::{Point2D, Rect, Size2D}; +use geom::{Point2D, Rect, Size2D, SideOffsets2D}; use servo_net::image::base::Image; use servo_util::range::Range; use extra::arc::ARC; @@ -99,8 +99,10 @@ pub struct ImageDisplayItem<E> { /// Renders a border. pub struct BorderDisplayItem<E> { base: BaseDisplayItem<E>, - /// The width of the border. - width: Au, + + /// The border widths + border: SideOffsets2D<Au>, + /// The color of the border. color: Color, } @@ -147,7 +149,9 @@ impl<E> DisplayItem<E> { } BorderDisplayItemClass(ref border) => { - render_context.draw_border(&border.base.bounds, border.width, border.color) + render_context.draw_border(&border.base.bounds, + border.border, + border.color) } } } diff --git a/src/components/gfx/render_context.rs b/src/components/gfx/render_context.rs index f36445acf8c..00ccdcabf32 100644 --- a/src/components/gfx/render_context.rs +++ b/src/components/gfx/render_context.rs @@ -14,6 +14,7 @@ use std::libc::types::common::c99::uint16_t; use geom::point::Point2D; use geom::rect::Rect; use geom::size::Size2D; +use geom::side_offsets::SideOffsets2D; use servo_net::image::base::Image; use extra::arc::ARC; @@ -33,21 +34,47 @@ impl<'self> RenderContext<'self> { self.canvas.draw_target.fill_rect(&bounds.to_azure_rect(), &ColorPattern(color)); } - pub fn draw_border(&self, bounds: &Rect<Au>, width: Au, color: Color) { + pub fn draw_border(&self, + bounds: &Rect<Au>, + border: SideOffsets2D<Au>, + color: Color) { let pattern = ColorPattern(color); - let stroke_fields = 2; // CAP_SQUARE - let width_px = width.to_px(); - let rect = if width_px % 2 == 0 { - bounds.to_azure_rect() - } else { - bounds.to_azure_snapped_rect() - }; - - let stroke_opts = StrokeOptions(width_px as AzFloat, 10 as AzFloat, stroke_fields); 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(); - self.canvas.draw_target.stroke_rect(&rect, &pattern, &stroke_opts, &draw_opts); + + // draw top border + stroke_opts.line_width = border.top; + 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, &pattern, &stroke_opts, &draw_opts); + + // draw bottom border + stroke_opts.line_width = border.bottom; + 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, &pattern, &stroke_opts, &draw_opts); + + // draw left border + stroke_opts.line_width = border.left; + 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); + self.canvas.draw_target.stroke_line(start, end, &pattern, &stroke_opts, &draw_opts); + + // draw right border + stroke_opts.line_width = border.right; + 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, &pattern, &stroke_opts, &draw_opts); } pub fn draw_image(&self, bounds: Rect<Au>, image: ARC<~Image>) { @@ -94,7 +121,6 @@ impl to_float for u8 { trait ToAzureRect { fn to_azure_rect(&self) -> Rect<AzFloat>; - fn to_azure_snapped_rect(&self) -> Rect<AzFloat>; } impl ToAzureRect for Rect<Au> { @@ -102,11 +128,17 @@ impl ToAzureRect for Rect<Au> { Rect(Point2D(self.origin.x.to_px() as AzFloat, self.origin.y.to_px() as AzFloat), Size2D(self.size.width.to_px() as AzFloat, self.size.height.to_px() as AzFloat)) } +} + +trait ToSideOffsetsPx { + fn to_float_px(&self) -> SideOffsets2D<AzFloat>; +} - fn to_azure_snapped_rect(&self) -> Rect<AzFloat> { - Rect(Point2D(self.origin.x.to_px() as AzFloat + 0.5f as AzFloat, - self.origin.y.to_px() as AzFloat + 0.5f as AzFloat), - Size2D(self.size.width.to_px() as AzFloat, - self.size.height.to_px() as AzFloat)) +impl ToSideOffsetsPx for SideOffsets2D<Au> { + fn to_float_px(&self) -> SideOffsets2D<AzFloat> { + SideOffsets2D::new(self.top.to_px() as AzFloat, + self.right.to_px() as AzFloat, + self.bottom.to_px() as AzFloat, + self.left.to_px() as AzFloat) } } diff --git a/src/components/main/layout/box.rs b/src/components/main/layout/box.rs index 1839d93dfc0..72271e0cd39 100644 --- a/src/components/main/layout/box.rs +++ b/src/components/main/layout/box.rs @@ -16,7 +16,7 @@ use std::cmp::ApproxEq; use std::managed; use std::num::Zero; use std::uint; -use geom::{Point2D, Rect, Size2D}; +use geom::{Point2D, Rect, Size2D, SideOffsets2D}; use gfx::display_list::{BaseDisplayItem, BorderDisplayItem, BorderDisplayItemClass}; use gfx::display_list::{DisplayList, ImageDisplayItem, ImageDisplayItemClass}; use gfx::display_list::{SolidColorDisplayItem, SolidColorDisplayItemClass, TextDisplayItem}; @@ -629,13 +629,17 @@ impl RenderBox { // should have a real `SERVO_DEBUG` system. debug!("%?", { // Compute the text box bounds and draw a border surrounding them. + let debug_border = SideOffsets2D::new(Au::from_px(1), + Au::from_px(1), + Au::from_px(1), + Au::from_px(1)); do list.with_mut_ref |list| { let border_display_item = ~BorderDisplayItem { base: BaseDisplayItem { bounds: absolute_box_bounds, extra: ExtraDisplayListData::new(*self), }, - width: Au::from_px(1), + border: debug_border, color: rgb(0, 0, 200).to_gfx_color(), }; list.append_item(BorderDisplayItemClass(border_display_item)) @@ -655,7 +659,7 @@ impl RenderBox { bounds: baseline, extra: ExtraDisplayListData::new(*self), }, - width: Au::from_px(1), + border: debug_border, color: rgb(0, 200, 0).to_gfx_color(), }; list.append_item(BorderDisplayItemClass(border_display_item)) @@ -672,13 +676,18 @@ impl RenderBox { // FIXME(pcwalton): This is a bit of an abuse of the logging infrastructure. We // should have a real `SERVO_DEBUG` system. debug!("%?", { + let debug_border = SideOffsets2D::new(Au::from_px(1), + Au::from_px(1), + Au::from_px(1), + Au::from_px(1)); + do list.with_mut_ref |list| { let border_display_item = ~BorderDisplayItem { base: BaseDisplayItem { bounds: absolute_box_bounds, extra: ExtraDisplayListData::new(*self), }, - width: Au::from_px(1), + border: debug_border, color: rgb(0, 0, 200).to_gfx_color(), }; list.append_item(BorderDisplayItemClass(border_display_item)) @@ -896,43 +905,25 @@ impl RenderBox { return } - // Are all the widths equal? - // - // FIXME(pcwalton): Obviously this is wrong. - let borders = [ border.top, border.right, border.bottom ]; - if borders.iter().all(|a| *a == border.left) { - let border_width = border.top; - let bounds = Rect { - origin: Point2D { - x: abs_bounds.origin.x + border_width.scale_by(0.5), - y: abs_bounds.origin.y + border_width.scale_by(0.5), + // FIXME: all colors set to top color. this is obviously not right. + let top_color = self.style().border_top_color(); + let color = top_color.to_gfx_color(); + + // Append the border to the display list. + do list.with_mut_ref |list| { + let border_display_item = ~BorderDisplayItem { + base: BaseDisplayItem { + bounds: *abs_bounds, + extra: ExtraDisplayListData::new(*self), }, - size: Size2D { - width: abs_bounds.size.width - border_width, - height: abs_bounds.size.height - border_width - } + border: SideOffsets2D::new(border.top, + border.right, + border.bottom, + border.left), + color: color, }; - let top_color = self.style().border_top_color(); - let color = top_color.to_gfx_color(); // FIXME - - // Append the border to the display list. - do list.with_mut_ref |list| { - let border_display_item = ~BorderDisplayItem { - base: BaseDisplayItem { - bounds: bounds, - extra: ExtraDisplayListData::new(*self), - }, - width: border_width, - color: color, - }; - - list.append_item(BorderDisplayItemClass(border_display_item)) - } - } else { - warn!("ignoring unimplemented border widths"); + list.append_item(BorderDisplayItemClass(border_display_item)) } } - } - |