mirror of
https://github.com/servo/servo.git
synced 2025-08-06 06:00:15 +01:00
Finish conversion to using only character ranges. We don't crash on multi-byte characters any more.
This commit is contained in:
parent
ddb4e5e17d
commit
29e46273f9
4 changed files with 31 additions and 30 deletions
|
@ -631,13 +631,9 @@ impl GlyphStore {
|
|||
}
|
||||
|
||||
pure fn char_is_newline(i: uint) -> bool {
|
||||
if i >= self.entry_buffer.len() {
|
||||
error!("char_is_newline: beyond entry buffer!");
|
||||
false
|
||||
} else {
|
||||
assert i < self.entry_buffer.len();
|
||||
self.entry_buffer[i].char_is_newline()
|
||||
}
|
||||
}
|
||||
|
||||
pure fn is_ligature_start(i: uint) -> bool {
|
||||
assert i < self.entry_buffer.len();
|
||||
|
|
|
@ -59,15 +59,16 @@ impl TextRun {
|
|||
static fn compute_potential_breaks(text: &str, glyphs: &mut GlyphStore) {
|
||||
// TODO(Issue #230): do a better job. See Gecko's LineBreaker.
|
||||
|
||||
let mut i = 0u;
|
||||
let mut byte_i = 0u;
|
||||
let mut char_j = 0u;
|
||||
let mut prev_is_whitespace = false;
|
||||
while i < text.len() {
|
||||
let {ch, next} = str::char_range_at(text, i);
|
||||
while byte_i < text.len() {
|
||||
let {ch, next} = str::char_range_at(text, byte_i);
|
||||
// set char properties.
|
||||
match ch {
|
||||
' ' => { glyphs.set_char_is_space(i); },
|
||||
'\t' => { glyphs.set_char_is_tab(i); },
|
||||
'\n' => { glyphs.set_char_is_newline(i); },
|
||||
' ' => { glyphs.set_char_is_space(char_j); },
|
||||
'\t' => { glyphs.set_char_is_tab(char_j); },
|
||||
'\n' => { glyphs.set_char_is_newline(char_j); },
|
||||
_ => {}
|
||||
}
|
||||
|
||||
|
@ -76,21 +77,22 @@ impl TextRun {
|
|||
match ch {
|
||||
' ' | '\t' | '\n' => {},
|
||||
_ => {
|
||||
glyphs.set_can_break_before(i, BreakTypeNormal);
|
||||
glyphs.set_can_break_before(char_j, BreakTypeNormal);
|
||||
prev_is_whitespace = false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
match ch {
|
||||
' ' | '\t' | '\n' => {
|
||||
glyphs.set_can_break_before(i, BreakTypeNormal);
|
||||
glyphs.set_can_break_before(char_j, BreakTypeNormal);
|
||||
prev_is_whitespace = true;
|
||||
},
|
||||
_ => { }
|
||||
}
|
||||
}
|
||||
|
||||
i = next;
|
||||
byte_i = next;
|
||||
char_j += 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -102,18 +104,14 @@ impl TextRun {
|
|||
}
|
||||
}
|
||||
|
||||
pure fn char_len() -> uint { self.glyphs.entry_buffer.len() }
|
||||
pure fn glyphs(&self) -> &self/GlyphStore { &self.glyphs }
|
||||
|
||||
pure fn range_is_trimmable_whitespace(&self, range: &const Range) -> bool {
|
||||
let mut i = range.begin();
|
||||
while i < range.end() {
|
||||
// jump i to each new char
|
||||
let {ch, next} = str::char_range_at(self.text, i);
|
||||
match ch {
|
||||
' ' | '\t' | '\r' => {},
|
||||
_ => { return false; }
|
||||
}
|
||||
i = next;
|
||||
for range.eachi |i| {
|
||||
if !self.glyphs.char_is_space(i) &&
|
||||
!self.glyphs.char_is_tab(i) &&
|
||||
!self.glyphs.char_is_newline(i) { return false; }
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -124,7 +122,9 @@ impl TextRun {
|
|||
|
||||
fn min_width_for_range(&self, range: &const Range) -> Au {
|
||||
let mut max_piece_width = Au(0);
|
||||
debug!("iterating outer range %?", range);
|
||||
for self.iter_indivisible_pieces_for_range(range) |piece_range| {
|
||||
debug!("iterated on %?", piece_range);
|
||||
let metrics = self.font.measure_text(self, piece_range);
|
||||
max_piece_width = Au::max(max_piece_width, metrics.advance_width);
|
||||
}
|
||||
|
|
|
@ -246,7 +246,7 @@ priv impl TextRunScanner {
|
|||
debug!("TextRunScanner: pushing single text box in range: %?", self.clump);
|
||||
let new_box = layout::text::adapt_textbox_with_range(old_box.d(),
|
||||
run,
|
||||
&const Range::new(0, run.text.len()));
|
||||
&const Range::new(0, run.char_len()));
|
||||
out_boxes.push(new_box);
|
||||
},
|
||||
(false, true) => {
|
||||
|
@ -263,14 +263,15 @@ priv impl TextRunScanner {
|
|||
transform_text(in_boxes[idx].raw_text(), compression)
|
||||
});
|
||||
|
||||
// next, concatenate all of the transformed strings together, saving the new text indices
|
||||
|
||||
// TODO(Issue #118): use a rope, simply give ownership of nonzero strs to rope
|
||||
// next, concatenate all of the transformed strings together, saving the new char indices
|
||||
let mut run_str : ~str = ~"";
|
||||
let new_ranges : DVec<Range> = DVec();
|
||||
let mut char_total = 0u;
|
||||
for uint::range(0, transformed_strs.len()) |i| {
|
||||
new_ranges.push(Range::new(run_str.len(), transformed_strs[i].len()));
|
||||
let added_chars = str::char_len(transformed_strs[i]);
|
||||
new_ranges.push(Range::new(char_total, added_chars));
|
||||
str::push_str(&mut run_str, transformed_strs[i]);
|
||||
char_total += added_chars;
|
||||
}
|
||||
|
||||
// create the run, then make new boxes with the run and adjusted text indices
|
||||
|
|
|
@ -19,8 +19,12 @@ pub fn TextBoxData(run: @TextRun, range: &const Range) -> TextBoxData {
|
|||
|
||||
pub fn adapt_textbox_with_range(box_data: &RenderBoxData, run: @TextRun,
|
||||
range: &const Range) -> @RenderBox {
|
||||
assert range.begin() < run.char_len();
|
||||
assert range.end() <= run.char_len();
|
||||
assert range.length() > 0;
|
||||
|
||||
debug!("Creating textbox with span: (strlen=%u, off=%u, len=%u) of textrun: %s",
|
||||
run.text.len(), range.begin(), range.length(), run.text);
|
||||
run.char_len(), range.begin(), range.length(), run.text);
|
||||
let new_box_data = copy *box_data;
|
||||
let new_text_data = TextBoxData(run, range);
|
||||
let metrics = run.metrics_for_range(range);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue