mirror of
https://github.com/servo/servo.git
synced 2025-08-03 04:30:10 +01:00
Remove usage of unstable feature box_patterns
This commit is contained in:
parent
e13ae77daf
commit
11bd81e115
3 changed files with 170 additions and 139 deletions
|
@ -21,7 +21,7 @@ use flow::{BaseFlow, Flow, IS_ABSOLUTELY_POSITIONED};
|
|||
use flow_ref::FlowRef;
|
||||
use fnv::FnvHashMap;
|
||||
use fragment::{CanvasFragmentSource, CoordinateSystem, Fragment, ImageFragmentInfo, ScannedTextFragmentInfo};
|
||||
use fragment::{SpecificFragmentInfo, TruncatedFragmentInfo};
|
||||
use fragment::SpecificFragmentInfo;
|
||||
use gfx::display_list;
|
||||
use gfx::display_list::{BLUR_INFLATION_FACTOR, BaseDisplayItem, BorderDetails, BorderDisplayItem};
|
||||
use gfx::display_list::{BorderRadii, BoxShadowClipMode, BoxShadowDisplayItem, ClipScrollNode};
|
||||
|
@ -2012,14 +2012,12 @@ impl FragmentDisplayListBuilding for Fragment {
|
|||
};
|
||||
|
||||
match self.specific {
|
||||
SpecificFragmentInfo::TruncatedFragment(box TruncatedFragmentInfo {
|
||||
text_info: Some(ref text_fragment),
|
||||
..
|
||||
}) |
|
||||
SpecificFragmentInfo::ScannedText(box ref text_fragment) => {
|
||||
SpecificFragmentInfo::TruncatedFragment(ref truncated_fragment)
|
||||
if truncated_fragment.text_info.is_some() => {
|
||||
let text_fragment = truncated_fragment.text_info.as_ref().unwrap();
|
||||
// Create the main text display item.
|
||||
self.build_display_list_for_text_fragment(state,
|
||||
&*text_fragment,
|
||||
&text_fragment,
|
||||
&stacking_relative_content_box,
|
||||
&self.style.get_inheritedtext().text_shadow.0,
|
||||
clip);
|
||||
|
@ -2029,7 +2027,24 @@ impl FragmentDisplayListBuilding for Fragment {
|
|||
self.style(),
|
||||
stacking_relative_border_box,
|
||||
&stacking_relative_content_box,
|
||||
&*text_fragment,
|
||||
&text_fragment,
|
||||
clip);
|
||||
}
|
||||
}
|
||||
SpecificFragmentInfo::ScannedText(ref text_fragment) => {
|
||||
// Create the main text display item.
|
||||
self.build_display_list_for_text_fragment(state,
|
||||
&text_fragment,
|
||||
&stacking_relative_content_box,
|
||||
&self.style.get_inheritedtext().text_shadow.0,
|
||||
clip);
|
||||
|
||||
if opts::get().show_debug_fragment_borders {
|
||||
self.build_debug_borders_around_text_fragments(state,
|
||||
self.style(),
|
||||
stacking_relative_border_box,
|
||||
&stacking_relative_content_box,
|
||||
&text_fragment,
|
||||
clip);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1460,8 +1460,10 @@ impl Fragment {
|
|||
/// Returns true if and only if this fragment is a generated content fragment.
|
||||
pub fn is_unscanned_generated_content(&self) -> bool {
|
||||
match self.specific {
|
||||
SpecificFragmentInfo::GeneratedContent(box GeneratedContentInfo::Empty) => false,
|
||||
SpecificFragmentInfo::GeneratedContent(..) => true,
|
||||
SpecificFragmentInfo::GeneratedContent(ref content) => match **content {
|
||||
GeneratedContentInfo::Empty => false,
|
||||
_ => true,
|
||||
},
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
@ -1536,41 +1538,45 @@ impl Fragment {
|
|||
});
|
||||
}
|
||||
|
||||
SpecificFragmentInfo::TruncatedFragment(box TruncatedFragmentInfo {
|
||||
text_info: Some(ref text_fragment_info),
|
||||
..
|
||||
}) |
|
||||
SpecificFragmentInfo::ScannedText(box ref text_fragment_info) => {
|
||||
let range = &text_fragment_info.range;
|
||||
|
||||
// See http://dev.w3.org/csswg/css-sizing/#max-content-inline-size.
|
||||
// TODO: Account for soft wrap opportunities.
|
||||
let max_line_inline_size = text_fragment_info.run
|
||||
.metrics_for_range(range)
|
||||
.advance_width;
|
||||
|
||||
let min_line_inline_size = if self.white_space().allow_wrap() {
|
||||
text_fragment_info.run.min_width_for_range(range)
|
||||
} else {
|
||||
max_line_inline_size
|
||||
};
|
||||
|
||||
result.union_block(&IntrinsicISizes {
|
||||
minimum_inline_size: min_line_inline_size,
|
||||
preferred_inline_size: max_line_inline_size,
|
||||
})
|
||||
SpecificFragmentInfo::TruncatedFragment(ref t) if t.text_info.is_some() => {
|
||||
let text_fragment_info = t.text_info.as_ref().unwrap();
|
||||
handle_text(text_fragment_info, self, &mut result)
|
||||
}
|
||||
SpecificFragmentInfo::ScannedText(ref text_fragment_info) => {
|
||||
handle_text(text_fragment_info, self, &mut result)
|
||||
}
|
||||
|
||||
SpecificFragmentInfo::TruncatedFragment(box TruncatedFragmentInfo {
|
||||
text_info: None,
|
||||
..
|
||||
}) => return IntrinsicISizesContribution::new(),
|
||||
SpecificFragmentInfo::TruncatedFragment(_) => {
|
||||
return IntrinsicISizesContribution::new()
|
||||
}
|
||||
|
||||
SpecificFragmentInfo::UnscannedText(..) => {
|
||||
panic!("Unscanned text fragments should have been scanned by now!")
|
||||
}
|
||||
};
|
||||
|
||||
fn handle_text(text_fragment_info: &ScannedTextFragmentInfo, self_: &Fragment,
|
||||
result: &mut IntrinsicISizesContribution) {
|
||||
let range = &text_fragment_info.range;
|
||||
|
||||
// See http://dev.w3.org/csswg/css-sizing/#max-content-inline-size.
|
||||
// TODO: Account for soft wrap opportunities.
|
||||
let max_line_inline_size = text_fragment_info.run
|
||||
.metrics_for_range(range)
|
||||
.advance_width;
|
||||
|
||||
let min_line_inline_size = if self_.white_space().allow_wrap() {
|
||||
text_fragment_info.run.min_width_for_range(range)
|
||||
} else {
|
||||
max_line_inline_size
|
||||
};
|
||||
|
||||
result.union_block(&IntrinsicISizes {
|
||||
minimum_inline_size: min_line_inline_size,
|
||||
preferred_inline_size: max_line_inline_size,
|
||||
})
|
||||
}
|
||||
|
||||
// Take borders and padding for parent inline fragments into account.
|
||||
let writing_mode = self.style.writing_mode;
|
||||
if let Some(ref context) = self.inline_context {
|
||||
|
@ -1605,11 +1611,11 @@ impl Fragment {
|
|||
/// this fragment.)
|
||||
pub fn minimum_splittable_inline_size(&self) -> Au {
|
||||
match self.specific {
|
||||
SpecificFragmentInfo::TruncatedFragment(box TruncatedFragmentInfo {
|
||||
text_info: Some(ref text),
|
||||
..
|
||||
}) |
|
||||
SpecificFragmentInfo::ScannedText(box ref text) => {
|
||||
SpecificFragmentInfo::TruncatedFragment(ref t) if t.text_info.is_some() => {
|
||||
let text = t.text_info.as_ref().unwrap();
|
||||
text.run.minimum_splittable_inline_size(&text.range)
|
||||
}
|
||||
SpecificFragmentInfo::ScannedText(ref text) => {
|
||||
text.run.minimum_splittable_inline_size(&text.range)
|
||||
}
|
||||
_ => Au(0),
|
||||
|
@ -1914,10 +1920,7 @@ impl Fragment {
|
|||
container_inline_size: Au,
|
||||
container_block_size: Option<Au>) {
|
||||
match self.specific {
|
||||
SpecificFragmentInfo::TruncatedFragment(box TruncatedFragmentInfo {
|
||||
text_info: None,
|
||||
..
|
||||
}) |
|
||||
SpecificFragmentInfo::TruncatedFragment(ref t) if t.text_info.is_none() => return,
|
||||
SpecificFragmentInfo::Generic |
|
||||
SpecificFragmentInfo::GeneratedContent(_) |
|
||||
SpecificFragmentInfo::Table |
|
||||
|
@ -1971,11 +1974,14 @@ impl Fragment {
|
|||
}
|
||||
|
||||
// Text
|
||||
SpecificFragmentInfo::TruncatedFragment(box TruncatedFragmentInfo {
|
||||
text_info: Some(ref info),
|
||||
..
|
||||
}) |
|
||||
SpecificFragmentInfo::ScannedText(box ref info) => {
|
||||
SpecificFragmentInfo::TruncatedFragment(ref t) if t.text_info.is_some() => {
|
||||
let info = t.text_info.as_ref().unwrap();
|
||||
// Scanned text fragments will have already had their content inline-sizes assigned
|
||||
// by this point.
|
||||
self.border_box.size.inline = info.content_size.inline +
|
||||
self.border_padding.inline_start_end();
|
||||
}
|
||||
SpecificFragmentInfo::ScannedText(ref info) => {
|
||||
// Scanned text fragments will have already had their content inline-sizes assigned
|
||||
// by this point.
|
||||
self.border_box.size.inline = info.content_size.inline +
|
||||
|
@ -2000,10 +2006,7 @@ impl Fragment {
|
|||
/// Ideally, this should follow CSS 2.1 § 10.6.2.
|
||||
pub fn assign_replaced_block_size_if_necessary(&mut self) {
|
||||
match self.specific {
|
||||
SpecificFragmentInfo::TruncatedFragment(box TruncatedFragmentInfo {
|
||||
text_info: None,
|
||||
..
|
||||
}) |
|
||||
SpecificFragmentInfo::TruncatedFragment(ref t) if t.text_info.is_none() => return,
|
||||
SpecificFragmentInfo::Generic |
|
||||
SpecificFragmentInfo::GeneratedContent(_) |
|
||||
SpecificFragmentInfo::Table |
|
||||
|
@ -2025,20 +2028,20 @@ impl Fragment {
|
|||
SpecificFragmentInfo::InlineAbsoluteHypothetical(_) |
|
||||
SpecificFragmentInfo::InlineAbsolute(_) |
|
||||
SpecificFragmentInfo::ScannedText(_) |
|
||||
SpecificFragmentInfo::TruncatedFragment(box TruncatedFragmentInfo {
|
||||
text_info: Some(_),
|
||||
..
|
||||
}) |
|
||||
SpecificFragmentInfo::TruncatedFragment(_) |
|
||||
SpecificFragmentInfo::Svg(_) => {}
|
||||
}
|
||||
|
||||
match self.specific {
|
||||
// Text
|
||||
SpecificFragmentInfo::TruncatedFragment(box TruncatedFragmentInfo {
|
||||
text_info: Some(ref info),
|
||||
..
|
||||
}) |
|
||||
SpecificFragmentInfo::ScannedText(box ref info) => {
|
||||
SpecificFragmentInfo::TruncatedFragment(ref t) if t.text_info.is_some() => {
|
||||
let info = t.text_info.as_ref().unwrap();
|
||||
// Scanned text fragments' content block-sizes are calculated by the text run
|
||||
// scanner during flow construction.
|
||||
self.border_box.size.block = info.content_size.block +
|
||||
self.border_padding.block_start_end();
|
||||
}
|
||||
SpecificFragmentInfo::ScannedText(ref info) => {
|
||||
// Scanned text fragments' content block-sizes are calculated by the text run
|
||||
// scanner during flow construction.
|
||||
self.border_box.size.block = info.content_size.block +
|
||||
|
@ -2115,22 +2118,12 @@ impl Fragment {
|
|||
ascent: ascent,
|
||||
}
|
||||
}
|
||||
SpecificFragmentInfo::TruncatedFragment(box TruncatedFragmentInfo {
|
||||
text_info: Some(ref info),
|
||||
..
|
||||
}) |
|
||||
SpecificFragmentInfo::ScannedText(box ref info) => {
|
||||
// Fragments with no glyphs don't contribute any inline metrics.
|
||||
// TODO: Filter out these fragments during flow construction?
|
||||
if info.insertion_point.is_none() && info.content_size.inline == Au(0) {
|
||||
return InlineMetrics::new(Au(0), Au(0), Au(0));
|
||||
}
|
||||
// See CSS 2.1 § 10.8.1.
|
||||
let font_metrics = with_thread_local_font_context(layout_context, |font_context| {
|
||||
text::font_metrics_for_style(font_context, self.style.clone_font())
|
||||
});
|
||||
let line_height = text::line_height_from_style(&*self.style, &font_metrics);
|
||||
InlineMetrics::from_font_metrics(&info.run.font_metrics, line_height)
|
||||
SpecificFragmentInfo::TruncatedFragment(ref t) if t.text_info.is_some() => {
|
||||
let info = t.text_info.as_ref().unwrap();
|
||||
inline_metrics_of_text(info, self, layout_context)
|
||||
}
|
||||
SpecificFragmentInfo::ScannedText(ref info) => {
|
||||
inline_metrics_of_text(info, self, layout_context)
|
||||
}
|
||||
SpecificFragmentInfo::InlineBlock(ref info) => {
|
||||
inline_metrics_of_block(&info.flow_ref, &*self.style)
|
||||
|
@ -2138,10 +2131,7 @@ impl Fragment {
|
|||
SpecificFragmentInfo::InlineAbsoluteHypothetical(ref info) => {
|
||||
inline_metrics_of_block(&info.flow_ref, &*self.style)
|
||||
}
|
||||
SpecificFragmentInfo::TruncatedFragment(box TruncatedFragmentInfo {
|
||||
text_info: None,
|
||||
..
|
||||
}) |
|
||||
SpecificFragmentInfo::TruncatedFragment(..) |
|
||||
SpecificFragmentInfo::InlineAbsolute(_) => {
|
||||
InlineMetrics::new(Au(0), Au(0), Au(0))
|
||||
}
|
||||
|
@ -2158,6 +2148,21 @@ impl Fragment {
|
|||
};
|
||||
return inline_metrics;
|
||||
|
||||
fn inline_metrics_of_text(info: &ScannedTextFragmentInfo, self_: &Fragment,
|
||||
layout_context: &LayoutContext) -> InlineMetrics {
|
||||
// Fragments with no glyphs don't contribute any inline metrics.
|
||||
// TODO: Filter out these fragments during flow construction?
|
||||
if info.insertion_point.is_none() && info.content_size.inline == Au(0) {
|
||||
return InlineMetrics::new(Au(0), Au(0), Au(0));
|
||||
}
|
||||
// See CSS 2.1 § 10.8.1.
|
||||
let font_metrics = with_thread_local_font_context(layout_context, |font_context| {
|
||||
text::font_metrics_for_style(font_context, self_.style.clone_font())
|
||||
});
|
||||
let line_height = text::line_height_from_style(&*self_.style, &font_metrics);
|
||||
InlineMetrics::from_font_metrics(&info.run.font_metrics, line_height)
|
||||
}
|
||||
|
||||
fn inline_metrics_of_block(flow: &FlowRef, style: &ComputedValues) -> InlineMetrics {
|
||||
// CSS 2.1 § 10.8: "The height of each inline-level box in the line box is calculated.
|
||||
// For replaced elements, inline-block elements, and inline-table elements, this is the
|
||||
|
@ -2612,12 +2617,12 @@ impl Fragment {
|
|||
|
||||
pub fn requires_line_break_afterward_if_wrapping_on_newlines(&self) -> bool {
|
||||
match self.specific {
|
||||
SpecificFragmentInfo::TruncatedFragment(box TruncatedFragmentInfo {
|
||||
text_info: Some(ref scanned_text),
|
||||
..
|
||||
}) |
|
||||
SpecificFragmentInfo::ScannedText(box ref scanned_text) => {
|
||||
scanned_text.requires_line_break_afterward_if_wrapping_on_newlines()
|
||||
SpecificFragmentInfo::TruncatedFragment(ref t) if t.text_info.is_some() => {
|
||||
let text = t.text_info.as_ref().unwrap();
|
||||
text.requires_line_break_afterward_if_wrapping_on_newlines()
|
||||
}
|
||||
SpecificFragmentInfo::ScannedText(ref text) => {
|
||||
text.requires_line_break_afterward_if_wrapping_on_newlines()
|
||||
}
|
||||
_ => false,
|
||||
}
|
||||
|
@ -2628,28 +2633,13 @@ impl Fragment {
|
|||
return WhitespaceStrippingResult::RetainFragment
|
||||
}
|
||||
|
||||
match self.specific {
|
||||
SpecificFragmentInfo::TruncatedFragment(box TruncatedFragmentInfo {
|
||||
text_info: Some(ref mut scanned_text_fragment_info),
|
||||
..
|
||||
}) |
|
||||
SpecificFragmentInfo::ScannedText(box ref mut scanned_text_fragment_info) => {
|
||||
let leading_whitespace_byte_count = scanned_text_fragment_info.text()
|
||||
.find(|c| !char_is_whitespace(c))
|
||||
.unwrap_or(scanned_text_fragment_info.text().len());
|
||||
|
||||
let whitespace_len = ByteIndex(leading_whitespace_byte_count as isize);
|
||||
let whitespace_range = Range::new(scanned_text_fragment_info.range.begin(),
|
||||
whitespace_len);
|
||||
let text_bounds =
|
||||
scanned_text_fragment_info.run.metrics_for_range(&whitespace_range).bounding_box;
|
||||
self.border_box.size.inline = self.border_box.size.inline - text_bounds.size.width;
|
||||
scanned_text_fragment_info.content_size.inline =
|
||||
scanned_text_fragment_info.content_size.inline - text_bounds.size.width;
|
||||
|
||||
scanned_text_fragment_info.range.adjust_by(whitespace_len, -whitespace_len);
|
||||
|
||||
WhitespaceStrippingResult::RetainFragment
|
||||
return match self.specific {
|
||||
SpecificFragmentInfo::TruncatedFragment(ref mut t) if t.text_info.is_some() => {
|
||||
let scanned_text_fragment_info = t.text_info.as_mut().unwrap();
|
||||
scanned_text(scanned_text_fragment_info, &mut self.border_box)
|
||||
}
|
||||
SpecificFragmentInfo::ScannedText(ref mut scanned_text_fragment_info) => {
|
||||
scanned_text(scanned_text_fragment_info, &mut self.border_box)
|
||||
}
|
||||
SpecificFragmentInfo::UnscannedText(ref mut unscanned_text_fragment_info) => {
|
||||
let mut new_text_string = String::new();
|
||||
|
@ -2677,6 +2667,27 @@ impl Fragment {
|
|||
&unscanned_text_fragment_info)
|
||||
}
|
||||
_ => WhitespaceStrippingResult::RetainFragment,
|
||||
};
|
||||
|
||||
fn scanned_text(scanned_text_fragment_info: &mut ScannedTextFragmentInfo,
|
||||
border_box: &mut LogicalRect<Au>)
|
||||
-> WhitespaceStrippingResult {
|
||||
let leading_whitespace_byte_count = scanned_text_fragment_info.text()
|
||||
.find(|c| !char_is_whitespace(c))
|
||||
.unwrap_or(scanned_text_fragment_info.text().len());
|
||||
|
||||
let whitespace_len = ByteIndex(leading_whitespace_byte_count as isize);
|
||||
let whitespace_range = Range::new(scanned_text_fragment_info.range.begin(),
|
||||
whitespace_len);
|
||||
let text_bounds =
|
||||
scanned_text_fragment_info.run.metrics_for_range(&whitespace_range).bounding_box;
|
||||
border_box.size.inline = border_box.size.inline - text_bounds.size.width;
|
||||
scanned_text_fragment_info.content_size.inline =
|
||||
scanned_text_fragment_info.content_size.inline - text_bounds.size.width;
|
||||
|
||||
scanned_text_fragment_info.range.adjust_by(whitespace_len, -whitespace_len);
|
||||
|
||||
WhitespaceStrippingResult::RetainFragment
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2686,32 +2697,13 @@ impl Fragment {
|
|||
return WhitespaceStrippingResult::RetainFragment
|
||||
}
|
||||
|
||||
match self.specific {
|
||||
SpecificFragmentInfo::TruncatedFragment(box TruncatedFragmentInfo {
|
||||
text_info: Some(ref mut scanned_text_fragment_info),
|
||||
..
|
||||
}) |
|
||||
SpecificFragmentInfo::ScannedText(box ref mut scanned_text_fragment_info) => {
|
||||
let mut trailing_whitespace_start_byte = 0;
|
||||
for (i, c) in scanned_text_fragment_info.text().char_indices().rev() {
|
||||
if !char_is_whitespace(c) {
|
||||
trailing_whitespace_start_byte = i + c.len_utf8();
|
||||
break;
|
||||
}
|
||||
}
|
||||
let whitespace_start = ByteIndex(trailing_whitespace_start_byte as isize);
|
||||
let whitespace_len = scanned_text_fragment_info.range.length() - whitespace_start;
|
||||
let mut whitespace_range = Range::new(whitespace_start, whitespace_len);
|
||||
whitespace_range.shift_by(scanned_text_fragment_info.range.begin());
|
||||
|
||||
let text_bounds = scanned_text_fragment_info.run
|
||||
.metrics_for_range(&whitespace_range)
|
||||
.bounding_box;
|
||||
self.border_box.size.inline -= text_bounds.size.width;
|
||||
scanned_text_fragment_info.content_size.inline -= text_bounds.size.width;
|
||||
|
||||
scanned_text_fragment_info.range.extend_by(-whitespace_len);
|
||||
WhitespaceStrippingResult::RetainFragment
|
||||
return match self.specific {
|
||||
SpecificFragmentInfo::TruncatedFragment(ref mut t) if t.text_info.is_some() => {
|
||||
let scanned_text_fragment_info = t.text_info.as_mut().unwrap();
|
||||
scanned_text(scanned_text_fragment_info, &mut self.border_box)
|
||||
}
|
||||
SpecificFragmentInfo::ScannedText(ref mut scanned_text_fragment_info) => {
|
||||
scanned_text(scanned_text_fragment_info, &mut self.border_box)
|
||||
}
|
||||
SpecificFragmentInfo::UnscannedText(ref mut unscanned_text_fragment_info) => {
|
||||
let mut trailing_bidi_control_characters_to_retain = Vec::new();
|
||||
|
@ -2741,6 +2733,31 @@ impl Fragment {
|
|||
&unscanned_text_fragment_info)
|
||||
}
|
||||
_ => WhitespaceStrippingResult::RetainFragment,
|
||||
};
|
||||
|
||||
fn scanned_text(scanned_text_fragment_info: &mut ScannedTextFragmentInfo,
|
||||
border_box: &mut LogicalRect<Au>)
|
||||
-> WhitespaceStrippingResult {
|
||||
let mut trailing_whitespace_start_byte = 0;
|
||||
for (i, c) in scanned_text_fragment_info.text().char_indices().rev() {
|
||||
if !char_is_whitespace(c) {
|
||||
trailing_whitespace_start_byte = i + c.len_utf8();
|
||||
break;
|
||||
}
|
||||
}
|
||||
let whitespace_start = ByteIndex(trailing_whitespace_start_byte as isize);
|
||||
let whitespace_len = scanned_text_fragment_info.range.length() - whitespace_start;
|
||||
let mut whitespace_range = Range::new(whitespace_start, whitespace_len);
|
||||
whitespace_range.shift_by(scanned_text_fragment_info.range.begin());
|
||||
|
||||
let text_bounds = scanned_text_fragment_info.run
|
||||
.metrics_for_range(&whitespace_range)
|
||||
.bounding_box;
|
||||
border_box.size.inline -= text_bounds.size.width;
|
||||
scanned_text_fragment_info.content_size.inline -= text_bounds.size.width;
|
||||
|
||||
scanned_text_fragment_info.range.extend_by(-whitespace_len);
|
||||
WhitespaceStrippingResult::RetainFragment
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#![deny(unsafe_code)]
|
||||
#![feature(box_patterns)]
|
||||
|
||||
extern crate app_units;
|
||||
extern crate atomic_refcell;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue