Skip to content

Commit 0dbe134

Browse files
committed
core: make swf::Rectangle Copy
`Rectangle<Twips>` is cheap to copy, being only 16 bytes, so requiring an explicit `.clone()` call is unnecessary ceremony. Has the nice side-effect of replacing some `RefCell`s by `Cell`s.
1 parent b4111ef commit 0dbe134

File tree

14 files changed

+80
-79
lines changed

14 files changed

+80
-79
lines changed

core/src/avm1/globals/movie_clip.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1449,7 +1449,7 @@ fn get_bounds<'gc>(
14491449
// the final matrix, but this matches Flash's behavior.
14501450
let to_global_matrix = movie_clip.local_to_global_matrix();
14511451
let to_target_matrix = target.global_to_local_matrix().unwrap_or_default();
1452-
let target_bounds = to_target_matrix * to_global_matrix * bounds.clone();
1452+
let target_bounds = to_target_matrix * to_global_matrix * bounds;
14531453

14541454
// If the bounds are invalid, the target space is identical to the origin space and
14551455
// use_new_invalid_bounds_value is true, the returned bounds use a specific invalid value.

core/src/debug_ui/display_object.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ impl DisplayObjectWindow {
120120
}
121121

122122
pub fn hovered_bounds(&self) -> Option<Rectangle<Twips>> {
123-
self.hovered_bounds.clone()
123+
self.hovered_bounds
124124
}
125125

126126
pub fn show<'gc>(

core/src/display_object.rs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1721,11 +1721,11 @@ pub trait TDisplayObject<'gc>:
17211721
}
17221722

17231723
fn scroll_rect(&self) -> Option<Rectangle<Twips>> {
1724-
self.base().scroll_rect.clone()
1724+
self.base().scroll_rect
17251725
}
17261726

17271727
fn next_scroll_rect(&self) -> Rectangle<Twips> {
1728-
self.base().next_scroll_rect.clone()
1728+
self.base().next_scroll_rect
17291729
}
17301730

17311731
fn set_next_scroll_rect(&self, gc_context: &Mutation<'gc>, rectangle: Rectangle<Twips>) {
@@ -1738,7 +1738,7 @@ pub trait TDisplayObject<'gc>:
17381738
}
17391739

17401740
fn scaling_grid(&self) -> Rectangle<Twips> {
1741-
self.base().scaling_grid.clone()
1741+
self.base().scaling_grid
17421742
}
17431743

17441744
fn set_scaling_grid(&self, gc_context: &Mutation<'gc>, rect: Rectangle<Twips>) {
@@ -2107,9 +2107,7 @@ pub trait TDisplayObject<'gc>:
21072107
fn pre_render(&self, context: &mut RenderContext<'_, 'gc>) {
21082108
let mut this = self.base_mut(context.gc());
21092109
this.clear_invalidate_flag();
2110-
this.scroll_rect = this
2111-
.has_scroll_rect()
2112-
.then(|| this.next_scroll_rect.clone());
2110+
this.scroll_rect = this.has_scroll_rect().then(|| this.next_scroll_rect);
21132111
}
21142112

21152113
fn render_self(&self, _context: &mut RenderContext<'_, 'gc>) {}

core/src/display_object/avm1_button.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -611,7 +611,7 @@ impl<'gc> TInteractiveObject<'gc> for Avm1Button<'gc> {
611611
// usually change on hover (children are swapped out),
612612
// which would cause the automatic tab order to change during tabbing.
613613
// That could potentially create a loop in the tab ordering (soft locking the tab).
614-
self.local_to_global_matrix() * self.0.cell.borrow().hit_bounds.clone()
614+
self.local_to_global_matrix() * self.0.cell.borrow().hit_bounds
615615
}
616616
}
617617

core/src/display_object/edit_text.rs

Lines changed: 33 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,9 @@ use ruffle_render::commands::CommandHandler;
4242
use ruffle_render::quality::StageQuality;
4343
use ruffle_render::transform::Transform;
4444
use ruffle_wstr::WStrToUtf8;
45-
use std::cell::RefCell;
45+
use std::cell::{Cell, Ref, RefMut};
4646
use std::collections::VecDeque;
47-
use std::{cell::Ref, cell::RefMut, sync::Arc};
47+
use std::sync::Arc;
4848
use swf::ColorTransform;
4949
use unic_segment::WordBoundIndices;
5050

@@ -118,16 +118,14 @@ pub struct EditTextData<'gc> {
118118
layout: Layout<'gc>,
119119

120120
/// The current intrinsic bounds of the text field.
121-
#[collect(require_static)]
122-
bounds: RefCell<Rectangle<Twips>>,
121+
bounds: Cell<Rectangle<Twips>>,
123122

124123
/// Lazily calculated autosize bounds.
125124
///
126125
/// When `None`, no new bounds should be applied.
127126
/// When `Some`, new bounds resulting from autosize are
128127
/// waiting to be applied, see [`EditText::apply_autosize_bounds`].
129-
#[collect(require_static)]
130-
autosize_lazy_bounds: RefCell<Option<Rectangle<Twips>>>,
128+
autosize_lazy_bounds: Cell<Option<Rectangle<Twips>>>,
131129

132130
/// The AVM1 object handle
133131
object: Option<AvmObject<'gc>>,
@@ -361,8 +359,8 @@ impl<'gc> EditText<'gc> {
361359
border_color: Color::BLACK,
362360
object: None,
363361
layout,
364-
bounds: RefCell::new(swf_tag.bounds().clone()),
365-
autosize_lazy_bounds: RefCell::new(None),
362+
bounds: Cell::new(*swf_tag.bounds()),
363+
autosize_lazy_bounds: Cell::new(None),
366364
autosize,
367365
variable: variable.map(|s| s.to_string_lossy(encoding)),
368366
bound_stage_object: None,
@@ -810,7 +808,7 @@ impl<'gc> EditText<'gc> {
810808
/// Returns the matrix for transforming from layout
811809
/// coordinate space into this object's local space.
812810
fn layout_to_local_matrix(self, data: &EditTextData) -> Matrix {
813-
let bounds = data.bounds.borrow();
811+
let bounds = data.bounds.get();
814812
Matrix::translate(
815813
bounds.x_min + Self::GUTTER - Twips::from_pixels(data.hscroll),
816814
bounds.y_min + Self::GUTTER - data.vertical_scroll_offset(),
@@ -920,7 +918,7 @@ impl<'gc> EditText<'gc> {
920918

921919
// Determine the internal width available for content layout.
922920
let content_width = if autosize == AutoSizeMode::None || is_word_wrap {
923-
Some(edit_text.bounds.borrow().width() - padding)
921+
Some(edit_text.bounds.get().width() - padding)
924922
} else {
925923
None
926924
};
@@ -942,7 +940,7 @@ impl<'gc> EditText<'gc> {
942940

943941
let text_size = edit_text.layout.text_size();
944942

945-
let mut autosize_bounds = edit_text.bounds.borrow().clone();
943+
let mut autosize_bounds = edit_text.bounds.get();
946944
if autosize != AutoSizeMode::None {
947945
if !is_word_wrap {
948946
// The edit text's bounds needs to have the padding baked in.
@@ -966,7 +964,7 @@ impl<'gc> EditText<'gc> {
966964
let height = text_size.height() + padding;
967965
autosize_bounds.set_height(height);
968966
}
969-
*edit_text.autosize_lazy_bounds.borrow_mut() = Some(autosize_bounds);
967+
edit_text.autosize_lazy_bounds.set(Some(autosize_bounds));
970968
drop(edit_text);
971969
self.invalidate_cached_bitmap(context.gc());
972970
}
@@ -995,7 +993,7 @@ impl<'gc> EditText<'gc> {
995993
pub fn apply_autosize_bounds(self) {
996994
let edit_text: Ref<'_, EditTextData<'gc>> = self.0.read();
997995
if let Some(bounds) = edit_text.autosize_lazy_bounds.take() {
998-
*edit_text.bounds.borrow_mut() = bounds;
996+
edit_text.bounds.set(bounds);
999997
// Note: We do not have to invalidate cache here.
1000998
// Cache has already been invalidated on relayout, and
1001999
// we will apply this anyway before render.
@@ -1020,7 +1018,7 @@ impl<'gc> EditText<'gc> {
10201018
}
10211019

10221020
let mut text_width = edit_text.layout.text_size().width();
1023-
let window_width = (edit_text.bounds.borrow().width() - Self::GUTTER * 2).max(Twips::ZERO);
1021+
let window_width = (edit_text.bounds.get().width() - Self::GUTTER * 2).max(Twips::ZERO);
10241022

10251023
if !edit_text.flags.contains(EditTextFlag::READ_ONLY) {
10261024
// input fields get extra space at the end
@@ -1047,7 +1045,7 @@ impl<'gc> EditText<'gc> {
10471045
}
10481046

10491047
let text_height = edit_text.layout.text_size().height();
1050-
let window_height = edit_text.bounds.borrow().height() - Self::GUTTER * 2;
1048+
let window_height = edit_text.bounds.get().height() - Self::GUTTER * 2;
10511049

10521050
// That's the y coordinate where the fully scrolled window begins.
10531051
// We have to find a line that's below this coordinate.
@@ -1076,7 +1074,7 @@ impl<'gc> EditText<'gc> {
10761074
let scroll_offset = lines
10771075
.get(edit_text.scroll - 1)
10781076
.map_or(Twips::ZERO, |l| l.offset_y());
1079-
let target = edit_text.bounds.borrow().height() + scroll_offset - Self::GUTTER * 2;
1077+
let target = edit_text.bounds.get().height() + scroll_offset - Self::GUTTER * 2;
10801078

10811079
// TODO Use binary search here
10821080
// Line before first line with extent greater than bounds.height() + line "scroll"'s offset
@@ -1250,7 +1248,7 @@ impl<'gc> EditText<'gc> {
12501248
// culls any other line which is not fully visible; masking is always used for left/right bounds
12511249
// TODO: also cull text that's simply out of screen, just like we cull whole DOs in render_self().
12521250
if origin.y() + Self::GUTTER - edit_text.vertical_scroll_offset()
1253-
> edit_text.bounds.borrow().height()
1251+
> edit_text.bounds.get().height()
12541252
{
12551253
return;
12561254
}
@@ -2304,7 +2302,7 @@ impl<'gc> EditText<'gc> {
23042302
let edit_text = self.0.read();
23052303

23062304
// Check bounds
2307-
let bounds = edit_text.bounds.borrow().clone().grow(-Self::GUTTER);
2305+
let bounds = edit_text.bounds.get().grow(-Self::GUTTER);
23082306
if !bounds.contains(position) {
23092307
return None;
23102308
}
@@ -2611,7 +2609,7 @@ impl<'gc> TDisplayObject<'gc> for EditText<'gc> {
26112609
fn self_bounds(&self) -> Rectangle<Twips> {
26122610
self.apply_autosize_bounds();
26132611

2614-
self.0.read().bounds.borrow().clone()
2612+
self.0.read().bounds.get()
26152613
}
26162614

26172615
fn pixel_bounds(&self) -> Rectangle<Twips> {
@@ -2621,7 +2619,7 @@ impl<'gc> TDisplayObject<'gc> for EditText<'gc> {
26212619
// are applied when reading anything related to bounds.
26222620
let old = self.0.read().autosize_lazy_bounds.take();
26232621
let bounds = self.world_bounds();
2624-
*self.0.read().autosize_lazy_bounds.borrow_mut() = old;
2622+
self.0.read().autosize_lazy_bounds.set(old);
26252623
bounds
26262624
}
26272625

@@ -2630,15 +2628,15 @@ impl<'gc> TDisplayObject<'gc> for EditText<'gc> {
26302628
self.apply_autosize_bounds();
26312629

26322630
let edit_text = self.0.read();
2633-
let offset = edit_text.bounds.borrow().x_min;
2631+
let offset = edit_text.bounds.get().x_min;
26342632
edit_text.base.base.x() + offset
26352633
}
26362634

26372635
fn set_x(&self, gc_context: &Mutation<'gc>, x: Twips) {
26382636
self.apply_autosize_bounds();
26392637

26402638
let mut edit_text = self.0.write(gc_context);
2641-
let offset = edit_text.bounds.borrow().x_min;
2639+
let offset = edit_text.bounds.get().x_min;
26422640
edit_text.base.base.set_x(x - offset);
26432641
drop(edit_text);
26442642
self.invalidate_cached_bitmap(gc_context);
@@ -2648,15 +2646,15 @@ impl<'gc> TDisplayObject<'gc> for EditText<'gc> {
26482646
self.apply_autosize_bounds();
26492647

26502648
let edit_text = self.0.read();
2651-
let offset = edit_text.bounds.borrow().y_min;
2649+
let offset = edit_text.bounds.get().y_min;
26522650
edit_text.base.base.y() + offset
26532651
}
26542652

26552653
fn set_y(&self, gc_context: &Mutation<'gc>, y: Twips) {
26562654
self.apply_autosize_bounds();
26572655

26582656
let mut edit_text = self.0.write(gc_context);
2659-
let offset = edit_text.bounds.borrow().y_min;
2657+
let offset = edit_text.bounds.get().y_min;
26602658
edit_text.base.base.set_y(y - offset);
26612659
drop(edit_text);
26622660
self.invalidate_cached_bitmap(gc_context);
@@ -2666,8 +2664,8 @@ impl<'gc> TDisplayObject<'gc> for EditText<'gc> {
26662664
self.apply_autosize_bounds();
26672665

26682666
let edit_text = self.0.read();
2669-
let bounds = edit_text.bounds.borrow();
2670-
(edit_text.base.base.transform.matrix * bounds.clone())
2667+
let bounds = edit_text.bounds.get();
2668+
(edit_text.base.base.transform.matrix * bounds)
26712669
.width()
26722670
.to_pixels()
26732671
}
@@ -2676,10 +2674,8 @@ impl<'gc> TDisplayObject<'gc> for EditText<'gc> {
26762674
self.apply_autosize_bounds();
26772675

26782676
let mut edit_text = self.0.write(context.gc());
2679-
edit_text
2680-
.bounds
2681-
.borrow_mut()
2682-
.set_width(Twips::from_pixels(value));
2677+
let bounds = &edit_text.bounds;
2678+
bounds.set(bounds.get().with_width(Twips::from_pixels(value)));
26832679
edit_text.base.base.set_transformed_by_script(true);
26842680
drop(edit_text);
26852681
self.relayout(context);
@@ -2689,8 +2685,8 @@ impl<'gc> TDisplayObject<'gc> for EditText<'gc> {
26892685
self.apply_autosize_bounds();
26902686

26912687
let edit_text = self.0.read();
2692-
let bounds = edit_text.bounds.borrow();
2693-
(edit_text.base.base.transform.matrix * bounds.clone())
2688+
let bounds = edit_text.bounds.get();
2689+
(edit_text.base.base.transform.matrix * bounds)
26942690
.height()
26952691
.to_pixels()
26962692
}
@@ -2699,10 +2695,8 @@ impl<'gc> TDisplayObject<'gc> for EditText<'gc> {
26992695
self.apply_autosize_bounds();
27002696

27012697
let mut edit_text = self.0.write(context.gc());
2702-
edit_text
2703-
.bounds
2704-
.borrow_mut()
2705-
.set_height(Twips::from_pixels(value));
2698+
let bounds = &edit_text.bounds;
2699+
bounds.set(bounds.get().with_height(Twips::from_pixels(value)));
27062700
edit_text.base.base.set_transformed_by_script(true);
27072701
drop(edit_text);
27082702
self.relayout(context);
@@ -2746,22 +2740,22 @@ impl<'gc> TDisplayObject<'gc> for EditText<'gc> {
27462740
if self.is_device_font() {
27472741
self.draw_device_text_box(
27482742
context,
2749-
edit_text.bounds.borrow().clone(),
2743+
edit_text.bounds.get(),
27502744
background_color,
27512745
border_color,
27522746
);
27532747
} else {
27542748
self.draw_text_box(
27552749
context,
2756-
edit_text.bounds.borrow().clone(),
2750+
edit_text.bounds.get(),
27572751
background_color,
27582752
border_color,
27592753
);
27602754
}
27612755
}
27622756

27632757
context.commands.push_mask();
2764-
let mask = Matrix::create_box_from_rectangle(&edit_text.bounds.borrow());
2758+
let mask = Matrix::create_box_from_rectangle(&edit_text.bounds.get());
27652759
context.commands.draw_rect(
27662760
Color::WHITE,
27672761
context.transform_stack.transform().matrix * mask,

core/src/display_object/graphic.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ impl<'gc> Graphic<'gc> {
5151
let library = context.library.library_for_movie(movie.clone()).unwrap();
5252
let shared = GraphicShared {
5353
id: swf_shape.id,
54-
bounds: swf_shape.shape_bounds.clone(),
54+
bounds: swf_shape.shape_bounds,
5555
render_handle: Some(
5656
context
5757
.renderer
@@ -140,9 +140,9 @@ impl<'gc> TDisplayObject<'gc> for Graphic<'gc> {
140140

141141
fn self_bounds(&self) -> Rectangle<Twips> {
142142
if let Some(drawing) = &self.0.read().drawing {
143-
drawing.self_bounds().clone()
143+
drawing.self_bounds()
144144
} else {
145-
self.0.read().shared.bounds.clone()
145+
self.0.read().shared.bounds
146146
}
147147
}
148148

core/src/display_object/morph_shape.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ impl<'gc> TDisplayObject<'gc> for MorphShape<'gc> {
152152
let ratio = self.0.ratio.get();
153153
let shared = self.0.shared.get();
154154
let frame = shared.get_frame(ratio);
155-
frame.bounds.clone()
155+
frame.bounds
156156
}
157157

158158
fn hit_test_shape(
@@ -366,8 +366,8 @@ impl MorphShapeShared {
366366
let shape = swf::Shape {
367367
version: 4,
368368
id: 0,
369-
shape_bounds: bounds.clone(),
370-
edge_bounds: bounds.clone(),
369+
shape_bounds: bounds,
370+
edge_bounds: bounds,
371371
flags: swf::ShapeFlag::HAS_SCALING_STROKES,
372372
styles,
373373
shape,

core/src/display_object/movie_clip.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2697,9 +2697,7 @@ impl<'gc> TDisplayObject<'gc> for MovieClip<'gc> {
26972697
}
26982698

26992699
fn self_bounds(&self) -> Rectangle<Twips> {
2700-
self.drawing()
2701-
.map(|d| d.self_bounds().clone())
2702-
.unwrap_or_default()
2700+
self.drawing().map(|d| d.self_bounds()).unwrap_or_default()
27032701
}
27042702

27052703
fn hit_test_shape(

core/src/display_object/stage.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -451,7 +451,7 @@ impl<'gc> Stage<'gc> {
451451
}
452452

453453
pub fn view_bounds(self) -> Rectangle<Twips> {
454-
self.0.read().view_bounds.clone()
454+
self.0.read().view_bounds
455455
}
456456

457457
pub fn show_menu(self) -> bool {

core/src/display_object/text.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ impl<'gc> Text<'gc> {
5252
TextShared {
5353
swf,
5454
id: tag.id,
55-
bounds: tag.bounds.clone(),
55+
bounds: tag.bounds,
5656
text_transform: tag.matrix.into(),
5757
text_blocks: tag.records.clone(),
5858
},
@@ -194,7 +194,7 @@ impl<'gc> TDisplayObject<'gc> for Text<'gc> {
194194
}
195195

196196
fn self_bounds(&self) -> Rectangle<Twips> {
197-
self.0.read().shared.bounds.clone()
197+
self.0.read().shared.bounds
198198
}
199199

200200
fn hit_test_shape(

0 commit comments

Comments
 (0)