mirror of
https://github.com/servo/servo.git
synced 2025-07-24 15:50:21 +01:00
Remove interior borders during flow construction
Instead of looking at the boundaries of the text run, set the border width to zero and the border style to none on border sides that are not the outermost for a node container that is display: inline.
This commit is contained in:
parent
8ad3c5aeb6
commit
ec2fa2558c
6 changed files with 74 additions and 9 deletions
|
@ -195,15 +195,18 @@ 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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
12
tests/ref/border_code_tag.html
Normal file
12
tests/ref/border_code_tag.html
Normal file
|
@ -0,0 +1,12 @@
|
|||
<html>
|
||||
<head>
|
||||
<style>
|
||||
code {
|
||||
border: 2px solid #ccc;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<code>Quotes: "".</code>
|
||||
</body>
|
||||
</html>
|
12
tests/ref/border_code_tag_ref.html
Normal file
12
tests/ref/border_code_tag_ref.html
Normal file
|
@ -0,0 +1,12 @@
|
|||
<html>
|
||||
<head>
|
||||
<style>
|
||||
code {
|
||||
border: 2px solid #ccc;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<code>Quotes: "".</code>
|
||||
</body>
|
||||
</html>
|
Loading…
Add table
Add a link
Reference in a new issue