mirror of
https://github.com/servo/servo.git
synced 2025-10-17 08:49:21 +01:00
Convert our iterators to external iterators
Except util/tree.rs (see next commit).
This commit is contained in:
parent
be061a9aa0
commit
abaeb58203
4 changed files with 173 additions and 146 deletions
|
@ -14,6 +14,7 @@ use std::u16;
|
|||
use std::vec;
|
||||
use std::uint;
|
||||
use std::util;
|
||||
use std::iterator;
|
||||
use geom::point::Point2D;
|
||||
use extra::sort;
|
||||
|
||||
|
@ -599,62 +600,24 @@ impl<'self> GlyphStore {
|
|||
self.entry_buffer[i] = entry;
|
||||
}
|
||||
|
||||
pub fn iter_glyphs_for_char_index(&'self self,
|
||||
i: uint,
|
||||
cb: &fn(uint, &GlyphInfo<'self>) -> bool)
|
||||
-> bool {
|
||||
assert!(i < self.entry_buffer.len());
|
||||
|
||||
let entry = &self.entry_buffer[i];
|
||||
match entry.is_simple() {
|
||||
true => {
|
||||
let proxy = &SimpleGlyphInfo(self, i);
|
||||
cb(i, proxy);
|
||||
},
|
||||
false => {
|
||||
let glyphs = self.detail_store.get_detailed_glyphs_for_entry(i,
|
||||
entry.glyph_count());
|
||||
for uint::range(0, glyphs.len()) |j| {
|
||||
let proxy = &DetailGlyphInfo(self, i, j as u16);
|
||||
cb(i, proxy);
|
||||
}
|
||||
}
|
||||
}
|
||||
true
|
||||
pub fn iter_glyphs_for_char_index(&'self self, i: uint) -> GlyphIterator<'self> {
|
||||
self.iter_glyphs_for_char_range(&Range::new(i, 1))
|
||||
}
|
||||
|
||||
pub fn iter_glyphs_for_char_range(&'self self,
|
||||
range: &Range,
|
||||
callback: &fn(uint, &GlyphInfo<'self>) -> bool)
|
||||
-> bool {
|
||||
if range.begin() >= self.entry_buffer.len() {
|
||||
error!("iter_glyphs_for_range: range.begin beyond length!");
|
||||
return false
|
||||
pub fn iter_glyphs_for_char_range(&'self self, rang: &Range) -> GlyphIterator<'self> {
|
||||
if rang.begin() >= self.entry_buffer.len() {
|
||||
fail!("iter_glyphs_for_range: range.begin beyond length!");
|
||||
}
|
||||
if range.end() > self.entry_buffer.len() {
|
||||
error!("iter_glyphs_for_range: range.end beyond length!");
|
||||
return false
|
||||
if rang.end() > self.entry_buffer.len() {
|
||||
fail!("iter_glyphs_for_range: range.end beyond length!");
|
||||
}
|
||||
|
||||
for range.eachi |i| {
|
||||
// FIXME: Work around rust#2202. We should be able to pass the callback directly.
|
||||
if !self.iter_glyphs_for_char_index(i, |a, b| callback(a, b)) {
|
||||
break
|
||||
}
|
||||
GlyphIterator {
|
||||
store: self,
|
||||
char_index: rang.begin(),
|
||||
char_range: rang.eachi(),
|
||||
glyph_range: None
|
||||
}
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
pub fn iter_all_glyphs(&'self self, callback: &fn(uint, &GlyphInfo<'self>) -> bool) -> bool {
|
||||
for uint::range(0, self.entry_buffer.len()) |i| {
|
||||
// FIXME: Work around rust#2202. We should be able to pass the callback directly.
|
||||
if !self.iter_glyphs_for_char_index(i, |a, b| callback(a, b)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
// getter methods
|
||||
|
@ -713,3 +676,49 @@ impl<'self> GlyphStore {
|
|||
self.entry_buffer[i] = entry.set_can_break_before(t);
|
||||
}
|
||||
}
|
||||
|
||||
pub struct GlyphIterator<'self> {
|
||||
priv store: &'self GlyphStore,
|
||||
priv char_index: uint,
|
||||
priv char_range: iterator::Range<uint>,
|
||||
priv glyph_range: Option<iterator::Range<uint>>,
|
||||
}
|
||||
|
||||
impl<'self> Iterator<(uint, GlyphInfo<'self>)> for GlyphIterator<'self> {
|
||||
// I tried to start with something simpler and apply FlatMap, but the
|
||||
// inability to store free variables in the FlatMap struct was problematic.
|
||||
|
||||
fn next(&mut self) -> Option<(uint, GlyphInfo<'self>)> {
|
||||
// Would use 'match' here but it borrows contents in a way that
|
||||
// interferes with mutation.
|
||||
if self.glyph_range.is_some() {
|
||||
match self.glyph_range.unwrap().next() {
|
||||
Some(j) => Some((self.char_index,
|
||||
DetailGlyphInfo(self.store, self.char_index, j as u16))),
|
||||
None => {
|
||||
// No more glyphs for current character. Try to get another.
|
||||
self.glyph_range = None;
|
||||
self.next()
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// No glyph range. Look at next character.
|
||||
match self.char_range.next() {
|
||||
Some(i) => {
|
||||
self.char_index = i;
|
||||
assert!(i < self.store.entry_buffer.len());
|
||||
let entry = &self.store.entry_buffer[i];
|
||||
if entry.is_simple() {
|
||||
Some((self.char_index, SimpleGlyphInfo(self.store, i)))
|
||||
} else {
|
||||
let glyphs = self.store.detail_store
|
||||
.get_detailed_glyphs_for_entry(i, entry.glyph_count());
|
||||
self.glyph_range = Some(range(0, glyphs.len()));
|
||||
self.next()
|
||||
}
|
||||
},
|
||||
None => None
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue