mirror of
https://github.com/servo/servo.git
synced 2025-08-06 06:00:15 +01:00
Extract Range into its own file.
This commit is contained in:
parent
c9ec35fa2d
commit
fcca6d6ada
10 changed files with 134 additions and 127 deletions
|
@ -4,11 +4,12 @@ use geom::rect::Rect;
|
||||||
use image::base::Image;
|
use image::base::Image;
|
||||||
use render_context::RenderContext;
|
use render_context::RenderContext;
|
||||||
use servo_text::text_run;
|
use servo_text::text_run;
|
||||||
|
use text::text_run::SendableTextRun;
|
||||||
|
use util::range::Range;
|
||||||
|
|
||||||
use std::arc::ARC;
|
use std::arc::ARC;
|
||||||
use clone_arc = std::arc::clone;
|
use clone_arc = std::arc::clone;
|
||||||
use dvec::DVec;
|
use dvec::DVec;
|
||||||
use text::text_run::{TextRange, SendableTextRun};
|
|
||||||
|
|
||||||
pub use layout::display_list_builder::DisplayListBuilder;
|
pub use layout::display_list_builder::DisplayListBuilder;
|
||||||
|
|
||||||
|
@ -24,7 +25,7 @@ pub enum DisplayItemData {
|
||||||
// TODO: need to provide spacing data for text run.
|
// TODO: need to provide spacing data for text run.
|
||||||
// (i.e, to support rendering of CSS 'word-spacing' and 'letter-spacing')
|
// (i.e, to support rendering of CSS 'word-spacing' and 'letter-spacing')
|
||||||
// TODO: don't copy text runs, ever.
|
// TODO: don't copy text runs, ever.
|
||||||
TextData(~SendableTextRun, TextRange),
|
TextData(~SendableTextRun, Range),
|
||||||
ImageData(ARC<~image::base::Image>),
|
ImageData(ARC<~image::base::Image>),
|
||||||
BorderData(au, u8, u8, u8)
|
BorderData(au, u8, u8, u8)
|
||||||
}
|
}
|
||||||
|
@ -76,7 +77,7 @@ pub fn Border(bounds: Rect<au>, width: au, r: u8, g: u8, b: u8) -> DisplayItem {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn Text(bounds: Rect<au>, run: ~SendableTextRun, range: TextRange) -> DisplayItem {
|
pub fn Text(bounds: Rect<au>, run: ~SendableTextRun, range: Range) -> DisplayItem {
|
||||||
DisplayItem {
|
DisplayItem {
|
||||||
draw: |self, ctx| draw_Text(self, ctx),
|
draw: |self, ctx| draw_Text(self, ctx),
|
||||||
bounds: bounds,
|
bounds: bounds,
|
||||||
|
|
|
@ -2,10 +2,11 @@ use mod au = geometry;
|
||||||
|
|
||||||
use compositor::LayerBuffer;
|
use compositor::LayerBuffer;
|
||||||
use text::font::Font;
|
use text::font::Font;
|
||||||
use text::text_run::{TextRun, TextRange};
|
use text::text_run::TextRun;
|
||||||
use text::font_cache::FontCache;
|
use text::font_cache::FontCache;
|
||||||
use image::base::Image;
|
use image::base::Image;
|
||||||
use au = au::au;
|
use au = au::au;
|
||||||
|
use util::range::Range;
|
||||||
|
|
||||||
use core::libc::types::common::c99::uint16_t;
|
use core::libc::types::common::c99::uint16_t;
|
||||||
use core::ptr::to_unsafe_ptr;
|
use core::ptr::to_unsafe_ptr;
|
||||||
|
@ -67,7 +68,7 @@ impl RenderContext {
|
||||||
draw_options);
|
draw_options);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn draw_text(&self, bounds: Rect<au>, run: &TextRun, range: TextRange) {
|
pub fn draw_text(&self, bounds: Rect<au>, run: &TextRun, range: Range) {
|
||||||
use ptr::{null};
|
use ptr::{null};
|
||||||
use vec::raw::to_ptr;
|
use vec::raw::to_ptr;
|
||||||
use libc::types::common::c99::{uint16_t, uint32_t};
|
use libc::types::common::c99::{uint16_t, uint32_t};
|
||||||
|
|
|
@ -22,10 +22,11 @@ use layout::debug::BoxedDebugMethods;
|
||||||
use layout::flow::FlowContext;
|
use layout::flow::FlowContext;
|
||||||
use layout::text::TextBoxData;
|
use layout::text::TextBoxData;
|
||||||
use servo_text::text_run;
|
use servo_text::text_run;
|
||||||
use servo_text::text_run::{MutableTextRange, TextRange, TextRun};
|
use servo_text::text_run::TextRun;
|
||||||
use std::net::url::Url;
|
use std::net::url::Url;
|
||||||
use task::spawn;
|
use task::spawn;
|
||||||
use util::color::Color;
|
use util::color::Color;
|
||||||
|
use util::range::*;
|
||||||
use util::tree;
|
use util::tree;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -187,8 +188,8 @@ impl RenderBox : RenderBoxMethods {
|
||||||
|
|
||||||
let mut pieces_processed_count : uint = 0;
|
let mut pieces_processed_count : uint = 0;
|
||||||
let mut remaining_width : au = max_width;
|
let mut remaining_width : au = max_width;
|
||||||
let left_range = MutableTextRange(data.range.begin(), 0);
|
let left_range = MutableRange(data.range.begin(), 0);
|
||||||
let mut right_range : Option<TextRange> = None;
|
let mut right_range : Option<Range> = None;
|
||||||
debug!("split_to_width: splitting text box (strlen=%u, range=%?, avail_width=%?)",
|
debug!("split_to_width: splitting text box (strlen=%u, range=%?, avail_width=%?)",
|
||||||
data.run.text.len(), data.range, max_width);
|
data.run.text.len(), data.range, max_width);
|
||||||
do data.run.iter_indivisible_pieces_for_range(data.range) |piece_range| {
|
do data.run.iter_indivisible_pieces_for_range(data.range) |piece_range| {
|
||||||
|
@ -216,14 +217,14 @@ impl RenderBox : RenderBoxMethods {
|
||||||
// if there are still things after the trimmable whitespace, create right chunk
|
// if there are still things after the trimmable whitespace, create right chunk
|
||||||
if piece_range.end() < data.range.end() {
|
if piece_range.end() < data.range.end() {
|
||||||
debug!("split_to_width: case=skipping trimmable trailing whitespace, then split remainder");
|
debug!("split_to_width: case=skipping trimmable trailing whitespace, then split remainder");
|
||||||
right_range = Some(TextRange(piece_range.end(),
|
right_range = Some(Range(piece_range.end(),
|
||||||
data.range.end() - piece_range.end()));
|
data.range.end() - piece_range.end()));
|
||||||
} else {
|
} else {
|
||||||
debug!("split_to_width: case=skipping trimmable trailing whitespace");
|
debug!("split_to_width: case=skipping trimmable trailing whitespace");
|
||||||
}
|
}
|
||||||
} else if piece_range.begin() < data.range.end() {
|
} else if piece_range.begin() < data.range.end() {
|
||||||
// still things left, create right chunk
|
// still things left, create right chunk
|
||||||
right_range = Some(TextRange(piece_range.begin(),
|
right_range = Some(Range(piece_range.begin(),
|
||||||
data.range.end() - piece_range.begin()));
|
data.range.end() - piece_range.begin()));
|
||||||
debug!("split_to_width: case=splitting remainder with right range=%?",
|
debug!("split_to_width: case=splitting remainder with right range=%?",
|
||||||
right_range);
|
right_range);
|
||||||
|
@ -237,7 +238,7 @@ impl RenderBox : RenderBoxMethods {
|
||||||
Some(layout::text::adapt_textbox_with_range(self.d(), data.run, left_range.as_immutable()))
|
Some(layout::text::adapt_textbox_with_range(self.d(), data.run, left_range.as_immutable()))
|
||||||
} else { None };
|
} else { None };
|
||||||
|
|
||||||
let right_box = option::map_default(&right_range, None, |range: &TextRange| {
|
let right_box = option::map_default(&right_range, None, |range: &Range| {
|
||||||
Some(layout::text::adapt_textbox_with_range(self.d(), data.run, *range))
|
Some(layout::text::adapt_textbox_with_range(self.d(), data.run, *range))
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,7 @@ use num::Num;
|
||||||
use servo_text::text_run::TextRun;
|
use servo_text::text_run::TextRun;
|
||||||
use servo_text::util::*;
|
use servo_text::util::*;
|
||||||
use std::arc;
|
use std::arc;
|
||||||
|
use util::range::Range;
|
||||||
use util::tree;
|
use util::tree;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -169,7 +170,7 @@ impl TextRunScanner {
|
||||||
debug!("TextRunScanner: pushing single text box when start=%u,end=%u",
|
debug!("TextRunScanner: pushing single text box when start=%u,end=%u",
|
||||||
self.clump_start, self.clump_end);
|
self.clump_start, self.clump_end);
|
||||||
let new_box = layout::text::adapt_textbox_with_range(in_boxes[self.clump_start].d(), run,
|
let new_box = layout::text::adapt_textbox_with_range(in_boxes[self.clump_start].d(), run,
|
||||||
TextRange(0, run.text.len()));
|
Range(0, run.text.len()));
|
||||||
out_boxes.push(new_box);
|
out_boxes.push(new_box);
|
||||||
},
|
},
|
||||||
(false, true) => {
|
(false, true) => {
|
||||||
|
@ -223,7 +224,7 @@ impl TextRunScanner {
|
||||||
debug!("TextRunScanner: pushing box(es) when start=%u,end=%u",
|
debug!("TextRunScanner: pushing box(es) when start=%u,end=%u",
|
||||||
self.clump_start, self.clump_end);
|
self.clump_start, self.clump_end);
|
||||||
let new_box = layout::text::adapt_textbox_with_range(in_boxes[self.clump_start].d(), run,
|
let new_box = layout::text::adapt_textbox_with_range(in_boxes[self.clump_start].d(), run,
|
||||||
TextRange(0, run.text.len()));
|
Range(0, run.text.len()));
|
||||||
out_boxes.push(new_box);
|
out_boxes.push(new_box);
|
||||||
}
|
}
|
||||||
} /* /match */
|
} /* /match */
|
||||||
|
|
|
@ -1,14 +1,15 @@
|
||||||
/** Text layout. */
|
/** Text layout. */
|
||||||
|
|
||||||
use servo_text::text_run::{TextRange, TextRun};
|
use servo_text::text_run::TextRun;
|
||||||
use layout::box::{TextBox, RenderBox, RenderBoxData, UnscannedTextBox};
|
use layout::box::{TextBox, RenderBox, RenderBoxData, UnscannedTextBox};
|
||||||
|
use util::range::Range;
|
||||||
|
|
||||||
pub struct TextBoxData {
|
pub struct TextBoxData {
|
||||||
run: @TextRun,
|
run: @TextRun,
|
||||||
range: TextRange,
|
range: Range,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn TextBoxData(run: @TextRun, range: TextRange) -> TextBoxData {
|
pub fn TextBoxData(run: @TextRun, range: Range) -> TextBoxData {
|
||||||
TextBoxData {
|
TextBoxData {
|
||||||
run: run,
|
run: run,
|
||||||
range: range,
|
range: range,
|
||||||
|
@ -16,7 +17,7 @@ pub fn TextBoxData(run: @TextRun, range: TextRange) -> TextBoxData {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn adapt_textbox_with_range(box_data: &RenderBoxData, run: @TextRun,
|
pub fn adapt_textbox_with_range(box_data: &RenderBoxData, run: @TextRun,
|
||||||
range: TextRange) -> @RenderBox {
|
range: Range) -> @RenderBox {
|
||||||
debug!("Creating textbox with span: (strlen=%u, off=%u, len=%u) of textrun: %s",
|
debug!("Creating textbox with span: (strlen=%u, off=%u, len=%u) of textrun: %s",
|
||||||
run.text.len(), range.begin(), range.length(), run.text);
|
run.text.len(), range.begin(), range.length(), run.text);
|
||||||
let new_box_data = copy *box_data;
|
let new_box_data = copy *box_data;
|
||||||
|
|
|
@ -129,6 +129,7 @@ pub mod util {
|
||||||
pub mod time;
|
pub mod time;
|
||||||
pub mod url;
|
pub mod url;
|
||||||
pub mod vec;
|
pub mod vec;
|
||||||
|
pub mod range;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub mod opts;
|
pub mod opts;
|
||||||
|
|
|
@ -9,8 +9,9 @@ use glyph::GlyphIndex;
|
||||||
use libc::{ c_int, c_double, c_ulong };
|
use libc::{ c_int, c_double, c_ulong };
|
||||||
use native_font::NativeFont;
|
use native_font::NativeFont;
|
||||||
use ptr::{null, addr_of};
|
use ptr::{null, addr_of};
|
||||||
use text::text_run::{TextRun, TextRange};
|
use text::text_run::TextRun;
|
||||||
use vec_to_ptr = vec::raw::to_ptr;
|
use vec_to_ptr = vec::raw::to_ptr;
|
||||||
|
use servo_util::range::Range;
|
||||||
|
|
||||||
// Used to abstract over the shaper's choice of fixed int representation.
|
// Used to abstract over the shaper's choice of fixed int representation.
|
||||||
type FractionalPixel = float;
|
type FractionalPixel = float;
|
||||||
|
@ -41,7 +42,7 @@ struct RunMetrics {
|
||||||
|
|
||||||
// Public API
|
// Public API
|
||||||
pub trait FontMethods {
|
pub trait FontMethods {
|
||||||
fn measure_text(&TextRun, TextRange) -> RunMetrics;
|
fn measure_text(&TextRun, Range) -> RunMetrics;
|
||||||
|
|
||||||
fn buf(&self) -> @~[u8];
|
fn buf(&self) -> @~[u8];
|
||||||
// these are used to get glyphs and advances in the case that the
|
// these are used to get glyphs and advances in the case that the
|
||||||
|
@ -51,7 +52,7 @@ pub trait FontMethods {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub impl Font : FontMethods {
|
pub impl Font : FontMethods {
|
||||||
fn measure_text(run: &TextRun, range: TextRange) -> RunMetrics {
|
fn measure_text(run: &TextRun, range: Range) -> RunMetrics {
|
||||||
assert range.is_valid_for_string(run.text);
|
assert range.is_valid_for_string(run.text);
|
||||||
|
|
||||||
// TODO: alter advance direction for RTL
|
// TODO: alter advance direction for RTL
|
||||||
|
|
|
@ -6,7 +6,7 @@ use core::u16;
|
||||||
use geom::point::Point2D;
|
use geom::point::Point2D;
|
||||||
use num::from_int;
|
use num::from_int;
|
||||||
use std::sort;
|
use std::sort;
|
||||||
use servo_text::text_run::TextRange;
|
use servo_util::range::Range;
|
||||||
use servo_util::vec::*;
|
use servo_util::vec::*;
|
||||||
|
|
||||||
|
|
||||||
|
@ -545,7 +545,7 @@ impl GlyphStore {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn iter_glyphs_for_range<T>(&self, range: TextRange, cb: fn&(uint, GlyphInfo/&) -> T) {
|
fn iter_glyphs_for_range<T>(&self, range: Range, cb: fn&(uint, GlyphInfo/&) -> T) {
|
||||||
assert range.begin() < self.entry_buffer.len();
|
assert range.begin() < self.entry_buffer.len();
|
||||||
assert range.end() <= self.entry_buffer.len();
|
assert range.end() <= self.entry_buffer.len();
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,7 @@ use libc::{c_void};
|
||||||
use servo_util::color;
|
use servo_util::color;
|
||||||
use shaper::shape_textrun;
|
use shaper::shape_textrun;
|
||||||
use std::arc;
|
use std::arc;
|
||||||
|
use servo_util::range::{Range, MutableRange};
|
||||||
|
|
||||||
pub struct TextRun {
|
pub struct TextRun {
|
||||||
text: ~str,
|
text: ~str,
|
||||||
|
@ -19,98 +20,6 @@ pub struct TextRun {
|
||||||
priv glyphs: GlyphStore,
|
priv glyphs: GlyphStore,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct TextRange {
|
|
||||||
priv off: u16,
|
|
||||||
priv len: u16
|
|
||||||
}
|
|
||||||
|
|
||||||
pure fn TextRange(off: uint, len :uint) -> TextRange {
|
|
||||||
assert off <= u16::max_value as uint;
|
|
||||||
assert len <= u16::max_value as uint;
|
|
||||||
|
|
||||||
TextRange {
|
|
||||||
off: off as u16,
|
|
||||||
len: len as u16
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TextRange {
|
|
||||||
pub pure fn begin() -> uint { self.off as uint }
|
|
||||||
pub pure fn length() -> uint { self.len as uint }
|
|
||||||
pub pure fn end() -> uint { (self.off as uint) + (self.len as uint) }
|
|
||||||
|
|
||||||
pub pure fn eachi(cb: fn&(uint) -> bool) {
|
|
||||||
do uint::range(self.off as uint,
|
|
||||||
(self.off as uint) + (self.len as uint)) |i| {
|
|
||||||
cb(i)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub pure fn is_valid_for_string(s: &str) -> bool {
|
|
||||||
self.begin() < s.len() && self.end() <= s.len() && self.length() <= s.len()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub pure fn shift_by(i: int) -> TextRange {
|
|
||||||
TextRange(((self.off as int) + i) as uint, self.len as uint)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub pure fn extend_by(i: int) -> TextRange {
|
|
||||||
TextRange(self.off as uint, ((self.len as int) + i) as uint)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub pure fn adjust_by(off_i: int, len_i: int) -> TextRange {
|
|
||||||
TextRange(((self.off as int) + off_i) as uint, ((self.len as int) + len_i) as uint)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct MutableTextRange {
|
|
||||||
priv mut off: uint,
|
|
||||||
priv mut len: uint
|
|
||||||
}
|
|
||||||
|
|
||||||
pure fn MutableTextRange(off: uint, len :uint) -> MutableTextRange {
|
|
||||||
MutableTextRange { off: off, len: len }
|
|
||||||
}
|
|
||||||
|
|
||||||
impl MutableTextRange {
|
|
||||||
pub pure fn begin() -> uint { self.off }
|
|
||||||
pub pure fn length() -> uint { self.len }
|
|
||||||
pub pure fn end() -> uint { self.off + self.len }
|
|
||||||
pub pure fn eachi(cb: fn&(uint) -> bool) {
|
|
||||||
do uint::range(self.off, self.off + self.len) |i| { cb(i) }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub pure fn as_immutable() -> TextRange {
|
|
||||||
TextRange(self.begin(), self.length())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub pure fn is_valid_for_string(s: &str) -> bool {
|
|
||||||
self.begin() < s.len() && self.end() <= s.len() && self.length() <= s.len()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn shift_by(i: int) {
|
|
||||||
self.off = ((self.off as int) + i) as uint;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn extend_by(i: int) {
|
|
||||||
self.len = ((self.len as int) + i) as uint;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn extend_to(i: uint) {
|
|
||||||
self.len = i - self.off;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn adjust_by(off_i: int, len_i: int) {
|
|
||||||
self.off = ((self.off as int) + off_i) as uint;
|
|
||||||
self.len = ((self.len as int) + len_i) as uint;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn reset(off_i: uint, len_i: uint) {
|
|
||||||
self.off = off_i;
|
|
||||||
self.len = len_i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// This is a hack until TextRuns are normally sendable, or
|
// This is a hack until TextRuns are normally sendable, or
|
||||||
// we instead use ARC<TextRun> everywhere.
|
// we instead use ARC<TextRun> everywhere.
|
||||||
pub struct SendableTextRun {
|
pub struct SendableTextRun {
|
||||||
|
@ -139,20 +48,20 @@ pub fn deserialize(cache: @FontCache, run: &SendableTextRun) -> @TextRun {
|
||||||
|
|
||||||
trait TextRunMethods {
|
trait TextRunMethods {
|
||||||
pure fn glyphs(&self) -> &self/GlyphStore;
|
pure fn glyphs(&self) -> &self/GlyphStore;
|
||||||
fn iter_indivisible_pieces_for_range(&self, range: TextRange, f: fn&(TextRange) -> bool);
|
fn iter_indivisible_pieces_for_range(&self, range: Range, f: fn&(Range) -> bool);
|
||||||
// TODO: needs to take box style as argument, or move to TextBox.
|
// TODO: needs to take box style as argument, or move to TextBox.
|
||||||
// see Gecko's IsTrimmableSpace methods for details.
|
// see Gecko's IsTrimmableSpace methods for details.
|
||||||
pure fn range_is_trimmable_whitespace(&self, range: TextRange) -> bool;
|
pure fn range_is_trimmable_whitespace(&self, range: Range) -> bool;
|
||||||
|
|
||||||
fn metrics_for_range(&self, range: TextRange) -> RunMetrics;
|
fn metrics_for_range(&self, range: Range) -> RunMetrics;
|
||||||
fn min_width_for_range(&self, range: TextRange) -> au;
|
fn min_width_for_range(&self, range: Range) -> au;
|
||||||
fn iter_natural_lines_for_range(&self, range: TextRange, f: fn&(TextRange) -> bool);
|
fn iter_natural_lines_for_range(&self, range: Range, f: fn&(Range) -> bool);
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TextRun : TextRunMethods {
|
impl TextRun : TextRunMethods {
|
||||||
pure fn glyphs(&self) -> &self/GlyphStore { &self.glyphs }
|
pure fn glyphs(&self) -> &self/GlyphStore { &self.glyphs }
|
||||||
|
|
||||||
pure fn range_is_trimmable_whitespace(&self, range: TextRange) -> bool {
|
pure fn range_is_trimmable_whitespace(&self, range: Range) -> bool {
|
||||||
let mut i = range.begin();
|
let mut i = range.begin();
|
||||||
while i < range.end() {
|
while i < range.end() {
|
||||||
// jump i to each new char
|
// jump i to each new char
|
||||||
|
@ -166,11 +75,11 @@ impl TextRun : TextRunMethods {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn metrics_for_range(&self, range: TextRange) -> RunMetrics {
|
fn metrics_for_range(&self, range: Range) -> RunMetrics {
|
||||||
self.font.measure_text(self, range)
|
self.font.measure_text(self, range)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn min_width_for_range(&self, range: TextRange) -> au {
|
fn min_width_for_range(&self, range: Range) -> au {
|
||||||
assert range.is_valid_for_string(self.text);
|
assert range.is_valid_for_string(self.text);
|
||||||
|
|
||||||
let mut max_piece_width = au(0);
|
let mut max_piece_width = au(0);
|
||||||
|
@ -181,10 +90,10 @@ impl TextRun : TextRunMethods {
|
||||||
return max_piece_width;
|
return max_piece_width;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn iter_natural_lines_for_range(&self, range: TextRange, f: fn(TextRange) -> bool) {
|
fn iter_natural_lines_for_range(&self, range: Range, f: fn(Range) -> bool) {
|
||||||
assert range.is_valid_for_string(self.text);
|
assert range.is_valid_for_string(self.text);
|
||||||
|
|
||||||
let clump = MutableTextRange(range.begin(), 0);
|
let clump = MutableRange(range.begin(), 0);
|
||||||
let mut in_clump = false;
|
let mut in_clump = false;
|
||||||
|
|
||||||
// clump non-linebreaks of nonzero length
|
// clump non-linebreaks of nonzero length
|
||||||
|
@ -209,10 +118,10 @@ impl TextRun : TextRunMethods {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn iter_indivisible_pieces_for_range(&self, range: TextRange, f: fn(TextRange) -> bool) {
|
fn iter_indivisible_pieces_for_range(&self, range: Range, f: fn(Range) -> bool) {
|
||||||
assert range.is_valid_for_string(self.text);
|
assert range.is_valid_for_string(self.text);
|
||||||
|
|
||||||
let clump = MutableTextRange(range.begin(), 0);
|
let clump = MutableRange(range.begin(), 0);
|
||||||
loop {
|
loop {
|
||||||
// find next non-whitespace byte index, then clump all whitespace before it.
|
// find next non-whitespace byte index, then clump all whitespace before it.
|
||||||
if clump.end() == range.end() { break }
|
if clump.end() == range.end() { break }
|
||||||
|
@ -291,7 +200,7 @@ fn test_iter_indivisible_pieces() {
|
||||||
let font = flib.get_test_font();
|
let font = flib.get_test_font();
|
||||||
let run = TextRun(font, copy text);
|
let run = TextRun(font, copy text);
|
||||||
let mut slices : ~[~str] = ~[];
|
let mut slices : ~[~str] = ~[];
|
||||||
for run.iter_indivisible_pieces_for_range(TextRange(0, text.len())) |subrange| {
|
for run.iter_indivisible_pieces_for_range(Range(0, text.len())) |subrange| {
|
||||||
slices.push(str::slice(text, subrange.begin(), subrange.length()));
|
slices.push(str::slice(text, subrange.begin(), subrange.length()));
|
||||||
}
|
}
|
||||||
assert slices == res;
|
assert slices == res;
|
||||||
|
|
91
src/servo/util/range.rs
Normal file
91
src/servo/util/range.rs
Normal file
|
@ -0,0 +1,91 @@
|
||||||
|
pub struct Range {
|
||||||
|
priv off: u16,
|
||||||
|
priv len: u16
|
||||||
|
}
|
||||||
|
|
||||||
|
pub pure fn Range(off: uint, len: uint) -> Range {
|
||||||
|
assert off <= u16::max_value as uint;
|
||||||
|
assert len <= u16::max_value as uint;
|
||||||
|
|
||||||
|
Range {
|
||||||
|
off: off as u16,
|
||||||
|
len: len as u16
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub impl Range {
|
||||||
|
pub pure fn begin() -> uint { self.off as uint }
|
||||||
|
pub pure fn length() -> uint { self.len as uint }
|
||||||
|
pub pure fn end() -> uint { (self.off as uint) + (self.len as uint) }
|
||||||
|
|
||||||
|
pub pure fn eachi(cb: fn&(uint) -> bool) {
|
||||||
|
do uint::range(self.off as uint,
|
||||||
|
(self.off as uint) + (self.len as uint)) |i| {
|
||||||
|
cb(i)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub pure fn is_valid_for_string(s: &str) -> bool {
|
||||||
|
self.begin() < s.len() && self.end() <= s.len() && self.length() <= s.len()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub pure fn shift_by(i: int) -> Range {
|
||||||
|
Range(((self.off as int) + i) as uint, self.len as uint)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub pure fn extend_by(i: int) -> Range {
|
||||||
|
Range(self.off as uint, ((self.len as int) + i) as uint)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub pure fn adjust_by(off_i: int, len_i: int) -> Range {
|
||||||
|
Range(((self.off as int) + off_i) as uint, ((self.len as int) + len_i) as uint)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct MutableRange {
|
||||||
|
priv mut off: uint,
|
||||||
|
priv mut len: uint
|
||||||
|
}
|
||||||
|
|
||||||
|
pure fn MutableRange(off: uint, len :uint) -> MutableRange {
|
||||||
|
MutableRange { off: off, len: len }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MutableRange {
|
||||||
|
pub pure fn begin() -> uint { self.off }
|
||||||
|
pub pure fn length() -> uint { self.len }
|
||||||
|
pub pure fn end() -> uint { self.off + self.len }
|
||||||
|
pub pure fn eachi(cb: fn&(uint) -> bool) {
|
||||||
|
do uint::range(self.off, self.off + self.len) |i| { cb(i) }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub pure fn as_immutable() -> Range {
|
||||||
|
Range(self.begin(), self.length())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub pure fn is_valid_for_string(s: &str) -> bool {
|
||||||
|
self.begin() < s.len() && self.end() <= s.len() && self.length() <= s.len()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn shift_by(i: int) {
|
||||||
|
self.off = ((self.off as int) + i) as uint;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn extend_by(i: int) {
|
||||||
|
self.len = ((self.len as int) + i) as uint;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn extend_to(i: uint) {
|
||||||
|
self.len = i - self.off;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn adjust_by(off_i: int, len_i: int) {
|
||||||
|
self.off = ((self.off as int) + off_i) as uint;
|
||||||
|
self.len = ((self.len as int) + len_i) as uint;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn reset(off_i: uint, len_i: uint) {
|
||||||
|
self.off = off_i;
|
||||||
|
self.len = len_i;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue