mirror of
https://github.com/servo/servo.git
synced 2025-08-07 06:25:32 +01:00
Use iterators to make some logic clearer
This commit is contained in:
parent
54f01aa4f4
commit
a351710004
2 changed files with 45 additions and 58 deletions
|
@ -206,10 +206,9 @@ impl<'a> TextRun {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn range_is_trimmable_whitespace(&self, range: &Range<CharIndex>) -> bool {
|
pub fn range_is_trimmable_whitespace(&self, range: &Range<CharIndex>) -> bool {
|
||||||
for (slice_glyphs, _, _) in self.iter_slices_for_range(range) {
|
self.iter_slices_for_range(range).all(|(slice_glyphs, _, _)| {
|
||||||
if !slice_glyphs.is_whitespace() { return false; }
|
slice_glyphs.is_whitespace()
|
||||||
}
|
})
|
||||||
true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn ascent(&self) -> Au {
|
pub fn ascent(&self) -> Au {
|
||||||
|
@ -242,13 +241,11 @@ impl<'a> TextRun {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn min_width_for_range(&self, range: &Range<CharIndex>) -> Au {
|
pub fn min_width_for_range(&self, range: &Range<CharIndex>) -> Au {
|
||||||
let mut max_piece_width = Au(0);
|
|
||||||
debug!("iterating outer range {:?}", range);
|
debug!("iterating outer range {:?}", range);
|
||||||
for (_, offset, slice_range) in self.iter_slices_for_range(range) {
|
self.iter_slices_for_range(range).fold(Au(0), |max_piece_width, (_, offset, slice_range)| {
|
||||||
debug!("iterated on {:?}[{:?}]", offset, slice_range);
|
debug!("iterated on {:?}[{:?}]", offset, slice_range);
|
||||||
max_piece_width = Au::max(max_piece_width, self.advance_for_range(&slice_range));
|
Au::max(max_piece_width, self.advance_for_range(&slice_range))
|
||||||
}
|
})
|
||||||
max_piece_width
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the index of the first glyph run containing the given character index.
|
/// Returns the index of the first glyph run containing the given character index.
|
||||||
|
|
|
@ -639,13 +639,9 @@ pub struct FragmentIterator<'a> {
|
||||||
impl<'a> Iterator<(&'a Fragment, InlineFragmentContext<'a>)> for FragmentIterator<'a> {
|
impl<'a> Iterator<(&'a Fragment, InlineFragmentContext<'a>)> for FragmentIterator<'a> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn next(&mut self) -> Option<(&'a Fragment, InlineFragmentContext<'a>)> {
|
fn next(&mut self) -> Option<(&'a Fragment, InlineFragmentContext<'a>)> {
|
||||||
match self.iter.next() {
|
self.iter.next().map(|(i, fragment)| {
|
||||||
None => None,
|
(fragment, InlineFragmentContext::new(self.ranges, FragmentIndex(i as int)))
|
||||||
Some((i, fragment)) => Some((
|
})
|
||||||
fragment,
|
|
||||||
InlineFragmentContext::new(self.ranges, FragmentIndex(i as int)),
|
|
||||||
)),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -658,13 +654,9 @@ pub struct MutFragmentIterator<'a> {
|
||||||
impl<'a> Iterator<(&'a mut Fragment, InlineFragmentContext<'a>)> for MutFragmentIterator<'a> {
|
impl<'a> Iterator<(&'a mut Fragment, InlineFragmentContext<'a>)> for MutFragmentIterator<'a> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn next(&mut self) -> Option<(&'a mut Fragment, InlineFragmentContext<'a>)> {
|
fn next(&mut self) -> Option<(&'a mut Fragment, InlineFragmentContext<'a>)> {
|
||||||
match self.iter.next() {
|
self.iter.next().map(|(i, fragment)| {
|
||||||
None => None,
|
(fragment, InlineFragmentContext::new(self.ranges, FragmentIndex(i as int)))
|
||||||
Some((i, fragment)) => Some((
|
})
|
||||||
fragment,
|
|
||||||
InlineFragmentContext::new(self.ranges, FragmentIndex(i as int)),
|
|
||||||
)),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -868,22 +860,15 @@ impl InlineFragments {
|
||||||
|
|
||||||
/// Strips ignorable whitespace from the start of a list of fragments.
|
/// Strips ignorable whitespace from the start of a list of fragments.
|
||||||
pub fn strip_ignorable_whitespace_from_start(&mut self) {
|
pub fn strip_ignorable_whitespace_from_start(&mut self) {
|
||||||
if self.is_empty() {
|
if self.is_empty() { return }; // Fast path
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// FIXME(#2264, pcwalton): This is slow because vector shift is broken. :(
|
let new_fragments = mem::replace(&mut self.fragments, vec![])
|
||||||
let mut found_nonwhitespace = false;
|
.move_iter()
|
||||||
let mut new_fragments = Vec::new();
|
.skip_while(|fragment| {
|
||||||
for fragment in self.fragments.iter() {
|
if fragment.is_whitespace_only() {
|
||||||
if !found_nonwhitespace && fragment.is_whitespace_only() {
|
debug!("stripping ignorable whitespace from start"); true
|
||||||
debug!("stripping ignorable whitespace from start");
|
} else { false }
|
||||||
continue;
|
}).collect();
|
||||||
}
|
|
||||||
|
|
||||||
found_nonwhitespace = true;
|
|
||||||
new_fragments.push(fragment.clone())
|
|
||||||
}
|
|
||||||
|
|
||||||
self.fixup(new_fragments);
|
self.fixup(new_fragments);
|
||||||
}
|
}
|
||||||
|
@ -1358,29 +1343,24 @@ struct InlineFragmentFixupWorkItem {
|
||||||
pub struct RangeIterator<'a> {
|
pub struct RangeIterator<'a> {
|
||||||
iter: Items<'a,InlineFragmentRange>,
|
iter: Items<'a,InlineFragmentRange>,
|
||||||
index: FragmentIndex,
|
index: FragmentIndex,
|
||||||
seen_first: bool,
|
is_first: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Iterator<&'a InlineFragmentRange> for RangeIterator<'a> {
|
impl<'a> Iterator<&'a InlineFragmentRange> for RangeIterator<'a> {
|
||||||
fn next(&mut self) -> Option<&'a InlineFragmentRange> {
|
fn next(&mut self) -> Option<&'a InlineFragmentRange> {
|
||||||
if self.seen_first {
|
if !self.is_first {
|
||||||
match self.iter.next() {
|
// Yield the next fragment range if it contains the index
|
||||||
Some(fragment_range) if fragment_range.range.contains(self.index) => {
|
self.iter.next().and_then(|frag_range| {
|
||||||
return Some(fragment_range)
|
if frag_range.range.contains(self.index) { Some(frag_range) } else { None }
|
||||||
}
|
})
|
||||||
Some(_) | None => return None
|
} else {
|
||||||
}
|
// Find the first fragment range that contains the index if it exists
|
||||||
}
|
let index = self.index;
|
||||||
|
let first = self.iter.by_ref().find(|frag_range| {
|
||||||
loop {
|
frag_range.range.contains(index)
|
||||||
match self.iter.next() {
|
});
|
||||||
None => return None,
|
self.is_first = false; // We have made our first iteration
|
||||||
Some(fragment_range) if fragment_range.range.contains(self.index) => {
|
first
|
||||||
self.seen_first = true;
|
|
||||||
return Some(fragment_range)
|
|
||||||
}
|
|
||||||
Some(_) => {}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1403,10 +1383,20 @@ impl<'a> InlineFragmentContext<'a> {
|
||||||
/// Iterates over all ranges that contain the fragment at context's index, outermost first.
|
/// Iterates over all ranges that contain the fragment at context's index, outermost first.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn ranges(&self) -> RangeIterator<'a> {
|
pub fn ranges(&self) -> RangeIterator<'a> {
|
||||||
|
// TODO: It would be more straightforward to return an existing iterator
|
||||||
|
// rather defining our own `RangeIterator`, but this requires unboxed
|
||||||
|
// closures in order to satisfy the borrow checker:
|
||||||
|
//
|
||||||
|
// ~~~rust
|
||||||
|
// let index = self.index;
|
||||||
|
// self.ranges.iter()
|
||||||
|
// .skip_while(|fr| fr.range.contains(index))
|
||||||
|
// .take_while(|fr| fr.range.contains(index))
|
||||||
|
// ~~~
|
||||||
RangeIterator {
|
RangeIterator {
|
||||||
iter: self.ranges.iter(),
|
iter: self.ranges.iter(),
|
||||||
index: self.index,
|
index: self.index,
|
||||||
seen_first: false,
|
is_first: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue