From 89cc0eb31d2fd38a545cefccb0b44e4a22807d5e Mon Sep 17 00:00:00 2001 From: Nathan Adams Date: Sun, 20 Aug 2023 21:25:18 +0200 Subject: [PATCH] core: EditText::is_link_at doesn't need to evaluate fonts --- core/src/display_object/edit_text.rs | 33 ++++++++++++++++++---------- core/src/html/dimensions.rs | 13 +++++++++++ core/src/html/layout.rs | 14 ++++++++++++ 3 files changed, 48 insertions(+), 12 deletions(-) diff --git a/core/src/display_object/edit_text.rs b/core/src/display_object/edit_text.rs index 5a90fa014..7efab597a 100644 --- a/core/src/display_object/edit_text.rs +++ b/core/src/display_object/edit_text.rs @@ -21,7 +21,9 @@ use crate::display_object::{DisplayObjectBase, DisplayObjectPtr, TDisplayObject} use crate::drawing::Drawing; use crate::events::{ClipEvent, ClipEventResult, TextControlCode}; use crate::font::{round_down_to_pixel, Glyph, TextRenderSettings}; -use crate::html::{BoxBounds, FormatSpans, LayoutBox, LayoutContent, LayoutMetrics, TextFormat}; +use crate::html::{ + BoxBounds, FormatSpans, LayoutBox, LayoutContent, LayoutMetrics, Position, TextFormat, +}; use crate::prelude::*; use crate::string::{utils as string_utils, AvmString, SwfStrExt as _, WStr, WString}; use crate::tag_utils::SwfMovie; @@ -1181,7 +1183,11 @@ impl<'gc> EditText<'gc> { position.x += Twips::from_pixels(Self::INTERNAL_PADDING) + Twips::from_pixels(text.hscroll); position.y += Twips::from_pixels(Self::INTERNAL_PADDING) + text.vertical_scroll_offset(); - for layout_box in text.layout.iter() { + for layout_box in text.layout.iter().filter(|layout| { + layout + .bounds() + .contains(Position::from((position.x, position.y))) + }) { let origin = layout_box.bounds().origin(); let mut matrix = Matrix::translate(origin.x(), origin.y()); matrix = matrix.inverse().expect("Invertible layout matrix"); @@ -1669,16 +1675,19 @@ impl<'gc> EditText<'gc> { } fn is_link_at(self, point: Point) -> bool { - if let Some(position) = self.screen_position_to_index(point) { - if let Some((span_index, _)) = - self.0.read().text_spans.resolve_position_as_span(position) - { - if let Some(span) = self.0.read().text_spans.span(span_index) { - return !span.url.is_empty(); - } - } - } - false + let text = self.0.read(); + let Some(mut position) = self.global_to_local(point) else { + return false; + }; + position.x += Twips::from_pixels(Self::INTERNAL_PADDING) + Twips::from_pixels(text.hscroll); + position.y += Twips::from_pixels(Self::INTERNAL_PADDING) + text.vertical_scroll_offset(); + + text.layout.iter().any(|layout| { + layout.is_link() + && layout + .bounds() + .contains(Position::from((position.x, position.y))) + }) } } diff --git a/core/src/html/dimensions.rs b/core/src/html/dimensions.rs index 00332c5b3..3f06e8258 100644 --- a/core/src/html/dimensions.rs +++ b/core/src/html/dimensions.rs @@ -205,6 +205,19 @@ where } } +#[allow(dead_code)] +impl BoxBounds +where + T: Copy + std::cmp::PartialOrd, +{ + pub fn contains(&self, local_position: Position) -> bool { + local_position.x >= self.offset_x + && local_position.x <= self.extent_x + && local_position.y >= self.offset_y + && local_position.y <= self.extent_y + } +} + #[allow(dead_code)] impl BoxBounds where diff --git a/core/src/html/layout.rs b/core/src/html/layout.rs index 81b563be4..e86bc29e5 100644 --- a/core/src/html/layout.rs +++ b/core/src/html/layout.rs @@ -886,6 +886,20 @@ impl<'gc> LayoutBox<'gc> { &self.content } + pub fn is_link(&self) -> bool { + match &self.content { + LayoutContent::Text { + text_format: TextFormat { url: Some(url), .. }, + .. + } => url.len() > 0, + LayoutContent::Bullet { + text_format: TextFormat { url: Some(url), .. }, + .. + } => url.len() > 0, + _ => false, + } + } + /// Returns a reference to the text this box contains, as well as font /// rendering parameters, if the layout box has any. pub fn as_renderable_text<'a>(