@@ -35,6 +35,7 @@ use core::fmt;
3535use gc_arena:: barrier:: unlock;
3636use gc_arena:: { Collect , Gc , Lock , Mutation , RefLock } ;
3737use ruffle_macros:: istr;
38+ use ruffle_render:: commands:: Command as RenderCommand ;
3839use ruffle_render:: commands:: CommandHandler ;
3940use ruffle_render:: quality:: StageQuality ;
4041use ruffle_render:: transform:: Transform ;
@@ -1100,9 +1101,9 @@ impl<'gc> EditText<'gc> {
11001101 /// Render lines according to the given procedure.
11011102 ///
11021103 /// This skips invisible lines.
1103- fn render_lines < F > ( self , context : & mut RenderContext < ' _ , ' gc > , f : F )
1104+ fn render_lines < F > ( self , context : & mut RenderContext < ' _ , ' gc > , mut f : F )
11041105 where
1105- F : Fn ( & mut RenderContext < ' _ , ' gc > , & LayoutLine < ' gc > ) ,
1106+ F : FnMut ( & mut RenderContext < ' _ , ' gc > , & LayoutLine < ' gc > ) ,
11061107 {
11071108 // Skip lines that are off-screen.
11081109 let lines_to_skip = self . scroll ( ) . saturating_sub ( 1 ) ;
@@ -1112,10 +1113,14 @@ impl<'gc> EditText<'gc> {
11121113 }
11131114
11141115 /// Render the visible text along with selection and the caret.
1115- fn render_text ( self , context : & mut RenderContext < ' _ , ' gc > ) {
1116+ fn render_text (
1117+ self ,
1118+ context : & mut RenderContext < ' _ , ' gc > ,
1119+ render_state : & mut EditTextRenderState ,
1120+ ) {
11161121 self . render_selection_background ( context) ;
11171122 self . render_lines ( context, |context, line| {
1118- self . render_layout_line ( context, line) ;
1123+ self . render_layout_line ( context, line, render_state ) ;
11191124 } ) ;
11201125 }
11211126
@@ -1187,14 +1192,24 @@ impl<'gc> EditText<'gc> {
11871192 context. commands . draw_rect ( color, selection_box) ;
11881193 }
11891194
1190- fn render_layout_line ( self , context : & mut RenderContext < ' _ , ' gc > , line : & LayoutLine < ' gc > ) {
1195+ fn render_layout_line (
1196+ self ,
1197+ context : & mut RenderContext < ' _ , ' gc > ,
1198+ line : & LayoutLine < ' gc > ,
1199+ render_state : & mut EditTextRenderState ,
1200+ ) {
11911201 for layout_box in line. boxes_iter ( ) {
1192- self . render_layout_box ( context, layout_box) ;
1202+ self . render_layout_box ( context, layout_box, render_state ) ;
11931203 }
11941204 }
11951205
11961206 /// Render a layout box, plus its children.
1197- fn render_layout_box ( self , context : & mut RenderContext < ' _ , ' gc > , lbox : & LayoutBox < ' gc > ) {
1207+ fn render_layout_box (
1208+ self ,
1209+ context : & mut RenderContext < ' _ , ' gc > ,
1210+ lbox : & LayoutBox < ' gc > ,
1211+ render_state : & mut EditTextRenderState ,
1212+ ) {
11981213 let origin = lbox. bounds ( ) . origin ( ) ;
11991214
12001215 // If text's top is under the textbox's bottom, skip drawing.
@@ -1293,7 +1308,7 @@ impl<'gc> EditText<'gc> {
12931308 ) ;
12941309
12951310 if caret. is_some ( ) {
1296- self . render_caret ( context, caret_x, caret_height, color) ;
1311+ self . render_caret ( context, caret_x, caret_height, color, render_state ) ;
12971312 }
12981313 }
12991314
@@ -1310,6 +1325,7 @@ impl<'gc> EditText<'gc> {
13101325 x : Twips ,
13111326 height : Twips ,
13121327 color : Color ,
1328+ render_state : & mut EditTextRenderState ,
13131329 ) {
13141330 let mut caret = context. transform_stack . transform ( ) . matrix
13151331 * Matrix :: create_box_with_rotation (
@@ -1321,7 +1337,12 @@ impl<'gc> EditText<'gc> {
13211337 ) ;
13221338 let pixel_snapping = EditTextPixelSnapping :: new ( context. stage . quality ( ) ) ;
13231339 pixel_snapping. apply ( & mut caret) ;
1324- context. commands . draw_line ( color, caret) ;
1340+
1341+ // We have to draw the caret outside of the text mask.
1342+ render_state. draw_caret_command = Some ( RenderCommand :: DrawLine {
1343+ color,
1344+ matrix : caret,
1345+ } ) ;
13251346 }
13261347
13271348 /// Attempts to bind this text field to a property of a display object.
@@ -2693,7 +2714,8 @@ impl<'gc> TDisplayObject<'gc> for EditText<'gc> {
26932714 ..Default :: default ( )
26942715 } ) ;
26952716
2696- self . render_text ( context) ;
2717+ let mut render_state = Default :: default ( ) ;
2718+ self . render_text ( context, & mut render_state) ;
26972719
26982720 self . render_debug_boxes (
26992721 context,
@@ -2709,6 +2731,10 @@ impl<'gc> TDisplayObject<'gc> for EditText<'gc> {
27092731 context. transform_stack . transform ( ) . matrix * mask,
27102732 ) ;
27112733 context. commands . pop_mask ( ) ;
2734+
2735+ if let Some ( draw_caret_command) = render_state. draw_caret_command {
2736+ context. commands . commands . push ( draw_caret_command) ;
2737+ }
27122738 }
27132739
27142740 fn allow_as_mask ( & self ) -> bool {
@@ -3615,3 +3641,10 @@ struct ImeData {
36153641 ime_end : usize ,
36163642 text : String ,
36173643}
3644+
3645+ #[ derive( Clone , Debug , Default ) ]
3646+ struct EditTextRenderState {
3647+ /// Used for delaying rendering the caret, so that it's
3648+ /// rendered outside of the text mask.
3649+ draw_caret_command : Option < RenderCommand > ,
3650+ }
0 commit comments