Add support for borders on inline elements.

Fix ahem reftests on mac, by disabling text AA in reftest mode.

Also fix precision issues in font metrics to correct height
and baseline calculations.
This commit is contained in:
Glenn Watson 2014-08-29 10:48:35 +10:00
parent a5965442b5
commit e4e1c71d48
10 changed files with 101 additions and 17 deletions

View file

@ -65,6 +65,7 @@ pub extern "C" fn cef_run_message_loop() {
hard_fail: false,
bubble_inline_sizes_separately: false,
show_debug_borders: false,
enable_text_antialiasing: true,
};
native::start(0, 0 as *const *const u8, proc() {
servo::run(opts);

View file

@ -63,7 +63,8 @@ trait ScaledFontExtensionMethods {
run: &Box<TextRun>,
range: &Range<CharIndex>,
baseline_origin: Point2D<Au>,
color: Color);
color: Color,
antialias: bool);
}
impl ScaledFontExtensionMethods for ScaledFont {
@ -72,8 +73,9 @@ impl ScaledFontExtensionMethods for ScaledFont {
run: &Box<TextRun>,
range: &Range<CharIndex>,
baseline_origin: Point2D<Au>,
color: Color) {
use libc::types::common::c99::{uint16_t, uint32_t};
color: Color,
antialias: bool) {
use libc::types::common::c99::uint32_t;
use azure::{struct__AzDrawOptions,
struct__AzGlyph,
struct__AzGlyphBuffer,
@ -85,9 +87,15 @@ impl ScaledFontExtensionMethods for ScaledFont {
let azure_pattern = pattern.azure_color_pattern;
assert!(azure_pattern.is_not_null());
let fields = if antialias {
0x0200
} else {
0
};
let mut options = struct__AzDrawOptions {
mAlpha: 1f64 as AzFloat,
fields: 0x0200 as uint16_t
fields: fields,
};
let mut origin = baseline_origin.clone();
@ -633,7 +641,8 @@ impl DisplayItem {
&*text.text_run,
&text.range,
baseline_origin,
text.text_color
text.text_color,
render_context.opts.enable_text_antialiasing
);
// Undo the transform, only when we did one.

View file

@ -150,7 +150,7 @@ impl FontHandleMethods for FontHandle {
let em_size = Au::from_frac_px(self.ctfont.pt_size() as f64);
let leading = self.ctfont.leading() as f64;
let scale = px_to_pt(self.ctfont.pt_size() as f64) / (self.ctfont.ascent() as f64 + self.ctfont.descent() as f64);
let scale = px_to_pt(self.ctfont.pt_size() as f64) / (ascent + descent);
let line_gap = (ascent + descent + leading + 0.5).floor();
let metrics = FontMetrics {
@ -166,12 +166,11 @@ impl FontHandleMethods for FontHandle {
leading: Au::from_pt(leading),
x_height: Au::from_pt(self.ctfont.x_height() as f64),
em_size: em_size,
ascent: Au::from_pt(ascent).scale_by(scale),
descent: Au::from_pt(descent).scale_by(scale),
ascent: Au::from_pt(ascent * scale),
descent: Au::from_pt(descent * scale),
max_advance: Au::from_pt(bounding_rect.size.width as f64),
line_gap: Au::from_frac_px(line_gap),
};
debug!("Font metrics (@{:f} pt): {:?}", self.ctfont.pt_size() as f64, metrics);
return metrics;
}

View file

@ -756,16 +756,15 @@ impl Fragment {
/// Adds the display items necessary to paint the borders of this fragment to a display list if
/// necessary.
pub fn build_display_list_for_borders_if_applicable(&self,
style: &ComputedValues,
list: &mut DisplayList,
abs_bounds: &Rect<Au>,
level: StackingLevel) {
// Fast path.
let border = self.border_width();
let border = style.logical_border_width();
if border.is_zero() {
return
}
let style = self.style();
let top_color = style.resolve_color(style.get_border().border_top_color);
let right_color = style.resolve_color(style.get_border().border_right_color);
let bottom_color = style.resolve_color(style.get_border().border_bottom_color);
@ -774,7 +773,7 @@ impl Fragment {
// Append the border to the display list.
let border_display_item = box BorderDisplayItem {
base: BaseDisplayItem::new(*abs_bounds, self.node, level),
border: border.to_physical(self.style.writing_mode),
border: border.to_physical(style.writing_mode),
color: SideOffsets2D::new(top_color.to_gfx_color(),
right_color.to_gfx_color(),
bottom_color.to_gfx_color(),
@ -922,9 +921,22 @@ impl Fragment {
// Add a border, if applicable.
//
// TODO: Outlines.
self.build_display_list_for_borders_if_applicable(display_list,
&absolute_fragment_bounds,
level);
match self.inline_context {
Some(ref inline_context) => {
for style in inline_context.styles.iter().rev() {
self.build_display_list_for_borders_if_applicable(&**style,
display_list,
&absolute_fragment_bounds,
level);
}
}
None => {
self.build_display_list_for_borders_if_applicable(&*self.style,
display_list,
&absolute_fragment_bounds,
level);
}
}
}
let content_box = self.content_box();

View file

@ -225,7 +225,7 @@ impl Au {
#[inline]
pub fn from_pt(pt: f64) -> Au {
from_px(pt_to_px(pt) as int)
from_frac_px(pt_to_px(pt))
}
#[inline]

View file

@ -72,6 +72,11 @@ pub struct Opts {
/// True if we should show borders on all layers and tiles for
/// debugging purposes (`--show-debug-borders`).
pub show_debug_borders: bool,
/// If set with --disable-text-aa, disable antialiasing on fonts. This is primarily useful for reftests
/// where pixel perfect results are required when using fonts such as the Ahem
/// font for layout tests.
pub enable_text_antialiasing: bool,
}
fn print_usage(app: &str, opts: &[getopts::OptGroup]) {
@ -104,6 +109,7 @@ pub fn from_cmdline_args(args: &[String]) -> Option<Opts> {
getopts::optflag("f", "hard-fail", "Exit on task failure instead of displaying about:failure"),
getopts::optflag("b", "bubble-widths", "Bubble intrinsic widths separately like other engines"),
getopts::optflag("", "show-debug-borders", "Show debugging borders on layers and tiles."),
getopts::optflag("", "disable-text-aa", "Disable antialiasing for text rendering."),
getopts::optflag("h", "help", "Print this message")
);
@ -193,6 +199,7 @@ pub fn from_cmdline_args(args: &[String]) -> Option<Opts> {
hard_fail: opt_match.opt_present("f"),
bubble_inline_sizes_separately: opt_match.opt_present("b"),
show_debug_borders: opt_match.opt_present("show-debug-borders"),
enable_text_antialiasing: !opt_match.opt_present("disable-text-aa"),
})
}

View file

@ -219,6 +219,8 @@ fn capture(reftest: &Reftest, side: uint) -> (u32, u32, Vec<u8>) {
if reftest.experimental {
args.push("--experimental".to_string());
}
// Allows pixel perfect rendering of Ahem font for reftests.
args.push("--disable-text-aa".to_string());
args.push_all(["-f".to_string(), "-o".to_string(), filename.clone(),
reftest.files[side].clone()]);

View file

@ -106,3 +106,4 @@ experimental == vertical-lr-blocks.html vertical-lr-blocks_ref.html
flaky_gpu,flaky_linux == acid2_noscroll.html acid2_ref_broken.html
!= inline_background_a.html inline_background_ref.html
== inline_element_border_a.html inline_element_border_ref.html

View file

@ -0,0 +1,24 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<style type="text/css">
@font-face {
font-family: 'ahem';
src: url(fonts/ahem/ahem.ttf);
}
.large-border {
border-left: 100px solid red;
border-right: 100px solid blue;
}
.green {
color: green;
}
body {
font-family: 'ahem';
font-size: 100px;
margin: 0;
}
</style>
</head>
<body><span class="large-border green">X</span></body>
</html>

View file

@ -0,0 +1,29 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<style type="text/css">
.red {
background-color: red;
}
.green {
background-color: green;
}
.blue {
background-color: blue;
}
div {
width: 100px;
height: 100px;
float: left;
}
body {
margin: 0;
}
</style>
</head>
<body>
<div class="red"></div>
<div class="green"></div>
<div class="blue"></div>
</body>
</html>