auto merge of #4952 : bjwbell/servo/borders-txt-nodes, r=pcwalton

Inline fragments that are part of a text run don't have interior borders.
So don't draw interior borders or include them when calculating positioning.

Fixes https://github.com/servo/servo/issues/4658, where multiple text nodes that are adjacent have distinct borders.

r? @Ms2ger, @pcwalton
This commit is contained in:
bors-servo 2015-02-27 16:57:53 -07:00
commit b2f099026a
6 changed files with 74 additions and 9 deletions

View file

@ -195,14 +195,17 @@ impl InlineFragmentsAccumulator {
mut fragments,
enclosing_style
} = self;
if let Some(enclosing_style) = enclosing_style {
let frag_len = fragments.len();
for (idx, frag) in fragments.iter_mut().enumerate() {
match enclosing_style {
Some(enclosing_style) => {
for frag in fragments.iter_mut() {
frag.add_inline_context_style(enclosing_style.clone());
}
// frag is first inline fragment in the inline node
let is_first = idx == 0;
// frag is the last inline fragment in the inline node
let is_last = idx == frag_len - 1;
frag.add_inline_context_style(enclosing_style.clone(), is_first, is_last);
}
None => {}
}
fragments
}

View file

@ -23,6 +23,7 @@ use text;
use util::OpaqueNodeMethods;
use wrapper::{TLayoutNode, ThreadSafeLayoutNode};
use geom::num::Zero;
use geom::{Point2D, Rect, Size2D};
use gfx::display_list::{BOX_SHADOW_INFLATION_FACTOR, OpaqueNode};
use gfx::text::glyph::CharIndex;
@ -46,7 +47,7 @@ use std::str::FromStr;
use std::sync::{Arc, Mutex};
use std::sync::mpsc::Sender;
use string_cache::Atom;
use style::properties::{ComputedValues, cascade_anonymous};
use style::properties::{ComputedValues, cascade_anonymous, make_border};
use style::node::{TElement, TNode};
use style::values::computed::{LengthOrPercentage, LengthOrPercentageOrAuto, LengthOrPercentageOrNone};
use style::computed_values::{clear, mix_blend_mode, overflow_wrap};
@ -877,11 +878,31 @@ impl Fragment {
/// Adds a style to the inline context for this fragment. If the inline
/// context doesn't exist yet, it will be created.
pub fn add_inline_context_style(&mut self, style: Arc<ComputedValues>) {
pub fn add_inline_context_style(&mut self,
style: Arc<ComputedValues>,
first_frag: bool,
last_frag: bool) {
if self.inline_context.is_none() {
self.inline_context = Some(InlineFragmentContext::new());
}
self.inline_context.as_mut().unwrap().styles.push(style.clone());
let frag_style = if first_frag && last_frag {
style.clone()
} else {
// Set the border width to zero and the border style to none on
// border sides that are not the outermost for a node container.
// Because with multiple inline fragments they don't have interior
// borders separating each other.
let mut border_width = style.logical_border_width();
if !last_frag {
border_width.set_right(style.writing_mode, Zero::zero());
}
if !first_frag {
border_width.set_left(style.writing_mode, Zero::zero());
}
Arc::new(make_border(&*style, border_width))
};
self.inline_context.as_mut().unwrap().styles.push(frag_style);
}
/// Determines which quantities (border/padding/margin/specified) should be included in the

View file

@ -17,6 +17,7 @@ use util::geometry::Au;
use url::Url;
use cssparser::{Parser, Color, RGBA, AtRuleParser, DeclarationParser,
DeclarationListParser, parse_important, ToCss};
use geom::num::Zero;
use geom::SideOffsets2D;
use values::specified::BorderStyle;
@ -3534,6 +3535,21 @@ pub fn make_inline(style: &ComputedValues) -> ComputedValues {
style
}
/// Sets `border_${side}_width` to the passed in values.
/// If `border_${side}_width` == 0 also sets `border_${side}_style` = none.
#[inline]
pub fn make_border(style: &ComputedValues, border_width: LogicalMargin<Au>) -> ComputedValues {
let mut style = (*style).clone();
let physical_border = LogicalMargin::to_physical(&border_width, style.writing_mode);
% for side in ["top", "right", "bottom", "left"]:
style.border.make_unique().border_${side}_width = physical_border.${side};
if physical_border.${side} == Zero::zero() {
style.border.make_unique().border_${side}_style = BorderStyle::none;
}
% endfor
style
}
pub fn is_supported_property(property: &str) -> bool {
match property {
% for property in SHORTHANDS + LONGHANDS:

View file

@ -31,6 +31,7 @@
== img_dynamic_remove.html img_dynamic_remove_ref.html
== upper_id_attr.html upper_id_attr_ref.html
# inline_border_a.html inline_border_b.html
== border_code_tag.html border_code_tag_ref.html
== anon_block_inherit_a.html anon_block_inherit_b.html
== attr_exists_selector.html attr_exists_selector_ref.html
== attr_selector_case_sensitivity.html attr_selector_case_sensitivity_ref.html

View file

@ -0,0 +1,12 @@
<html>
<head>
<style>
code {
border: 2px solid #ccc;
}
</style>
</head>
<body>
<code>Quotes: &quot;&quot;.</code>
</body>
</html>

View file

@ -0,0 +1,12 @@
<html>
<head>
<style>
code {
border: 2px solid #ccc;
}
</style>
</head>
<body>
<code>Quotes: "".</code>
</body>
</html>