auto merge of #681 : metajack/servo/asymmetric-borders, r=pcwalton

This commit is contained in:
bors-servo 2013-08-07 16:33:32 -07:00
commit 6ecae7b8db
3 changed files with 86 additions and 59 deletions

View file

@ -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)
}
}
}

View file

@ -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))
}
}
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))
trait ToSideOffsetsPx {
fn to_float_px(&self) -> SideOffsets2D<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)
}
}

View file

@ -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),
},
size: Size2D {
width: abs_bounds.size.width - border_width,
height: abs_bounds.size.height - border_width
}
};
// 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(); // FIXME
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: bounds,
bounds: *abs_bounds,
extra: ExtraDisplayListData::new(*self),
},
width: border_width,
border: SideOffsets2D::new(border.top,
border.right,
border.bottom,
border.left),
color: color,
};
list.append_item(BorderDisplayItemClass(border_display_item))
}
} else {
warn!("ignoring unimplemented border widths");
}
}
}