text: Refactor EditText.layout_metrics

This refactor takes advantage of the
new layout structure to simplify code.
This commit is contained in:
Kamil Jarosz 2024-06-19 18:16:04 +02:00 committed by Nathan Adams
parent 50ade23779
commit bfbd2dbd19
1 changed files with 27 additions and 43 deletions

View File

@ -32,6 +32,7 @@ use crate::vminterface::{AvmObject, Instantiator};
use chrono::DateTime; use chrono::DateTime;
use chrono::Utc; use chrono::Utc;
use core::fmt; use core::fmt;
use either::Either;
use gc_arena::{Collect, Gc, GcCell, Mutation}; use gc_arena::{Collect, Gc, GcCell, Mutation};
use ruffle_render::commands::CommandHandler; use ruffle_render::commands::CommandHandler;
use ruffle_render::shape_utils::DrawCommand; use ruffle_render::shape_utils::DrawCommand;
@ -1865,59 +1866,42 @@ impl<'gc> EditText<'gc> {
/// Calculate the layout metrics for a given line. /// Calculate the layout metrics for a given line.
/// ///
/// Returns None if the line does not exist or there is not enough data /// Returns `None` if the line does not exist or there is not enough data
/// about the line to calculate metrics with. /// about the line to calculate metrics with.
pub fn layout_metrics(self, line: Option<usize>) -> Option<LayoutMetrics> { pub fn layout_metrics(self, line: Option<usize>) -> Option<LayoutMetrics> {
let read = self.0.read(); let layout = &self.0.read().layout;
let line = line.and_then(|line| read.layout.lines().get(line)); let line = line.and_then(|line| layout.lines().get(line));
let mut union_bounds = None;
let mut font = None;
let mut text_format = None;
for layout_box in read.layout.boxes_iter() { let (boxes, union_bounds) = if let Some(line) = line {
if let Some(line) = line { (Either::Left(line.boxes_iter()), line.bounds())
if layout_box.bounds().offset_y() < line.offset() } else {
|| layout_box.bounds().extent_y() > line.extent() (Either::Right(layout.boxes_iter()), layout.bounds())
{ };
continue;
let mut first_font = None;
let mut first_format = None;
for layout_box in boxes {
match layout_box.content() {
LayoutContent::Text {
font, text_format, ..
} }
} | LayoutContent::Bullet {
font, text_format, ..
if let Some(bounds) = &mut union_bounds { } => {
*bounds += layout_box.bounds(); first_font = Some(font);
} else { first_format = Some(text_format);
union_bounds = Some(layout_box.bounds()); break;
}
if font.is_none() {
match layout_box.content() {
LayoutContent::Text {
font: box_font,
text_format: box_text_format,
..
} => {
font = Some(box_font);
text_format = Some(box_text_format);
}
LayoutContent::Bullet {
font: box_font,
text_format: box_text_format,
..
} => {
font = Some(box_font);
text_format = Some(box_text_format);
}
LayoutContent::Drawing { .. } => {}
} }
LayoutContent::Drawing { .. } => {}
} }
} }
let union_bounds = union_bounds?; let font = first_font?;
let font = font?; let text_format = first_format?;
let size = Twips::from_pixels(text_format?.size?); let size = Twips::from_pixels(text_format.size?);
let ascent = font.get_baseline_for_height(size); let ascent = font.get_baseline_for_height(size);
let descent = font.get_descent_for_height(size); let descent = font.get_descent_for_height(size);
let leading = Twips::from_pixels(text_format?.leading?); let leading = Twips::from_pixels(text_format.leading?);
Some(LayoutMetrics { Some(LayoutMetrics {
ascent, ascent,