diff --git a/core/src/avm1/globals/text_field.rs b/core/src/avm1/globals/text_field.rs index 5aaeba604b7d..46a2bcde283d 100644 --- a/core/src/avm1/globals/text_field.rs +++ b/core/src/avm1/globals/text_field.rs @@ -122,6 +122,7 @@ pub fn create_proto<'gc>( with_text_field_props!( object, gc_context, fn_proto, "autoSize" => [auto_size, set_auto_size], + "background" => [background, set_background], "backgroundColor" => [background_color, set_background_color], "border" => [border, set_border], "borderColor" => [border_color, set_border_color], @@ -391,6 +392,23 @@ pub fn set_html_text<'gc>( Ok(()) } +pub fn background<'gc>( + this: EditText<'gc>, + _activation: &mut Activation<'_, 'gc, '_>, +) -> Result, Error<'gc>> { + Ok(this.has_background().into()) +} + +pub fn set_background<'gc>( + this: EditText<'gc>, + activation: &mut Activation<'_, 'gc, '_>, + value: Value<'gc>, +) -> Result<(), Error<'gc>> { + let has_background = value.as_bool(activation.current_swf_version()); + this.set_has_background(activation.context.gc_context, has_background); + Ok(()) +} + pub fn background_color<'gc>( this: EditText<'gc>, _activation: &mut Activation<'_, 'gc, '_>, diff --git a/core/src/display_object/edit_text.rs b/core/src/display_object/edit_text.rs index 8f9a1cffd99c..1c01dad10ede 100644 --- a/core/src/display_object/edit_text.rs +++ b/core/src/display_object/edit_text.rs @@ -90,7 +90,10 @@ pub struct EditTextData<'gc> { /// If this is a password input field is_password: bool, - /// The color of the background fill. Only applied when has_border. + /// If the text field should have a background. Only applied when has_border. + has_background: bool, + + /// The color of the background fill. Only applied when has_border and has_background. background_color: u32, /// If the text field should have a border. @@ -195,6 +198,7 @@ impl<'gc> EditText<'gc> { swf_tag.is_device_font, ); + let has_background = false; let background_color = 0xFFFFFF; // Default is white let has_border = swf_tag.has_border; let border_color = 0; // Default is black @@ -252,6 +256,7 @@ impl<'gc> EditText<'gc> { is_editable, is_word_wrap, is_password, + has_background, background_color, has_border, border_color, @@ -513,6 +518,15 @@ impl<'gc> EditText<'gc> { self.relayout(context); } + pub fn has_background(self) -> bool { + self.0.read().has_background + } + + pub fn set_has_background(self, context: MutationContext<'gc, '_>, has_background: bool) { + self.0.write(context).has_background = has_background; + self.redraw_border(context); + } + pub fn background_color(self) -> u32 { self.0.read().background_color } @@ -673,12 +687,16 @@ impl<'gc> EditText<'gc> { Twips::new(1), swf::Color::from_rgb(border_color, 0xFF), ))); - write - .drawing - .set_fill_style(Some(swf::FillStyle::Color(swf::Color::from_rgb( - background_color, - 0xFF, - )))); + if write.has_background { + write + .drawing + .set_fill_style(Some(swf::FillStyle::Color(swf::Color::from_rgb( + background_color, + 0xFF, + )))); + } else { + write.drawing.set_fill_style(None); + } write.drawing.draw_command(DrawCommand::MoveTo { x: Twips::new(0), y: Twips::new(0), @@ -743,38 +761,39 @@ impl<'gc> EditText<'gc> { AutoSizeMode::None => {} AutoSizeMode::Left => { if !is_word_wrap { - let old_x = edit_text.bounds.x_min; - edit_text.bounds.set_x(old_x); - edit_text.base.set_x(old_x.to_pixels()); edit_text.bounds.set_width(intrinsic_bounds.width()); } edit_text.bounds.set_height(intrinsic_bounds.height()); edit_text.base.set_transformed_by_script(true); + drop(edit_text); + self.redraw_border(context.gc_context); } AutoSizeMode::Center => { if !is_word_wrap { - let old_x = edit_text.bounds.x_min; - let new_x = (intrinsic_bounds.width() - old_x) / 2; - edit_text.bounds.set_x(new_x); - edit_text.base.set_x(new_x.to_pixels()); + let center = (edit_text.bounds.x_min + edit_text.bounds.x_max) / 2; + edit_text + .bounds + .set_x(center - intrinsic_bounds.width() / 2); edit_text.bounds.set_width(intrinsic_bounds.width()); } edit_text.bounds.set_height(intrinsic_bounds.height()); edit_text.base.set_transformed_by_script(true); + drop(edit_text); + self.redraw_border(context.gc_context); } AutoSizeMode::Right => { if !is_word_wrap { - let old_x = edit_text.bounds.x_min; - let new_x = intrinsic_bounds.width() - old_x; + let new_x = edit_text.bounds.x_max - intrinsic_bounds.width(); edit_text.bounds.set_x(new_x); - edit_text.base.set_x(new_x.to_pixels()); edit_text.bounds.set_width(intrinsic_bounds.width()); } edit_text.bounds.set_height(intrinsic_bounds.height()); edit_text.base.set_transformed_by_script(true); + drop(edit_text); + self.redraw_border(context.gc_context); } } } diff --git a/core/tests/regression_tests.rs b/core/tests/regression_tests.rs index 9688f81bdab7..3073f9a42864 100644 --- a/core/tests/regression_tests.rs +++ b/core/tests/regression_tests.rs @@ -531,6 +531,7 @@ swf_tests_approx! { (parse_float, "avm1/parse_float", 1, max_relative = 5.0 * f64::EPSILON), (edittext_letter_spacing, "avm1/edittext_letter_spacing", 1, epsilon = 15.0), // TODO: Discrepancy in wrapping in letterSpacing = 0.1 test. (edittext_align, "avm1/edittext_align", 1, epsilon = 3.0), + (edittext_autosize, "avm1/edittext_autosize", 1, epsilon = 4.0), // TODO Flash has _width higher by 4.0, probably padding logic mistake (edittext_margins, "avm1/edittext_margins", 1, epsilon = 5.0), // TODO: Discrepancy in wrapping. (edittext_tab_stops, "avm1/edittext_tab_stops", 1, epsilon = 5.0), (edittext_bullet, "avm1/edittext_bullet", 1, epsilon = 3.0), diff --git a/core/tests/swfs/avm1/edittext_autosize/output.txt b/core/tests/swfs/avm1/edittext_autosize/output.txt new file mode 100644 index 000000000000..ad6f83c7a411 --- /dev/null +++ b/core/tests/swfs/avm1/edittext_autosize/output.txt @@ -0,0 +1,72 @@ +// no autosize +//my_txt1._x +50 +//my_txt1._width +100 +//my_txt1._width + my_txt1._x +150 +//my_txt1.textWidth +195 +// xMin: +50 +// xMax: +150 +// yMin: +40 +// yMax: +70 + +// autosize left +//my_txt2._x +50 +//my_txt2._width +199.9 +//my_txt2._width + my_txt2._x +249.9 +//my_txt2.textWidth +195 +// xMin: +50 +// xMax: +249.9 +// yMin: +80 +// yMax: +102.3 + +// autosize center +//my_txt3._x +0.05 +//my_txt3._width +199.9 +//my_txt3._width + my_txt3._x +199.95 +//my_txt3.textWidth +195 +// xMin: +0.05 +// xMax: +199.95 +// yMin: +120 +// yMax: +142.3 + +// autosize right +//my_txt4._x +-49.9 +//my_txt4._width +199.9 +//my_txt4._width + my_txt4._x +150 +//my_txt4.textWidth +195 +// xMin: +-49.9 +// xMax: +150 +// yMin: +160 +// yMax: +182.3 + diff --git a/core/tests/swfs/avm1/edittext_autosize/test.fla b/core/tests/swfs/avm1/edittext_autosize/test.fla new file mode 100644 index 000000000000..c0ed532d6d19 Binary files /dev/null and b/core/tests/swfs/avm1/edittext_autosize/test.fla differ diff --git a/core/tests/swfs/avm1/edittext_autosize/test.swf b/core/tests/swfs/avm1/edittext_autosize/test.swf new file mode 100644 index 000000000000..810657d0312e Binary files /dev/null and b/core/tests/swfs/avm1/edittext_autosize/test.swf differ diff --git a/core/tests/swfs/avm1/textfield_properties/output.txt b/core/tests/swfs/avm1/textfield_properties/output.txt index a75134c517ba..47fe0542d717 100644 --- a/core/tests/swfs/avm1/textfield_properties/output.txt +++ b/core/tests/swfs/avm1/textfield_properties/output.txt @@ -38,3 +38,8 @@ undefined // txt.textColor: 4210752 +// txt.background: +false +// txt.background = true: +true + diff --git a/core/tests/swfs/avm1/textfield_properties/test.fla b/core/tests/swfs/avm1/textfield_properties/test.fla index 2b5ea65a71a0..013c187866fd 100644 Binary files a/core/tests/swfs/avm1/textfield_properties/test.fla and b/core/tests/swfs/avm1/textfield_properties/test.fla differ diff --git a/core/tests/swfs/avm1/textfield_properties/test.swf b/core/tests/swfs/avm1/textfield_properties/test.swf index cbb61f370946..8fc2131e795a 100644 Binary files a/core/tests/swfs/avm1/textfield_properties/test.swf and b/core/tests/swfs/avm1/textfield_properties/test.swf differ