diff options
-rw-r--r-- | src/components/gfx/text/glyph.rs | 12 | ||||
-rw-r--r-- | src/components/gfx/text/shaping/harfbuzz.rs | 6 | ||||
-rw-r--r-- | src/components/main/layout/inline.rs | 6 | ||||
-rw-r--r-- | src/components/main/layout/text.rs | 2 | ||||
-rw-r--r-- | src/components/util/range.rs | 175 |
5 files changed, 152 insertions, 49 deletions
diff --git a/src/components/gfx/text/glyph.rs b/src/components/gfx/text/glyph.rs index f762e4a0c99..2382a4ae1ce 100644 --- a/src/components/gfx/text/glyph.rs +++ b/src/components/gfx/text/glyph.rs @@ -3,7 +3,8 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use servo_util::vec::*; -use servo_util::range::Range; +use servo_util::range; +use servo_util::range::{Range, EachIndex}; use servo_util::geometry::Au; use std::cmp::{Ord, Eq}; @@ -11,7 +12,6 @@ use std::num::{NumCast, Zero}; use std::mem; use std::u16; use std::slice; -use std::iter; use geom::point::Point2D; /// GlyphEntry is a port of Gecko's CompressedGlyph scheme for storing glyph data compactly. @@ -609,7 +609,7 @@ impl<'a> GlyphStore { GlyphIterator { store: self, char_index: rang.begin(), - char_range: rang.eachi(), + char_range: rang.each_index(), glyph_range: None } } @@ -674,8 +674,8 @@ impl<'a> GlyphStore { pub struct GlyphIterator<'a> { store: &'a GlyphStore, char_index: int, - char_range: iter::Range<int>, - glyph_range: Option<iter::Range<int>>, + char_range: EachIndex<int, int>, + glyph_range: Option<EachIndex<int, int>>, } impl<'a> GlyphIterator<'a> { @@ -698,7 +698,7 @@ impl<'a> GlyphIterator<'a> { fn next_complex_glyph(&mut self, entry: &GlyphEntry, i: int) -> Option<(int, GlyphInfo<'a>)> { let glyphs = self.store.detail_store.get_detailed_glyphs_for_entry(i, entry.glyph_count()); - self.glyph_range = Some(range(0, glyphs.len() as int)); + self.glyph_range = Some(range::each_index(0, glyphs.len() as int)); self.next() } } diff --git a/src/components/gfx/text/shaping/harfbuzz.rs b/src/components/gfx/text/shaping/harfbuzz.rs index 7fcfca35426..f40a39ff6ce 100644 --- a/src/components/gfx/text/shaping/harfbuzz.rs +++ b/src/components/gfx/text/shaping/harfbuzz.rs @@ -316,7 +316,7 @@ impl Shaper { // extend glyph range to max glyph index covered by char_span, // in cases where one char made several glyphs and left some unassociated chars. let mut max_glyph_idx = glyph_span.end(); - for i in char_byte_span.eachi() { + for i in char_byte_span.each_index() { if byteToGlyph[i as uint] > NO_GLYPH { max_glyph_idx = cmp::max(byteToGlyph[i as uint] as int + 1, max_glyph_idx); } @@ -340,7 +340,7 @@ impl Shaper { probably doesn't work."); let mut all_glyphs_are_within_cluster: bool = true; - for j in glyph_span.eachi() { + for j in glyph_span.each_index() { let loc = glyph_data.byte_offset_of_glyph(j); if !char_byte_span.contains(loc) { all_glyphs_are_within_cluster = false; @@ -414,7 +414,7 @@ impl Shaper { // collect all glyphs to be assigned to the first character. let mut datas = vec!(); - for glyph_i in glyph_span.eachi() { + for glyph_i in glyph_span.each_index() { let shape = glyph_data.get_entry_for_glyph(glyph_i, &mut y_pos); datas.push(GlyphData::new(shape.codepoint, shape.advance, diff --git a/src/components/main/layout/inline.rs b/src/components/main/layout/inline.rs index 060fd7f6344..e797120cb02 100644 --- a/src/components/main/layout/inline.rs +++ b/src/components/main/layout/inline.rs @@ -713,7 +713,7 @@ impl InlineFlow { text_align::right => slack_width, }; - for i in line.range.eachi() { + for i in line.range.each_index() { let box_ = boxes.get_mut(i as uint); let size = box_.border_box.size; box_.border_box = Rect(Point2D(offset_x, box_.border_box.origin.y), size); @@ -844,7 +844,7 @@ impl Flow for InlineFlow { let (mut largest_height_for_top_fragments, mut largest_height_for_bottom_fragments) = (Au(0), Au(0)); - for box_i in line.range.eachi() { + for box_i in line.range.each_index() { let fragment = self.boxes.boxes.get_mut(box_i as uint); let InlineMetrics { @@ -920,7 +920,7 @@ impl Flow for InlineFlow { // Compute the final positions in the block direction of each fragment. Recall that // `fragment.border_box.origin.y` was set to the distance from the baseline above. - for box_i in line.range.eachi() { + for box_i in line.range.each_index() { let fragment = self.boxes.get_mut(box_i as uint); match fragment.vertical_align() { vertical_align::top => { diff --git a/src/components/main/layout/text.rs b/src/components/main/layout/text.rs index f254d07d5a4..1aa2b0c7866 100644 --- a/src/components/main/layout/text.rs +++ b/src/components/main/layout/text.rs @@ -232,7 +232,7 @@ impl TextRunScanner { // Make new boxes with the run and adjusted text indices. debug!("TextRunScanner: pushing box(es) in range: {}", self.clump); - for i in clump.eachi() { + for i in clump.each_index() { let logical_offset = i - self.clump.begin(); let range = new_ranges.get(logical_offset as uint); if range.length() == 0 { diff --git a/src/components/util/range.rs b/src/components/util/range.rs index 0acf6343dab..05421d9af87 100644 --- a/src/components/util/range.rs +++ b/src/components/util/range.rs @@ -6,12 +6,85 @@ use std::cmp::{max, min}; use std::iter; use std::fmt; use std::num; -use std::num::Bounded; +use std::num::{Bounded, Zero}; + +/// An index type to be used by a `Range` +pub trait RangeIndex<T>: Eq + Ord + + Clone + + Copy + + Zero + + TotalEq + + TotalOrd + + Add<Self, Self> + + Sub<Self, Self> + + Neg<Self> + + fmt::Show { + fn new(x: T) -> Self; + fn get(self) -> T; +} + +impl RangeIndex<int> for int { + #[inline] + fn new(x: int) -> int { x } + + #[inline] + fn get(self) -> int { self } +} + +/// Implements a range index type with operator overloads +#[macro_export] +macro_rules! range_index { + ($(#[$attr:meta])* struct $Self:ident($T:ty)) => ( + #[deriving(Clone, Eq, Ord, TotalEq, TotalOrd, Show, Zero)] + $(#[$attr])* + pub struct $Self(pub $T); + + impl $Self { + #[inline] + pub fn to_uint(self) -> uint { + self.get() as uint + } + } + + impl RangeIndex<$T> for $Self { + #[inline] + fn new(x: $T) -> $Self { + $Self(x) + } + + #[inline] + fn get(self) -> $T { + match self { $Self(x) => x } + } + } + + impl Add<$Self, $Self> for $Self { + #[inline] + fn add(&self, other: &$Self) -> $Self { + $Self(self.get() + other.get()) + } + } + + impl Sub<$Self, $Self> for $Self { + #[inline] + fn sub(&self, other: &$Self) -> $Self { + $Self(self.get() - other.get()) + } + } + + impl Neg<$Self> for $Self { + #[inline] + fn neg(&self) -> $Self { + $Self(-self.get()) + } + } + ) +} #[deriving(Show)] -pub enum RangeRelation<T> { - OverlapsBegin(/* overlap */ T), - OverlapsEnd(/* overlap */ T), +pub enum RangeRelation<I> { + OverlapsBegin(/* overlap */ I), + OverlapsEnd(/* overlap */ I), ContainedBy, Contains, Coincides, @@ -19,59 +92,88 @@ pub enum RangeRelation<T> { EntirelyAfter } +/// A range of indices #[deriving(Clone)] -pub struct Range<T> { - off: T, - len: T, +pub struct Range<I> { + off: I, + len: I, } -impl<T: Int + TotalOrd + Signed> fmt::Show for Range<T> { +impl<T: Int, I: fmt::Show + RangeIndex<T>> fmt::Show for Range<I> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f.buf, "[{} .. {})", self.begin(), self.end()) } } -impl<T: Int + TotalOrd + Signed> Range<T> { +/// An iterator over each index in a range +pub struct EachIndex<T, I> { + it: iter::Range<T>, +} + +pub fn each_index<T: Int, I: RangeIndex<T>>(start: I, stop: I) -> EachIndex<T, I> { + EachIndex { + it: iter::range(start.get(), stop.get()) + } +} + +impl<T: Int, I: RangeIndex<T>> Iterator<I> for EachIndex<T, I> { #[inline] - pub fn new(off: T, len: T) -> Range<T> { - Range { - off: off, - len: len, - } + fn next(&mut self) -> Option<I> { + self.it.next().map(|i| RangeIndex::new(i)) + } + + #[inline] + fn size_hint(&self) -> (uint, Option<uint>) { + self.it.size_hint() + } +} + +impl<T: Int, I: RangeIndex<T>> Range<I> { + #[inline] + pub fn new(off: I, len: I) -> Range<I> { + Range { off: off, len: len } } #[inline] - pub fn empty() -> Range<T> { + pub fn empty() -> Range<I> { Range::new(num::zero(), num::zero()) } #[inline] - pub fn begin(&self) -> T { self.off } + pub fn begin(&self) -> I { self.off } #[inline] - pub fn length(&self) -> T { self.len } + pub fn length(&self) -> I { self.len } #[inline] - pub fn end(&self) -> T { self.off + self.len } + pub fn end(&self) -> I { self.off + self.len } #[inline] - pub fn eachi(&self) -> iter::Range<T> { - range(self.off, self.off + self.len) + pub fn each_index(&self) -> EachIndex<T, I> { + each_index(self.off, self.off + self.len) } #[inline] - pub fn contains(&self, i: T) -> bool { + pub fn contains(&self, i: I) -> bool { i >= self.begin() && i < self.end() } #[inline] pub fn is_valid_for_string(&self, s: &str) -> bool { let s_len = s.len(); - match num::cast(s_len) { + match num::cast::<uint, T>(s_len) { Some(len) => { - self.begin() < len && self.end() <= len && self.length() <= len + let len = RangeIndex::new(len); + self.begin() < len + && self.end() <= len + && self.length() <= len }, None => { - debug!("Range<T>::is_valid_for_string: string length (len={}) is longer than the max \ - value for T (max={})", s_len, { let val: T = Bounded::max_value(); val }); + debug!("Range<T>::is_valid_for_string: string length (len={}) is longer than the \ + max value for the range index (max={})", s_len, + { + let max: T = Bounded::max_value(); + let val: I = RangeIndex::new(max); + val + }); false }, } @@ -83,34 +185,34 @@ impl<T: Int + TotalOrd + Signed> Range<T> { } #[inline] - pub fn shift_by(&mut self, i: T) { + pub fn shift_by(&mut self, i: I) { self.off = self.off + i; } #[inline] - pub fn extend_by(&mut self, i: T) { + pub fn extend_by(&mut self, i: I) { self.len = self.len + i; } #[inline] - pub fn extend_to(&mut self, i: T) { + pub fn extend_to(&mut self, i: I) { self.len = i - self.off; } #[inline] - pub fn adjust_by(&mut self, off_i: T, len_i: T) { + pub fn adjust_by(&mut self, off_i: I, len_i: I) { self.off = self.off + off_i; self.len = self.len + len_i; } #[inline] - pub fn reset(&mut self, off_i: T, len_i: T) { + pub fn reset(&mut self, off_i: I, len_i: I) { self.off = off_i; self.len = len_i; } #[inline] - pub fn intersect(&self, other: &Range<T>) -> Range<T> { + pub fn intersect(&self, other: &Range<I>) -> Range<I> { let begin = max(self.begin(), other.begin()); let end = min(self.end(), other.end()); @@ -125,7 +227,7 @@ impl<T: Int + TotalOrd + Signed> Range<T> { /// from the point of view of `self`. So, 'EntirelyBefore' means /// that the `self` range is entirely before `other` range. #[inline] - pub fn relation_to_range(&self, other: &Range<T>) -> RangeRelation<T> { + pub fn relation_to_range(&self, other: &Range<I>) -> RangeRelation<I> { if other.begin() > self.end() { return EntirelyBefore; } @@ -154,19 +256,20 @@ impl<T: Int + TotalOrd + Signed> Range<T> { } #[inline] - pub fn repair_after_coalesced_range(&mut self, other: &Range<T>) { + pub fn repair_after_coalesced_range(&mut self, other: &Range<I>) { let relation = self.relation_to_range(other); debug!("repair_after_coalesced_range: possibly repairing range {}", *self); debug!("repair_after_coalesced_range: relation of original range and coalesced range {}: {}", *other, relation); + let _1: I = RangeIndex::new(num::one::<T>()); match relation { EntirelyBefore => {}, EntirelyAfter => { self.shift_by(-other.length()); }, - Coincides | ContainedBy => { self.reset(other.begin(), num::one()); }, + Coincides | ContainedBy => { self.reset(other.begin(), _1); }, Contains => { self.extend_by(-other.length()); }, - OverlapsBegin(overlap) => { self.extend_by(num::one::<T>() - overlap); }, + OverlapsBegin(overlap) => { self.extend_by(_1 - overlap); }, OverlapsEnd(overlap) => { - let len = self.length() - overlap + num::one(); + let len = self.length() - overlap + _1; self.reset(other.begin(), len); } }; |