@@ -24,7 +24,7 @@ use graphene_std::choice_type::ChoiceTypeStatic;
2424use graphene_std:: color:: SRGBA8 ;
2525use graphene_std:: renderer:: Quad ;
2626use graphene_std:: text:: { Font , TextAlign , TypesettingConfig , lines_clipping} ;
27- use graphene_std:: vector:: style:: { FillChoice , FillChoiceUI } ;
27+ use graphene_std:: vector:: style:: { Fill , FillChoice , FillChoiceUI } ;
2828use graphene_std:: { Color , NodeInputDecleration } ;
2929
3030#[ derive( Default , ExtractField ) ]
@@ -571,6 +571,10 @@ impl TextToolData {
571571 parent : document. new_layer_parent ( true ) ,
572572 insert_index : 0 ,
573573 } ) ;
574+ responses. add ( GraphOperationMessage :: FillSet {
575+ layer : self . layer ,
576+ fill : editing_text. color . map_or ( Fill :: None , Fill :: Solid ) ,
577+ } ) ;
574578 let transform = editing_text. transform ;
575579 self . editing_text = Some ( editing_text) ;
576580
@@ -650,14 +654,21 @@ impl Fsm for TextToolFsmState {
650654 let ToolMessage :: Text ( event) = event else { return self } ;
651655 match ( self , event) {
652656 ( TextToolFsmState :: Editing , TextToolMessage :: Overlays { context : mut overlay_context } ) => {
653- let transform = document. metadata ( ) . transform_to_viewport ( tool_data. layer ) . to_cols_array ( ) ;
657+ // While editing, the text is blanked, so the layer's rendered transform metadata is absent; read the Transform node so the overlay tracks placement
658+ let transform = document
659+ . metadata ( )
660+ . transform_to_viewport_with_first_transform_node_if_group ( tool_data. layer , & document. network_interface )
661+ . to_cols_array ( ) ;
654662 responses. add ( FrontendMessage :: DisplayEditableTextboxTransform { transform } ) ;
655663 if let Some ( editing_text) = tool_data. editing_text . as_mut ( ) {
656664 let font_resource = fonts. get_resource_or_queue_load ( & editing_text. font , responses) ;
657665 let far = graphene_std:: text:: bounding_box ( & tool_data. new_text , & font_resource, editing_text. typesetting , false ) ;
658666 if far. x != 0. && far. y != 0. {
659667 let quad = Quad :: from_box ( [ DVec2 :: ZERO , far] ) ;
660- let transformed_quad = document. metadata ( ) . transform_to_viewport ( tool_data. layer ) * quad;
668+ let transformed_quad = document
669+ . metadata ( )
670+ . transform_to_viewport_with_first_transform_node_if_group ( tool_data. layer , & document. network_interface )
671+ * quad;
661672 overlay_context. quad ( transformed_quad, None , Some ( fill_color) ) ;
662673 }
663674 }
@@ -960,11 +971,17 @@ impl Fsm for TextToolFsmState {
960971 return TextToolFsmState :: Editing ;
961972 }
962973
963- // Otherwise create some new text
964- let constraint_size = has_dragged. then_some ( ( start - end) . abs ( ) ) ;
974+ // Otherwise create some new text. The drag bounds are in viewport space; map them into document space for the text's
975+ // transform and wrapping size, then compose with document-to-viewport so the editing overlay (a screen-space CSS matrix) carries the zoom.
976+ let document_to_viewport = document. metadata ( ) . document_to_viewport ;
977+ let viewport_to_document = document_to_viewport. inverse ( ) ;
978+ let document_start = viewport_to_document. transform_point2 ( start) ;
979+ let document_end = viewport_to_document. transform_point2 ( end) ;
980+
981+ let constraint_size = has_dragged. then_some ( ( document_start - document_end) . abs ( ) ) ;
965982 let editing_text = EditingText {
966983 text : String :: new ( ) ,
967- transform : DAffine2 :: from_translation ( start ) ,
984+ transform : document_to_viewport * DAffine2 :: from_translation ( document_start ) ,
968985 typesetting : TypesettingConfig {
969986 font_size : tool_options. font_size ,
970987 letter_spacing : tool_options. letter_spacing ,
0 commit comments