mirror of
https://github.com/servo/servo.git
synced 2025-08-06 14:10:11 +01:00
Merge pull request #3182 from glennw/inline-text-border
Add support for borders on inline elements
This commit is contained in:
commit
603f7c9770
10 changed files with 101 additions and 17 deletions
|
@ -65,6 +65,7 @@ pub extern "C" fn cef_run_message_loop() {
|
||||||
hard_fail: false,
|
hard_fail: false,
|
||||||
bubble_inline_sizes_separately: false,
|
bubble_inline_sizes_separately: false,
|
||||||
show_debug_borders: false,
|
show_debug_borders: false,
|
||||||
|
enable_text_antialiasing: true,
|
||||||
};
|
};
|
||||||
native::start(0, 0 as *const *const u8, proc() {
|
native::start(0, 0 as *const *const u8, proc() {
|
||||||
servo::run(opts);
|
servo::run(opts);
|
||||||
|
|
|
@ -63,7 +63,8 @@ trait ScaledFontExtensionMethods {
|
||||||
run: &Box<TextRun>,
|
run: &Box<TextRun>,
|
||||||
range: &Range<CharIndex>,
|
range: &Range<CharIndex>,
|
||||||
baseline_origin: Point2D<Au>,
|
baseline_origin: Point2D<Au>,
|
||||||
color: Color);
|
color: Color,
|
||||||
|
antialias: bool);
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ScaledFontExtensionMethods for ScaledFont {
|
impl ScaledFontExtensionMethods for ScaledFont {
|
||||||
|
@ -72,8 +73,9 @@ impl ScaledFontExtensionMethods for ScaledFont {
|
||||||
run: &Box<TextRun>,
|
run: &Box<TextRun>,
|
||||||
range: &Range<CharIndex>,
|
range: &Range<CharIndex>,
|
||||||
baseline_origin: Point2D<Au>,
|
baseline_origin: Point2D<Au>,
|
||||||
color: Color) {
|
color: Color,
|
||||||
use libc::types::common::c99::{uint16_t, uint32_t};
|
antialias: bool) {
|
||||||
|
use libc::types::common::c99::uint32_t;
|
||||||
use azure::{struct__AzDrawOptions,
|
use azure::{struct__AzDrawOptions,
|
||||||
struct__AzGlyph,
|
struct__AzGlyph,
|
||||||
struct__AzGlyphBuffer,
|
struct__AzGlyphBuffer,
|
||||||
|
@ -85,9 +87,15 @@ impl ScaledFontExtensionMethods for ScaledFont {
|
||||||
let azure_pattern = pattern.azure_color_pattern;
|
let azure_pattern = pattern.azure_color_pattern;
|
||||||
assert!(azure_pattern.is_not_null());
|
assert!(azure_pattern.is_not_null());
|
||||||
|
|
||||||
|
let fields = if antialias {
|
||||||
|
0x0200
|
||||||
|
} else {
|
||||||
|
0
|
||||||
|
};
|
||||||
|
|
||||||
let mut options = struct__AzDrawOptions {
|
let mut options = struct__AzDrawOptions {
|
||||||
mAlpha: 1f64 as AzFloat,
|
mAlpha: 1f64 as AzFloat,
|
||||||
fields: 0x0200 as uint16_t
|
fields: fields,
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut origin = baseline_origin.clone();
|
let mut origin = baseline_origin.clone();
|
||||||
|
@ -633,7 +641,8 @@ impl DisplayItem {
|
||||||
&*text.text_run,
|
&*text.text_run,
|
||||||
&text.range,
|
&text.range,
|
||||||
baseline_origin,
|
baseline_origin,
|
||||||
text.text_color
|
text.text_color,
|
||||||
|
render_context.opts.enable_text_antialiasing
|
||||||
);
|
);
|
||||||
|
|
||||||
// Undo the transform, only when we did one.
|
// Undo the transform, only when we did one.
|
||||||
|
|
|
@ -150,7 +150,7 @@ impl FontHandleMethods for FontHandle {
|
||||||
let em_size = Au::from_frac_px(self.ctfont.pt_size() as f64);
|
let em_size = Au::from_frac_px(self.ctfont.pt_size() as f64);
|
||||||
let leading = self.ctfont.leading() 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 line_gap = (ascent + descent + leading + 0.5).floor();
|
||||||
|
|
||||||
let metrics = FontMetrics {
|
let metrics = FontMetrics {
|
||||||
|
@ -166,12 +166,11 @@ impl FontHandleMethods for FontHandle {
|
||||||
leading: Au::from_pt(leading),
|
leading: Au::from_pt(leading),
|
||||||
x_height: Au::from_pt(self.ctfont.x_height() as f64),
|
x_height: Au::from_pt(self.ctfont.x_height() as f64),
|
||||||
em_size: em_size,
|
em_size: em_size,
|
||||||
ascent: Au::from_pt(ascent).scale_by(scale),
|
ascent: Au::from_pt(ascent * scale),
|
||||||
descent: Au::from_pt(descent).scale_by(scale),
|
descent: Au::from_pt(descent * scale),
|
||||||
max_advance: Au::from_pt(bounding_rect.size.width as f64),
|
max_advance: Au::from_pt(bounding_rect.size.width as f64),
|
||||||
line_gap: Au::from_frac_px(line_gap),
|
line_gap: Au::from_frac_px(line_gap),
|
||||||
};
|
};
|
||||||
|
|
||||||
debug!("Font metrics (@{:f} pt): {:?}", self.ctfont.pt_size() as f64, metrics);
|
debug!("Font metrics (@{:f} pt): {:?}", self.ctfont.pt_size() as f64, metrics);
|
||||||
return metrics;
|
return metrics;
|
||||||
}
|
}
|
||||||
|
|
|
@ -756,16 +756,15 @@ impl Fragment {
|
||||||
/// Adds the display items necessary to paint the borders of this fragment to a display list if
|
/// Adds the display items necessary to paint the borders of this fragment to a display list if
|
||||||
/// necessary.
|
/// necessary.
|
||||||
pub fn build_display_list_for_borders_if_applicable(&self,
|
pub fn build_display_list_for_borders_if_applicable(&self,
|
||||||
|
style: &ComputedValues,
|
||||||
list: &mut DisplayList,
|
list: &mut DisplayList,
|
||||||
abs_bounds: &Rect<Au>,
|
abs_bounds: &Rect<Au>,
|
||||||
level: StackingLevel) {
|
level: StackingLevel) {
|
||||||
// Fast path.
|
let border = style.logical_border_width();
|
||||||
let border = self.border_width();
|
|
||||||
if border.is_zero() {
|
if border.is_zero() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
let style = self.style();
|
|
||||||
let top_color = style.resolve_color(style.get_border().border_top_color);
|
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 right_color = style.resolve_color(style.get_border().border_right_color);
|
||||||
let bottom_color = style.resolve_color(style.get_border().border_bottom_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.
|
// Append the border to the display list.
|
||||||
let border_display_item = box BorderDisplayItem {
|
let border_display_item = box BorderDisplayItem {
|
||||||
base: BaseDisplayItem::new(*abs_bounds, self.node, level),
|
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(),
|
color: SideOffsets2D::new(top_color.to_gfx_color(),
|
||||||
right_color.to_gfx_color(),
|
right_color.to_gfx_color(),
|
||||||
bottom_color.to_gfx_color(),
|
bottom_color.to_gfx_color(),
|
||||||
|
@ -922,9 +921,22 @@ impl Fragment {
|
||||||
// Add a border, if applicable.
|
// Add a border, if applicable.
|
||||||
//
|
//
|
||||||
// TODO: Outlines.
|
// TODO: Outlines.
|
||||||
self.build_display_list_for_borders_if_applicable(display_list,
|
match self.inline_context {
|
||||||
&absolute_fragment_bounds,
|
Some(ref inline_context) => {
|
||||||
level);
|
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();
|
let content_box = self.content_box();
|
||||||
|
|
|
@ -219,7 +219,7 @@ impl Au {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn from_pt(pt: f64) -> Au {
|
pub fn from_pt(pt: f64) -> Au {
|
||||||
from_px(pt_to_px(pt) as int)
|
from_frac_px(pt_to_px(pt))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
|
|
@ -73,6 +73,11 @@ pub struct Opts {
|
||||||
/// True if we should show borders on all layers and tiles for
|
/// True if we should show borders on all layers and tiles for
|
||||||
/// debugging purposes (`--show-debug-borders`).
|
/// debugging purposes (`--show-debug-borders`).
|
||||||
pub show_debug_borders: bool,
|
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]) {
|
fn print_usage(app: &str, opts: &[getopts::OptGroup]) {
|
||||||
|
@ -105,6 +110,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("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("b", "bubble-widths", "Bubble intrinsic widths separately like other engines"),
|
||||||
getopts::optflag("", "show-debug-borders", "Show debugging borders on layers and tiles."),
|
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")
|
getopts::optflag("h", "help", "Print this message")
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -194,6 +200,7 @@ pub fn from_cmdline_args(args: &[String]) -> Option<Opts> {
|
||||||
hard_fail: opt_match.opt_present("f"),
|
hard_fail: opt_match.opt_present("f"),
|
||||||
bubble_inline_sizes_separately: opt_match.opt_present("b"),
|
bubble_inline_sizes_separately: opt_match.opt_present("b"),
|
||||||
show_debug_borders: opt_match.opt_present("show-debug-borders"),
|
show_debug_borders: opt_match.opt_present("show-debug-borders"),
|
||||||
|
enable_text_antialiasing: !opt_match.opt_present("disable-text-aa"),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -219,6 +219,8 @@ fn capture(reftest: &Reftest, side: uint) -> (u32, u32, Vec<u8>) {
|
||||||
if reftest.experimental {
|
if reftest.experimental {
|
||||||
args.push("--experimental".to_string());
|
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(),
|
args.push_all(["-f".to_string(), "-o".to_string(), filename.clone(),
|
||||||
reftest.files[side].clone()]);
|
reftest.files[side].clone()]);
|
||||||
|
|
||||||
|
|
|
@ -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
|
flaky_gpu,flaky_linux == acid2_noscroll.html acid2_ref_broken.html
|
||||||
|
|
||||||
!= inline_background_a.html inline_background_ref.html
|
!= inline_background_a.html inline_background_ref.html
|
||||||
|
== inline_element_border_a.html inline_element_border_ref.html
|
||||||
|
|
24
src/test/ref/inline_element_border_a.html
Normal file
24
src/test/ref/inline_element_border_a.html
Normal 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>
|
29
src/test/ref/inline_element_border_ref.html
Normal file
29
src/test/ref/inline_element_border_ref.html
Normal 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>
|
Loading…
Add table
Add a link
Reference in a new issue