text: Add start and end text positions to LayoutLine

By adding start and end positions to LayoutLine, it's now easy to
calculate the line length, get its text, or search through lines.
This commit is contained in:
Kamil Jarosz 2024-06-27 15:21:19 +02:00 committed by Nathan Adams
parent dcafb3d291
commit 8569df9503
1 changed files with 57 additions and 19 deletions

View File

@ -13,7 +13,7 @@ use ruffle_render::shape_utils::DrawCommand;
use std::cmp::{max, min};
use std::fmt::{Debug, Formatter};
use std::mem;
use std::ops::Deref;
use std::ops::{Deref, Range};
use std::slice::Iter;
use std::sync::Arc;
use swf::{Point, Twips};
@ -345,7 +345,7 @@ impl<'a, 'gc> LayoutContext<'a, 'gc> {
line_bounds += Position::from((left_adjustment + align_adjustment, Twips::ZERO));
line_bounds += Size::from((Twips::ZERO, font_leading_adjustment));
self.flush_line();
self.flush_line(end);
if let Some(eb) = &mut self.exterior_bounds {
*eb += line_bounds;
@ -354,24 +354,39 @@ impl<'a, 'gc> LayoutContext<'a, 'gc> {
}
}
fn flush_line(&mut self) {
if !self.boxes.is_empty() {
let boxes = mem::take(&mut self.boxes);
let bounds = boxes
.iter()
.fold(boxes[0].bounds, |bounds, b| bounds + b.bounds);
self.lines.push(LayoutLine {
index: self.current_line_index,
bounds,
boxes,
});
self.current_line_index += 1;
fn flush_line(&mut self, end: usize) {
if self.boxes.is_empty() {
return;
}
if let Some(lb) = &mut self.bounds {
*lb += bounds;
} else {
self.bounds = Some(bounds);
}
let boxes = mem::take(&mut self.boxes);
let first_box = boxes.first().unwrap();
let start = first_box.start();
let bounds = boxes
.iter()
.fold(first_box.bounds, |bounds, b| bounds + b.bounds);
// Update last line's end position to take into account the delimiter.
// It's easier to do it here, but maybe after some refactors this update
// will not be needed, and the end position will be calculated correctly.
if let Some(last_line) = self.lines.last_mut() {
last_line.end = start;
}
self.lines.push(LayoutLine {
index: self.current_line_index,
bounds,
start,
end,
boxes,
});
self.current_line_index += 1;
// Update layout bounds
if let Some(lb) = &mut self.bounds {
*lb += bounds;
} else {
self.bounds = Some(bounds);
}
}
@ -775,6 +790,13 @@ pub struct LayoutLine<'gc> {
#[collect(require_static)]
bounds: BoxBounds<Twips>,
/// The start position of the line (inclusive).
start: usize,
/// The end position of the line (exclusive).
/// This position includes the line delimiter.
end: usize,
/// Layout boxes contained within this line.
boxes: Vec<LayoutBox<'gc>>,
}
@ -788,6 +810,22 @@ impl<'gc> LayoutLine<'gc> {
self.bounds
}
pub fn start(&self) -> usize {
self.start
}
pub fn end(&self) -> usize {
self.end
}
pub fn len(&self) -> usize {
self.end() - self.start()
}
pub fn text_range(&self) -> Range<usize> {
self.start..self.end
}
pub fn offset_y(&self) -> Twips {
self.bounds().offset_y()
}