mirror of
https://github.com/servo/servo.git
synced 2025-08-03 20:50:07 +01:00
Auto merge of #5805 - pcwalton:whitespace-effect-on-minimum-inline-sizes, r=glennw
Improves Amazon. r? @glennw <!-- Reviewable:start --> [<img src="https://reviewable.io/review_button.png" height=40 alt="Review on Reviewable"/>](https://reviewable.io/reviews/servo/servo/5805) <!-- Reviewable:end -->
This commit is contained in:
commit
68f03c9dbb
5 changed files with 154 additions and 7 deletions
|
@ -16,8 +16,7 @@ use flow_ref::FlowRef;
|
||||||
use incremental::{self, RestyleDamage};
|
use incremental::{self, RestyleDamage};
|
||||||
use inline::{InlineFragmentContext, InlineMetrics};
|
use inline::{InlineFragmentContext, InlineMetrics};
|
||||||
use layout_debug;
|
use layout_debug;
|
||||||
use model::{IntrinsicISizes, IntrinsicISizesContribution, MaybeAuto, specified};
|
use model::{self, IntrinsicISizes, IntrinsicISizesContribution, MaybeAuto, specified};
|
||||||
use model;
|
|
||||||
use text;
|
use text;
|
||||||
use opaque_node::OpaqueNodeMethods;
|
use opaque_node::OpaqueNodeMethods;
|
||||||
use wrapper::{TLayoutNode, ThreadSafeLayoutNode};
|
use wrapper::{TLayoutNode, ThreadSafeLayoutNode};
|
||||||
|
@ -1200,7 +1199,6 @@ impl Fragment {
|
||||||
}
|
}
|
||||||
SpecificFragmentInfo::ScannedText(ref text_fragment_info) => {
|
SpecificFragmentInfo::ScannedText(ref text_fragment_info) => {
|
||||||
let range = &text_fragment_info.range;
|
let range = &text_fragment_info.range;
|
||||||
let min_line_inline_size = text_fragment_info.run.min_width_for_range(range);
|
|
||||||
|
|
||||||
// See http://dev.w3.org/csswg/css-sizing/#max-content-inline-size.
|
// See http://dev.w3.org/csswg/css-sizing/#max-content-inline-size.
|
||||||
// TODO: Account for soft wrap opportunities.
|
// TODO: Account for soft wrap opportunities.
|
||||||
|
@ -1208,6 +1206,11 @@ impl Fragment {
|
||||||
.metrics_for_range(range)
|
.metrics_for_range(range)
|
||||||
.advance_width;
|
.advance_width;
|
||||||
|
|
||||||
|
let min_line_inline_size = match self.style.get_inheritedtext().white_space {
|
||||||
|
white_space::T::pre | white_space::T::nowrap => max_line_inline_size,
|
||||||
|
white_space::T::normal => text_fragment_info.run.min_width_for_range(range),
|
||||||
|
};
|
||||||
|
|
||||||
result.union_block(&IntrinsicISizes {
|
result.union_block(&IntrinsicISizes {
|
||||||
minimum_inline_size: min_line_inline_size,
|
minimum_inline_size: min_line_inline_size,
|
||||||
preferred_inline_size: max_line_inline_size,
|
preferred_inline_size: max_line_inline_size,
|
||||||
|
|
|
@ -1133,12 +1133,49 @@ impl Flow for InlineFlow {
|
||||||
flow::mut_base(kid).floats = Floats::new(writing_mode);
|
flow::mut_base(kid).floats = Floats::new(writing_mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut computation = IntrinsicISizesContribution::new();
|
let mut intrinsic_sizes_for_flow = IntrinsicISizesContribution::new();
|
||||||
|
let mut intrinsic_sizes_for_inline_run = IntrinsicISizesContribution::new();
|
||||||
|
let mut intrinsic_sizes_for_nonbroken_run = IntrinsicISizesContribution::new();
|
||||||
for fragment in self.fragments.fragments.iter_mut() {
|
for fragment in self.fragments.fragments.iter_mut() {
|
||||||
debug!("Flow: measuring {:?}", *fragment);
|
let intrinsic_sizes_for_fragment = fragment.compute_intrinsic_inline_sizes().finish();
|
||||||
computation.union_inline(&fragment.compute_intrinsic_inline_sizes().finish())
|
match fragment.style.get_inheritedtext().white_space {
|
||||||
|
white_space::T::nowrap => {
|
||||||
|
intrinsic_sizes_for_nonbroken_run.union_nonbreaking_inline(
|
||||||
|
&intrinsic_sizes_for_fragment)
|
||||||
|
}
|
||||||
|
white_space::T::pre => {
|
||||||
|
intrinsic_sizes_for_nonbroken_run.union_nonbreaking_inline(
|
||||||
|
&intrinsic_sizes_for_fragment);
|
||||||
|
|
||||||
|
// Flush the intrinsic sizes we've been gathering up in order to handle the
|
||||||
|
// line break, if necessary.
|
||||||
|
if fragment.requires_line_break_afterward_if_wrapping_on_newlines() {
|
||||||
|
intrinsic_sizes_for_inline_run.union_inline(
|
||||||
|
&intrinsic_sizes_for_nonbroken_run.finish());
|
||||||
|
intrinsic_sizes_for_nonbroken_run = IntrinsicISizesContribution::new();
|
||||||
|
intrinsic_sizes_for_flow.union_block(
|
||||||
|
&intrinsic_sizes_for_inline_run.finish());
|
||||||
|
intrinsic_sizes_for_inline_run = IntrinsicISizesContribution::new();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
white_space::T::normal => {
|
||||||
|
// Flush the intrinsic sizes we were gathering up for the nonbroken run, if
|
||||||
|
// necessary.
|
||||||
|
intrinsic_sizes_for_inline_run.union_inline(
|
||||||
|
&intrinsic_sizes_for_nonbroken_run.finish());
|
||||||
|
intrinsic_sizes_for_nonbroken_run = IntrinsicISizesContribution::new();
|
||||||
|
|
||||||
|
intrinsic_sizes_for_nonbroken_run.union_inline(&intrinsic_sizes_for_fragment)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
self.base.intrinsic_inline_sizes = computation.finish()
|
|
||||||
|
// Flush any remaining nonbroken-run and inline-run intrinsic sizes.
|
||||||
|
intrinsic_sizes_for_inline_run.union_inline(&intrinsic_sizes_for_nonbroken_run.finish());
|
||||||
|
intrinsic_sizes_for_flow.union_block(&intrinsic_sizes_for_inline_run.finish());
|
||||||
|
|
||||||
|
// Finish up the computation.
|
||||||
|
self.base.intrinsic_inline_sizes = intrinsic_sizes_for_flow.finish()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Recursively (top-down) determines the actual inline-size of child contexts and fragments.
|
/// Recursively (top-down) determines the actual inline-size of child contexts and fragments.
|
||||||
|
|
|
@ -331,6 +331,17 @@ impl IntrinsicISizesContribution {
|
||||||
self.content_intrinsic_sizes.preferred_inline_size + sizes.preferred_inline_size
|
self.content_intrinsic_sizes.preferred_inline_size + sizes.preferred_inline_size
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Updates the computation so that the minimum is the sum of the current minimum and the
|
||||||
|
/// given minimum and the preferred is the sum of the current preferred and the given
|
||||||
|
/// preferred. This is used when laying out fragments in the inline direction when
|
||||||
|
/// `white-space` is `pre` or `nowrap`.
|
||||||
|
pub fn union_nonbreaking_inline(&mut self, sizes: &IntrinsicISizes) {
|
||||||
|
self.content_intrinsic_sizes.minimum_inline_size =
|
||||||
|
self.content_intrinsic_sizes.minimum_inline_size + sizes.minimum_inline_size;
|
||||||
|
self.content_intrinsic_sizes.preferred_inline_size =
|
||||||
|
self.content_intrinsic_sizes.preferred_inline_size + sizes.preferred_inline_size
|
||||||
|
}
|
||||||
|
|
||||||
/// Updates the computation so that the minimum is the maximum of the current minimum and the
|
/// Updates the computation so that the minimum is the maximum of the current minimum and the
|
||||||
/// given minimum and the preferred is the maximum of the current preferred and the given
|
/// given minimum and the preferred is the maximum of the current preferred and the given
|
||||||
/// preferred. This can be useful when laying out fragments in the block direction (but note
|
/// preferred. This can be useful when laying out fragments in the block direction (but note
|
||||||
|
|
50
tests/ref/white_space_intrinsic_sizes_a.html
Normal file
50
tests/ref/white_space_intrinsic_sizes_a.html
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<style type="text/css">
|
||||||
|
table {
|
||||||
|
width: 0;
|
||||||
|
}
|
||||||
|
td {
|
||||||
|
border: solid black 1px;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<div>
|
||||||
|
<div>Instant Video</div>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td>
|
||||||
|
<div>
|
||||||
|
<div>Digital Music Store</div>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td>
|
||||||
|
<div>
|
||||||
|
<div>Cloud Drive</div>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td>
|
||||||
|
<div>
|
||||||
|
<div>Fire Phone</div>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td>
|
||||||
|
<div>
|
||||||
|
<div>Appstore<br>for Android</div>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</body>
|
||||||
|
</html>
|
46
tests/ref/white_space_intrinsic_sizes_ref.html
Normal file
46
tests/ref/white_space_intrinsic_sizes_ref.html
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<style type="text/css">
|
||||||
|
td {
|
||||||
|
border: solid black 1px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<div>
|
||||||
|
<div>Instant Video</div>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td>
|
||||||
|
<div>
|
||||||
|
<div>Digital Music Store</div>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td>
|
||||||
|
<div>
|
||||||
|
<div>Cloud Drive</div>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td>
|
||||||
|
<div>
|
||||||
|
<div>Fire Phone</div>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td>
|
||||||
|
<div>
|
||||||
|
<div><div>Appstore</div><div>for Android</div></div>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</body>
|
||||||
|
</html>
|
Loading…
Add table
Add a link
Reference in a new issue