mirror of
https://github.com/servo/servo.git
synced 2025-08-05 21:50:18 +01:00
auto merge of #681 : metajack/servo/asymmetric-borders, r=pcwalton
This commit is contained in:
commit
6ecae7b8db
3 changed files with 86 additions and 59 deletions
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue